From 1299ccd9f0c8c7013cc7b0eccd24d066f87ca16f Mon Sep 17 00:00:00 2001 From: Fabio Date: Tue, 27 Jan 2026 12:51:43 +0100 Subject: [PATCH] first commit --- .gitignore | 1 + README.md | 60 + docker-compose.yml | 27 + frontend/api.js | 122 + frontend/app.js | 273 ++ frontend/getAppMetadata.js | 83 + frontend/index.html | 92 + frontend/start.sh | 4 + frontend/style.css | 85 + how_use/api.js | 97 + how_use/del_link.js | 3 + how_use/list.js | 9 + how_use/new_link.js | 16 + how_use/update_link.js | 7 + server/.env | 16 + server/.env.example | 17 + server/Dockerfile | 14 + server/appMetadata.js | 132 + server/index.js | 57 + server/middleware/auth.js | 16 + server/models/Link.js | 14 + server/models/User.js | 8 + server/package-lock.json | 2953 +++++++++++++++++++ server/package.json | 20 + server/routes/auth.js | 42 + server/routes/links.js | 162 + server/routes/metadata.js | 104 + server/uploads/1767548820927-1000084863.jpg | Bin 0 -> 88040 bytes server/uploads/1767548868131.png | Bin 0 -> 6518 bytes 29 files changed, 4434 insertions(+) create mode 100644 .gitignore create mode 100644 README.md create mode 100644 docker-compose.yml create mode 100644 frontend/api.js create mode 100644 frontend/app.js create mode 100644 frontend/getAppMetadata.js create mode 100644 frontend/index.html create mode 100644 frontend/start.sh create mode 100644 frontend/style.css create mode 100644 how_use/api.js create mode 100644 how_use/del_link.js create mode 100644 how_use/list.js create mode 100644 how_use/new_link.js create mode 100644 how_use/update_link.js create mode 100644 server/.env create mode 100644 server/.env.example create mode 100644 server/Dockerfile create mode 100644 server/appMetadata.js create mode 100644 server/index.js create mode 100644 server/middleware/auth.js create mode 100644 server/models/Link.js create mode 100644 server/models/User.js create mode 100644 server/package-lock.json create mode 100644 server/package.json create mode 100644 server/routes/auth.js create mode 100644 server/routes/links.js create mode 100644 server/routes/metadata.js create mode 100644 server/uploads/1767548820927-1000084863.jpg create mode 100644 server/uploads/1767548868131.png diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..c2658d7 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +node_modules/ diff --git a/README.md b/README.md new file mode 100644 index 0000000..ae2f92f --- /dev/null +++ b/README.md @@ -0,0 +1,60 @@ +# Server Json per condivisione delle mie apps + +Utilizza MongoDB su 192.168.1.3 con user root e password example nella vesione non docker + +## Installazione ed avvio server + +vai su server e installa i packages + +```sh +cd server +npm ci install +``` + +far partire il server con + +``` +node index.js +``` +o con +``` +npm start +``` + +è settato per far partire su porta 3000 + +## User interface per inserire i dati + +vai su frontend ed avvia la UI + +``` +cd frontend +npx http-server . -c-1 -p 8282 +``` + +il comando -c-1 toglie la cache +-p indica la porta + +## Altri strumenti per l'utilizzo + +nella directory server c'è + + ./link.sh + +che estrae la lista usando curl + +oppure il comando in js + + node list.js + +che estrae la lista + +nel folder how_use le api e i vari comandi in js + +## Installazione in docker con mongoDB incluso (non testato) + +Come avviarlo + +``` +docker-compose up --build -d +``` diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..4653d18 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,27 @@ + +services: + + myappssvr: + build: ./server + container_name: myappssvr + restart: unless-stopped + environment: + - MONGO_URI=mongodb://root:example@192.168.1.4:27017/myapphttps?authSource=admin + - JWT_SECRET=master66 + - PORT=3000 + - UPLOAD_DIR=uploads + ports: + - "11001:3000" + volumes: + - /home/nvme/dockerdata/myapps_svr/uploads:/app/uploads + + frontend: + image: nginx:alpine + container_name: myappsfrontend + restart: unless-stopped + ports: + - "11002:80" + volumes: + - ./frontend:/usr/share/nginx/html:ro + depends_on: + - myappssvr diff --git a/frontend/api.js b/frontend/api.js new file mode 100644 index 0000000..cefff34 --- /dev/null +++ b/frontend/api.js @@ -0,0 +1,122 @@ +const API_BASE = "http://192.168.1.4:11001"; + +// ------------------------------ +// AUTH +// ------------------------------ + +export async function login(email, password) { + const res = await fetch(`${API_BASE}/auth/login`, { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ email, password }) + }); + + const data = await res.json(); + if (!res.ok) throw new Error(data.error || "Errore login"); + return data.token; +} + +export async function register(email, password) { + const res = await fetch(`${API_BASE}/auth/register`, { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ email, password }) + }); + + const data = await res.json(); + if (!res.ok) throw new Error(data.error || "Errore registrazione"); + return data; +} + +// ------------------------------ +// LINKS +// ------------------------------ + +export async function getLinks(token) { + const res = await fetch(`${API_BASE}/links`, { + headers: { + Authorization: `Bearer ${token}`, + Accept: "application/json" + } + }); + + const data = await res.json(); + if (!res.ok) throw new Error(data.error || "Errore caricamento link"); + return data; +} + +/*export async function createLink(token, { name, url, iconFile }) { + const formData = new FormData(); + formData.append("name", name); + formData.append("url", url); + if (iconFile) formData.append("icon", iconFile); + + const res = await fetch(`${API_BASE}/links`, { + method: "POST", + headers: { + Authorization: `Bearer ${token}` + }, + body: formData + }); + + const data = await res.json(); + if (!res.ok) throw new Error(data.error || "Errore creazione link"); + return data; +}*/ + +export async function createLink(token, { name, url, iconFile, iconURL }) { + const formData = new FormData(); + formData.append("name", name); + formData.append("url", url); + + if (iconFile) { + formData.append("icon", iconFile); + } + + if (iconURL) { + formData.append("iconURL", iconURL); + } + + const res = await fetch(`${API_BASE}/links`, { + method: "POST", + headers: { Authorization: `Bearer ${token}` }, + body: formData + }); + + const data = await res.json(); + if (!res.ok) throw new Error(data.error || "Errore creazione link"); + return data; +} + +export async function deleteLink(token, id) { + const res = await fetch(`${API_BASE}/links/${id}`, { + method: "DELETE", + headers: { + Authorization: `Bearer ${token}` + } + }); + + const data = await res.json(); + if (!res.ok) throw new Error(data.error || "Errore eliminazione link"); + return data; +} + +export async function updateLink(token, id, { name, url, iconFile }) { + const formData = new FormData(); + if (name) formData.append("name", name); + if (url) formData.append("url", url); + if (iconFile) formData.append("icon", iconFile); + + const res = await fetch(`${API_BASE}/links/${id}`, { + method: "PUT", + headers: { + Authorization: `Bearer ${token}` + }, + body: formData + }); + + const data = await res.json(); + if (!res.ok) throw new Error(data.error || "Errore aggiornamento link"); + return data; +} + diff --git a/frontend/app.js b/frontend/app.js new file mode 100644 index 0000000..555c320 --- /dev/null +++ b/frontend/app.js @@ -0,0 +1,273 @@ +import { + login, + register, + getLinks, + createLink, + deleteLink, + updateLink +} from "./api.js"; + +const URL_SVR = "http://192.168.1.4:11001"; + +let token = null; +let autoIconURL = null; +let editingId = null; + +// =============================== +// MOSTRA DIMENSIONI IMMAGINE +// =============================== +function showImageSize(imgElement, sizeElement) { + const img = new Image(); + img.onload = () => { + sizeElement.textContent = `${img.width} × ${img.height} px`; + sizeElement.style.display = "block"; + }; + img.src = imgElement.src; +} + +// =============================== +// AUTH +// =============================== +function setToken(t) { + token = t; + document.getElementById("authSection").style.display = token ? "none" : "block"; + document.getElementById("linkSection").style.display = token ? "block" : "none"; + if (token) loadLinks(); +} + +document.getElementById("loginForm").addEventListener("submit", async e => { + e.preventDefault(); + try { + const t = await login(e.target.email.value, e.target.password.value); + setToken(t); + } catch (err) { + document.getElementById("authStatus").textContent = err.message; + } +}); + +document.getElementById("registerForm").addEventListener("submit", async e => { + e.preventDefault(); + try { + await register(e.target.email.value, e.target.password.value); + document.getElementById("authStatus").textContent = "Registrato! Ora accedi."; + } catch (err) { + document.getElementById("authStatus").textContent = err.message; + } +}); + +// =============================== +// LOAD LINKS +// =============================== +/*async function loadLinks() { + const links = await getLinks(token); + const list = document.getElementById("list"); + + list.innerHTML = links + .map( + link => ` +
+ ${link.icon ? `` : ""} +
+ ${link.name}
+ ${link.url} +
+
+ + +
+
+ ` + ) + .join(""); +}*/ +async function loadLinks() { + const links = await getLinks(token); + // alert(links); + const list = document.getElementById("list"); + +list.innerHTML = links + .map(link => { + let iconHtml = ""; + + if (link.icon && link.icon.data && link.icon.mime) { + const base64 = btoa( + String.fromCharCode(...link.icon.data.data) + ); + iconHtml = ``; + } + + return ` +
+ ${iconHtml} +
+ ${link.name}
+ ${link.url} +
+
+ + +
+
+ `; + }) + .join(""); + +/* + list.innerHTML = links + .map(link => ` +
+ ${link.icon ? `` : ""} +
+ ${link.name}
+ ${link.url} +
+
+ + +
+
+ `) + .join("");*/ +} + +// =============================== +// METADATA (icona automatica) +// =============================== +document.getElementById("fetchMetaBtn").addEventListener("click", async () => { + const url = document.getElementById("urlInput").value.trim(); + if (!url) return; + + const res = await fetch(`${URL_SVR}/metadata?url=${encodeURIComponent(url)}`); + const data = await res.json(); + + document.getElementById("nameInput").value = data.name || ""; + autoIconURL = data.icon || null; + + // L’icona automatica è l’ultima scelta → reset input manuale + const fileInput = document.getElementById("iconInput"); + fileInput.value = ""; + + const preview = document.getElementById("iconPreview"); + const sizeBox = document.getElementById("iconSize"); + + if (autoIconURL) { + preview.src = autoIconURL; + preview.style.display = "block"; + sizeBox.style.display = "none"; + showImageSize(preview, sizeBox); + } +}); + +// =============================== +// ANTEPRIMA ICONA MANUALE +// =============================== +document.getElementById("iconInput").addEventListener("change", e => { + const file = e.target.files[0]; + if (!file) return; + + autoIconURL = null; // manuale vince + + const preview = document.getElementById("iconPreview"); + const sizeBox = document.getElementById("iconSize"); + + preview.src = URL.createObjectURL(file); + preview.style.display = "block"; + sizeBox.style.display = "none"; + + showImageSize(preview, sizeBox); +}); + +// =============================== +// CREAZIONE LINK +// =============================== +document.getElementById("linkForm").addEventListener("submit", async e => { + e.preventDefault(); + + const raw = new FormData(e.target); + const manualFile = raw.get("icon"); + const hasManualFile = manualFile instanceof File && manualFile.size > 0; + + await createLink(token, { + name: raw.get("name"), + url: raw.get("url"), + iconFile: hasManualFile ? manualFile : null, + iconURL: !hasManualFile ? autoIconURL : null + }); + + autoIconURL = null; + document.getElementById("iconPreview").style.display = "none"; + document.getElementById("iconSize").style.display = "none"; + + e.target.reset(); + loadLinks(); +}); + +// =============================== +// EDIT +// =============================== +document.getElementById("list").addEventListener("click", e => { + const id = e.target.dataset.id; + if (!id) return; + + if (e.target.classList.contains("deleteBtn")) { + deleteLink(token, id).then(loadLinks); + return; + } + + if (e.target.classList.contains("editBtn")) { + editingId = id; + + const item = e.target.closest(".item"); + const name = item.querySelector("strong").textContent; + const url = item.querySelector("a").textContent; + + const form = document.getElementById("editForm"); + form.name.value = name; + form.url.value = url; + + document.getElementById("iconPreviewEdit").style.display = "none"; + document.getElementById("iconSizeEdit").style.display = "none"; + + document.getElementById("editModal").style.display = "flex"; + } +}); + +// ANTEPRIMA MANUALE IN EDIT +document.getElementById("iconInputEdit").addEventListener("change", e => { + const file = e.target.files[0]; + if (!file) return; + + const preview = document.getElementById("iconPreviewEdit"); + const sizeBox = document.getElementById("iconSizeEdit"); + + preview.src = URL.createObjectURL(file); + preview.style.display = "block"; + sizeBox.style.display = "none"; + + showImageSize(preview, sizeBox); +}); + +// SALVA EDIT +document.getElementById("editForm").addEventListener("submit", async e => { + e.preventDefault(); + + const name = e.target.name.value; + const url = e.target.url.value; + const iconFile = e.target.icon.files[0] || null; + + await updateLink(token, editingId, { + name, + url, + iconFile, + iconURL: null + }); + + document.getElementById("editModal").style.display = "none"; + loadLinks(); +}); + +document.getElementById("closeModal").addEventListener("click", () => { + document.getElementById("editModal").style.display = "none"; +}); + +setToken(null); diff --git a/frontend/getAppMetadata.js b/frontend/getAppMetadata.js new file mode 100644 index 0000000..2cc7c5d --- /dev/null +++ b/frontend/getAppMetadata.js @@ -0,0 +1,83 @@ + diff --git a/frontend/index.html b/frontend/index.html new file mode 100644 index 0000000..0fbdb07 --- /dev/null +++ b/frontend/index.html @@ -0,0 +1,92 @@ + + + + + Link Manager + + + + +
+ +

Link Manager

+ + +
+
+

Accedi

+
+ + + +
+ +

Oppure registrati

+
+ + + +
+ +
+
+
+ + + + +
+ + + + + + + + + + diff --git a/frontend/start.sh b/frontend/start.sh new file mode 100644 index 0000000..65193b5 --- /dev/null +++ b/frontend/start.sh @@ -0,0 +1,4 @@ +#!/bin/bash + +# Avvia un server HTTP sulla porta 11002 senza cache +npx http-server . -c-1 -p 11003 diff --git a/frontend/style.css b/frontend/style.css new file mode 100644 index 0000000..5e2c3c3 --- /dev/null +++ b/frontend/style.css @@ -0,0 +1,85 @@ +body { + font-family: -apple-system, BlinkMacSystemFont, "SF Pro", sans-serif; + background: #f5f5f7; + margin: 0; + padding: 40px; + color: #333; +} + +.container { + max-width: 700px; + margin: auto; +} + +h1 { + text-align: center; + margin-bottom: 40px; + font-weight: 600; +} + +.card { + background: white; + padding: 25px; + border-radius: 18px; + box-shadow: 0 4px 20px rgba(0,0,0,0.08); + margin-bottom: 30px; +} + +form { + display: flex; + flex-direction: column; + gap: 12px; +} + +input { + padding: 12px; + border-radius: 10px; + border: 1px solid #ccc; + font-size: 15px; +} + +button { + padding: 12px; + border-radius: 10px; + border: none; + background: #007aff; + color: white; + font-size: 16px; + cursor: pointer; + font-weight: 600; +} + +button:hover { + background: #0063cc; +} + +#list .item { + display: flex; + align-items: center; + gap: 12px; + padding: 10px 0; + border-bottom: 1px solid #eee; +} + +#list img { + width: 40px; + height: 40px; + object-fit: contain; + border-radius: 8px; +} +.modal { + position: fixed; + top: 0; left: 0; + width: 100%; height: 100%; + background: rgba(0,0,0,0.4); + display: flex; + justify-content: center; + align-items: center; +} + +.modal-content { + background: white; + padding: 20px; + border-radius: 12px; + width: 300px; +} diff --git a/how_use/api.js b/how_use/api.js new file mode 100644 index 0000000..b71b531 --- /dev/null +++ b/how_use/api.js @@ -0,0 +1,97 @@ +const API_BASE = "http://localhost:3000"; + +// ------------------------------ +// AUTH +// ------------------------------ + +export async function login(email, password) { + const res = await fetch(`${API_BASE}/auth/login`, { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ email, password }) + }); + + const data = await res.json(); + if (!res.ok) throw new Error(data.error || "Errore login"); + return data.token; +} + +export async function register(email, password) { + const res = await fetch(`${API_BASE}/auth/register`, { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ email, password }) + }); + + const data = await res.json(); + if (!res.ok) throw new Error(data.error || "Errore registrazione"); + return data; +} + +// ------------------------------ +// LINKS +// ------------------------------ + +export async function getLinks(token) { + const res = await fetch(`${API_BASE}/links`, { + headers: { + Authorization: `Bearer ${token}`, + Accept: "application/json" + } + }); + + const data = await res.json(); + if (!res.ok) throw new Error(data.error || "Errore caricamento link"); + return data; +} + +export async function createLink(token, { name, url, iconFile }) { + const formData = new FormData(); + formData.append("name", name); + formData.append("url", url); + if (iconFile) formData.append("icon", iconFile); + + const res = await fetch(`${API_BASE}/links`, { + method: "POST", + headers: { + Authorization: `Bearer ${token}` + }, + body: formData + }); + + const data = await res.json(); + if (!res.ok) throw new Error(data.error || "Errore creazione link"); + return data; +} + +export async function deleteLink(token, id) { + const res = await fetch(`${API_BASE}/links/${id}`, { + method: "DELETE", + headers: { + Authorization: `Bearer ${token}` + } + }); + + const data = await res.json(); + if (!res.ok) throw new Error(data.error || "Errore eliminazione link"); + return data; +} + +export async function updateLink(token, id, { name, url, iconFile }) { + const formData = new FormData(); + if (name) formData.append("name", name); + if (url) formData.append("url", url); + if (iconFile) formData.append("icon", iconFile); + + const res = await fetch(`${API_BASE}/links/${id}`, { + method: "PUT", + headers: { + Authorization: `Bearer ${token}` + }, + body: formData + }); + + const data = await res.json(); + if (!res.ok) throw new Error(data.error || "Errore aggiornamento link"); + return data; +} diff --git a/how_use/del_link.js b/how_use/del_link.js new file mode 100644 index 0000000..46d247b --- /dev/null +++ b/how_use/del_link.js @@ -0,0 +1,3 @@ +import { deleteLink } from "./api.js"; + +await deleteLink(token, "ID_DEL_LINK"); diff --git a/how_use/list.js b/how_use/list.js new file mode 100644 index 0000000..f9e7597 --- /dev/null +++ b/how_use/list.js @@ -0,0 +1,9 @@ +import { login, getLinks } from "./api.js"; + +async function main() { + const token = await login("fabio.micheluz@gmail.com", "master66"); + const links = await getLinks(token); + console.log("Lista link:", links); +} + +main(); diff --git a/how_use/new_link.js b/how_use/new_link.js new file mode 100644 index 0000000..3ce10ce --- /dev/null +++ b/how_use/new_link.js @@ -0,0 +1,16 @@ +import { createLink } from "./api.js"; + +async function add() { + const token = "IL_TUO_TOKEN"; + + const fileInput = document.querySelector("#iconInput"); + const iconFile = fileInput.files[0]; + + const link = await createLink(token, { + name: "Google", + url: "https://google.com", + iconFile + }); + + console.log("Creato:", link); +} diff --git a/how_use/update_link.js b/how_use/update_link.js new file mode 100644 index 0000000..0eb784b --- /dev/null +++ b/how_use/update_link.js @@ -0,0 +1,7 @@ +import { updateLink } from "./api.js"; + +await updateLink(token, "ID_DEL_LINK", { + name: "Nuovo nome", + url: "https://nuovo-url.com", + iconFile: nuovoFile +}); diff --git a/server/.env b/server/.env new file mode 100644 index 0000000..2e946e6 --- /dev/null +++ b/server/.env @@ -0,0 +1,16 @@ +# === SERVER CONFIG === +PORT=11001 + +# === JWT CONFIG === +# Cambialo SEMPRE in produzione +JWT_SECRET=master66 + +# === MONGO CONFIG === +# In locale: +# MONGO_URI=mongodb://localhost:27017/mydb +# +# In Docker (usato dal docker-compose): +MONGO_URI=mongodb://root:example@192.168.1.3:27017/myapphttps?authSource=admin +# === UPLOADS === +# Cartella dove Express serve le icone +UPLOAD_DIR=uploads diff --git a/server/.env.example b/server/.env.example new file mode 100644 index 0000000..949fb60 --- /dev/null +++ b/server/.env.example @@ -0,0 +1,17 @@ +# === SERVER CONFIG === +PORT=3000 + +# === JWT CONFIG === +# Cambialo SEMPRE in produzione +JWT_SECRET=supersegreto-cambialo + +# === MONGO CONFIG === +# In locale: +# MONGO_URI=mongodb://localhost:27017/mydb +# +# In Docker (usato dal docker-compose): +MONGO_URI=mongodb://mongo:27017/mydb + +# === UPLOADS === +# Cartella dove Express serve le icone +UPLOAD_DIR=uploads diff --git a/server/Dockerfile b/server/Dockerfile new file mode 100644 index 0000000..3dacabd --- /dev/null +++ b/server/Dockerfile @@ -0,0 +1,14 @@ +FROM node:20-alpine + +WORKDIR /app + +COPY package.json package-lock.json* ./ +RUN npm install --production + +COPY . . + +RUN mkdir -p uploads + +EXPOSE 3000 + +CMD ["node", "index.js"] \ No newline at end of file diff --git a/server/appMetadata.js b/server/appMetadata.js new file mode 100644 index 0000000..6f9cd45 --- /dev/null +++ b/server/appMetadata.js @@ -0,0 +1,132 @@ +// appMetadata.js +import axios from "axios"; +import * as cheerio from "cheerio"; +import sizeOf from "image-size"; +import sharp from "sharp"; + +export async function getAppMetadata(baseUrl) { + console.log(baseUrl); + try { + const res = await axios.get(baseUrl, { timeout: 3000 }); + const $ = cheerio.load(res.data); + + // ------------------------------- + // 1. Nome più corto + // ------------------------------- + const nameCandidates = [ + $('meta[property="og:site_name"]').attr("content"), + $('meta[name="application-name"]').attr("content"), + $('meta[property="og:title"]').attr("content"), + $("title").text().trim() + ].filter(Boolean); + + const name = nameCandidates.length > 0 + ? nameCandidates.sort((a, b) => a.length - b.length)[0] + : "no_name"; + + // ------------------------------- + // 2. Icone HTML + // ------------------------------- + const htmlIcons = []; + $("link[rel*='icon']").each((_, el) => { + const href = $(el).attr("href"); + const sizes = $(el).attr("sizes") || ""; + if (href) htmlIcons.push({ href, sizes }); + }); + + // ------------------------------- + // 3. Manifest.json + // ------------------------------- + let manifestIcons = []; + const manifestHref = $('link[rel="manifest"]').attr("href"); + + if (manifestHref) { + try { + const manifestUrl = new URL(manifestHref, baseUrl).href; + const manifestRes = await axios.get(manifestUrl, { timeout: 3000 }); + const manifest = manifestRes.data; + + if (manifest.icons && Array.isArray(manifest.icons)) { + manifestIcons = manifest.icons.map(icon => ({ + href: icon.src, + sizes: icon.sizes || "" + })); + } + } catch {} + } + + // ------------------------------- + // 4. Fallback 4 icone + // ------------------------------- + const fallbackPaths = [ + "/favicon.ico", + "/favicon.png", + "/icon.png", + "/apple-touch-icon.png" + ]; + + const fallbackIcons = fallbackPaths.map(p => ({ + href: p, + sizes: "" + })); + + // ------------------------------- + // 5. Unisci tutte le icone + // ------------------------------- + const allIcons = [...htmlIcons, ...manifestIcons, ...fallbackIcons]; + + // ------------------------------- + // 6. Determina dimensione reale (PNG, ICO, SVG) + // ------------------------------- + const iconsWithRealSize = []; + + for (const icon of allIcons) { + try { + const url = new URL(icon.href, baseUrl).href; + const imgRes = await axios.get(url, { responseType: "arraybuffer" }); + + let width = 0; + + // ---- PNG / JPG / ICO ---- + try { + const dim = sizeOf(imgRes.data); + if (dim.width) width = dim.width; + } catch { + // Non è un formato supportato da image-size + } + + // ---- SVG → converti in PNG e misura ---- + if (width === 0) { + try { + const pngBuffer = await sharp(imgRes.data).png().toBuffer(); + const dim = sizeOf(pngBuffer); + if (dim.width) width = dim.width; + } catch { + // SVG non convertibile → ignora + } + } + + if (width > 0) { + iconsWithRealSize.push({ url, size: width }); + } + + } catch { + // icona non accessibile → ignora + } + } + + // ------------------------------- + // 7. Scegli la più grande + // ------------------------------- + iconsWithRealSize.sort((a, b) => b.size - a.size); + + const icon = iconsWithRealSize.length > 0 + ? iconsWithRealSize[0].url + : null; + + return { name, icon }; + + } catch { + return { name: "no_name", icon: null }; + } +} diff --git a/server/index.js b/server/index.js new file mode 100644 index 0000000..14b66a9 --- /dev/null +++ b/server/index.js @@ -0,0 +1,57 @@ +import express from "express"; +import mongoose from "mongoose"; +import cors from "cors"; +import dotenv from "dotenv"; +import linksRouter from "./routes/links.js"; +import authRouter from "./routes/auth.js"; +import metadataRouter from "./routes/metadata.js"; + +dotenv.config(); + +const app = express(); + +app.use(cors()); +app.use(express.json()); + +// Static folder per le icone +app.use("/uploads", express.static("uploads")); + +// Auth routes +app.use("/auth", authRouter); + +// Link routes (protette) +app.use("/links", linksRouter); + +// link per metadata +app.use("/metadata", metadataRouter); + +// Connessione Mongo (URL da env con fallback) +const MONGO_URI = process.env.MONGO_URI || "mongodb://mongo:27017/mydb"; + +mongoose + .connect(MONGO_URI) + .then(() => { + console.log("MongoDB connesso"); + }) + .catch(err => { + console.error("❌ Errore di connessione a MongoDB:", err.message); + process.exit(1); // termina il processo + }); + + + +const PORT = process.env.PORT || 3000; + +const server = app.listen(PORT, () => { + console.log(`API su http://localhost:${PORT}`); +}); + +server.on('error', (err) => { + if (err.code === 'EADDRINUSE') { + console.error(`❌ Porta ${PORT} già in uso. Arresto del processo.`); + process.exit(1); + } else { + console.error('Errore del server:', err); + process.exit(1); + } +}); diff --git a/server/middleware/auth.js b/server/middleware/auth.js new file mode 100644 index 0000000..eefd0c4 --- /dev/null +++ b/server/middleware/auth.js @@ -0,0 +1,16 @@ +import jwt from "jsonwebtoken"; + +export function authMiddleware(req, res, next) { + const authHeader = req.headers.authorization || ""; + const token = authHeader.startsWith("Bearer ") ? authHeader.slice(7) : null; + + if (!token) return res.status(401).json({ error: "Token mancante" }); + + try { + const payload = jwt.verify(token, process.env.JWT_SECRET || "devsecret"); + req.userId = payload.userId; + next(); + } catch (err) { + return res.status(401).json({ error: "Token non valido" }); + } +} diff --git a/server/models/Link.js b/server/models/Link.js new file mode 100644 index 0000000..7d06566 --- /dev/null +++ b/server/models/Link.js @@ -0,0 +1,14 @@ +import mongoose from "mongoose"; + +const LinkSchema = new mongoose.Schema({ + url: { type: String, required: true }, + name: { type: String, required: true }, + icon: { + data: { type: Buffer, required: false }, + mime: { type: String, required: false }, + size: { type: Number, required: false } + }, + owner: { type: mongoose.Schema.Types.ObjectId, ref: "User", required: true } +}); + +export default mongoose.model("Link", LinkSchema); diff --git a/server/models/User.js b/server/models/User.js new file mode 100644 index 0000000..fa7e608 --- /dev/null +++ b/server/models/User.js @@ -0,0 +1,8 @@ +import mongoose from "mongoose"; + +const UserSchema = new mongoose.Schema({ + email: { type: String, required: true, unique: true }, + passwordHash: { type: String, required: true } +}); + +export default mongoose.model("User", UserSchema); diff --git a/server/package-lock.json b/server/package-lock.json new file mode 100644 index 0000000..82c9c63 --- /dev/null +++ b/server/package-lock.json @@ -0,0 +1,2953 @@ +{ + "name": "backend", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "dependencies": { + "axios": "^1.13.2", + "bcryptjs": "^3.0.3", + "cheerio": "^1.1.2", + "cors": "^2.8.5", + "dotenv": "^17.2.3", + "express": "^5.2.1", + "icojs": "^0.20.1", + "image-size": "^2.0.2", + "jsonwebtoken": "^9.0.3", + "mongoose": "^9.0.2", + "multer": "^2.0.2", + "sharp": "^0.34.5" + } + }, + "node_modules/@borewit/text-codec": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/@borewit/text-codec/-/text-codec-0.2.1.tgz", + "integrity": "sha512-k7vvKPbf7J2fZ5klGRD9AeKfUvojuZIQ3BT5u7Jfv+puwXkUBUT5PVyMDfJZpy30CBDXGMgw7fguK/lpOMBvgw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Borewit" + } + }, + "node_modules/@canvas/image-data": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@canvas/image-data/-/image-data-1.1.0.tgz", + "integrity": "sha512-QdObRRjRbcXGmM1tmJ+MrHcaz1MftF2+W7YI+MsphnsCrmtyfS0d5qJbk0MeSbUeyM/jCb0hmnkXPsy026L7dA==", + "license": "MIT" + }, + "node_modules/@emnapi/runtime": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.7.1.tgz", + "integrity": "sha512-PVtJr5CmLwYAU9PZDMITZoR5iAOShYREoR45EyyLrbntV50mdePTgUn4AmOw90Ifcj+x2kRjdzr1HP3RrNiHGA==", + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@img/colour": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@img/colour/-/colour-1.0.0.tgz", + "integrity": "sha512-A5P/LfWGFSl6nsckYtjw9da+19jB8hkJ6ACTGcDfEJ0aE+l2n2El7dsVM7UVHZQ9s2lmYMWlrS21YLy2IR1LUw==", + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/@img/sharp-darwin-arm64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.34.5.tgz", + "integrity": "sha512-imtQ3WMJXbMY4fxb/Ndp6HBTNVtWCUI0WdobyheGf5+ad6xX8VIDO8u2xE4qc/fr08CKG/7dDseFtn6M6g/r3w==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-darwin-arm64": "1.2.4" + } + }, + "node_modules/@img/sharp-darwin-x64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.34.5.tgz", + "integrity": "sha512-YNEFAF/4KQ/PeW0N+r+aVVsoIY0/qxxikF2SWdp+NRkmMB7y9LBZAVqQ4yhGCm/H3H270OSykqmQMKLBhBJDEw==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-darwin-x64": "1.2.4" + } + }, + "node_modules/@img/sharp-libvips-darwin-arm64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.2.4.tgz", + "integrity": "sha512-zqjjo7RatFfFoP0MkQ51jfuFZBnVE2pRiaydKJ1G/rHZvnsrHAOcQALIi9sA5co5xenQdTugCvtb1cuf78Vf4g==", + "cpu": [ + "arm64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "darwin" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-darwin-x64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.2.4.tgz", + "integrity": "sha512-1IOd5xfVhlGwX+zXv2N93k0yMONvUlANylbJw1eTah8K/Jtpi15KC+WSiaX/nBmbm2HxRM1gZ0nSdjSsrZbGKg==", + "cpu": [ + "x64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "darwin" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-arm": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.2.4.tgz", + "integrity": "sha512-bFI7xcKFELdiNCVov8e44Ia4u2byA+l3XtsAj+Q8tfCwO6BQ8iDojYdvoPMqsKDkuoOo+X6HZA0s0q11ANMQ8A==", + "cpu": [ + "arm" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-arm64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.2.4.tgz", + "integrity": "sha512-excjX8DfsIcJ10x1Kzr4RcWe1edC9PquDRRPx3YVCvQv+U5p7Yin2s32ftzikXojb1PIFc/9Mt28/y+iRklkrw==", + "cpu": [ + "arm64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-ppc64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-ppc64/-/sharp-libvips-linux-ppc64-1.2.4.tgz", + "integrity": "sha512-FMuvGijLDYG6lW+b/UvyilUWu5Ayu+3r2d1S8notiGCIyYU/76eig1UfMmkZ7vwgOrzKzlQbFSuQfgm7GYUPpA==", + "cpu": [ + "ppc64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-riscv64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-riscv64/-/sharp-libvips-linux-riscv64-1.2.4.tgz", + "integrity": "sha512-oVDbcR4zUC0ce82teubSm+x6ETixtKZBh/qbREIOcI3cULzDyb18Sr/Wcyx7NRQeQzOiHTNbZFF1UwPS2scyGA==", + "cpu": [ + "riscv64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-s390x": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.2.4.tgz", + "integrity": "sha512-qmp9VrzgPgMoGZyPvrQHqk02uyjA0/QrTO26Tqk6l4ZV0MPWIW6LTkqOIov+J1yEu7MbFQaDpwdwJKhbJvuRxQ==", + "cpu": [ + "s390x" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-x64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.2.4.tgz", + "integrity": "sha512-tJxiiLsmHc9Ax1bz3oaOYBURTXGIRDODBqhveVHonrHJ9/+k89qbLl0bcJns+e4t4rvaNBxaEZsFtSfAdquPrw==", + "cpu": [ + "x64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linuxmusl-arm64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.2.4.tgz", + "integrity": "sha512-FVQHuwx1IIuNow9QAbYUzJ+En8KcVm9Lk5+uGUQJHaZmMECZmOlix9HnH7n1TRkXMS0pGxIJokIVB9SuqZGGXw==", + "cpu": [ + "arm64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linuxmusl-x64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.2.4.tgz", + "integrity": "sha512-+LpyBk7L44ZIXwz/VYfglaX/okxezESc6UxDSoyo2Ks6Jxc4Y7sGjpgU9s4PMgqgjj1gZCylTieNamqA1MF7Dg==", + "cpu": [ + "x64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-linux-arm": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.34.5.tgz", + "integrity": "sha512-9dLqsvwtg1uuXBGZKsxem9595+ujv0sJ6Vi8wcTANSFpwV/GONat5eCkzQo/1O6zRIkh0m/8+5BjrRr7jDUSZw==", + "cpu": [ + "arm" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-arm": "1.2.4" + } + }, + "node_modules/@img/sharp-linux-arm64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.34.5.tgz", + "integrity": "sha512-bKQzaJRY/bkPOXyKx5EVup7qkaojECG6NLYswgktOZjaXecSAeCWiZwwiFf3/Y+O1HrauiE3FVsGxFg8c24rZg==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-arm64": "1.2.4" + } + }, + "node_modules/@img/sharp-linux-ppc64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-ppc64/-/sharp-linux-ppc64-0.34.5.tgz", + "integrity": "sha512-7zznwNaqW6YtsfrGGDA6BRkISKAAE1Jo0QdpNYXNMHu2+0dTrPflTLNkpc8l7MUP5M16ZJcUvysVWWrMefZquA==", + "cpu": [ + "ppc64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-ppc64": "1.2.4" + } + }, + "node_modules/@img/sharp-linux-riscv64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-riscv64/-/sharp-linux-riscv64-0.34.5.tgz", + "integrity": "sha512-51gJuLPTKa7piYPaVs8GmByo7/U7/7TZOq+cnXJIHZKavIRHAP77e3N2HEl3dgiqdD/w0yUfiJnII77PuDDFdw==", + "cpu": [ + "riscv64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-riscv64": "1.2.4" + } + }, + "node_modules/@img/sharp-linux-s390x": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.34.5.tgz", + "integrity": "sha512-nQtCk0PdKfho3eC5MrbQoigJ2gd1CgddUMkabUj+rBevs8tZ2cULOx46E7oyX+04WGfABgIwmMC0VqieTiR4jg==", + "cpu": [ + "s390x" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-s390x": "1.2.4" + } + }, + "node_modules/@img/sharp-linux-x64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.34.5.tgz", + "integrity": "sha512-MEzd8HPKxVxVenwAa+JRPwEC7QFjoPWuS5NZnBt6B3pu7EG2Ge0id1oLHZpPJdn3OQK+BQDiw9zStiHBTJQQQQ==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-x64": "1.2.4" + } + }, + "node_modules/@img/sharp-linuxmusl-arm64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.34.5.tgz", + "integrity": "sha512-fprJR6GtRsMt6Kyfq44IsChVZeGN97gTD331weR1ex1c1rypDEABN6Tm2xa1wE6lYb5DdEnk03NZPqA7Id21yg==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linuxmusl-arm64": "1.2.4" + } + }, + "node_modules/@img/sharp-linuxmusl-x64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.34.5.tgz", + "integrity": "sha512-Jg8wNT1MUzIvhBFxViqrEhWDGzqymo3sV7z7ZsaWbZNDLXRJZoRGrjulp60YYtV4wfY8VIKcWidjojlLcWrd8Q==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linuxmusl-x64": "1.2.4" + } + }, + "node_modules/@img/sharp-wasm32": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.34.5.tgz", + "integrity": "sha512-OdWTEiVkY2PHwqkbBI8frFxQQFekHaSSkUIJkwzclWZe64O1X4UlUjqqqLaPbUpMOQk6FBu/HtlGXNblIs0huw==", + "cpu": [ + "wasm32" + ], + "license": "Apache-2.0 AND LGPL-3.0-or-later AND MIT", + "optional": true, + "dependencies": { + "@emnapi/runtime": "^1.7.0" + }, + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-arm64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-arm64/-/sharp-win32-arm64-0.34.5.tgz", + "integrity": "sha512-WQ3AgWCWYSb2yt+IG8mnC6Jdk9Whs7O0gxphblsLvdhSpSTtmu69ZG1Gkb6NuvxsNACwiPV6cNSZNzt0KPsw7g==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0 AND LGPL-3.0-or-later", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-ia32": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.34.5.tgz", + "integrity": "sha512-FV9m/7NmeCmSHDD5j4+4pNI8Cp3aW+JvLoXcTUo0IqyjSfAZJ8dIUmijx1qaJsIiU+Hosw6xM5KijAWRJCSgNg==", + "cpu": [ + "ia32" + ], + "license": "Apache-2.0 AND LGPL-3.0-or-later", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-x64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.34.5.tgz", + "integrity": "sha512-+29YMsqY2/9eFEiW93eqWnuLcWcufowXewwSNIT6UwZdUUCrM3oFjMWH/Z6/TMmb4hlFenmfAVbpWeup2jryCw==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0 AND LGPL-3.0-or-later", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@jimp/bmp": { + "version": "0.22.12", + "resolved": "https://registry.npmjs.org/@jimp/bmp/-/bmp-0.22.12.tgz", + "integrity": "sha512-aeI64HD0npropd+AR76MCcvvRaa+Qck6loCOS03CkkxGHN5/r336qTM5HPUdHKMDOGzqknuVPA8+kK1t03z12g==", + "license": "MIT", + "dependencies": { + "@jimp/utils": "^0.22.12", + "bmp-js": "^0.1.0" + }, + "peerDependencies": { + "@jimp/custom": ">=0.3.5" + } + }, + "node_modules/@jimp/core": { + "version": "0.22.12", + "resolved": "https://registry.npmjs.org/@jimp/core/-/core-0.22.12.tgz", + "integrity": "sha512-l0RR0dOPyzMKfjUW1uebzueFEDtCOj9fN6pyTYWWOM/VS4BciXQ1VVrJs8pO3kycGYZxncRKhCoygbNr8eEZQA==", + "license": "MIT", + "peer": true, + "dependencies": { + "@jimp/utils": "^0.22.12", + "any-base": "^1.1.0", + "buffer": "^5.2.0", + "exif-parser": "^0.1.12", + "file-type": "^16.5.4", + "isomorphic-fetch": "^3.0.0", + "pixelmatch": "^4.0.2", + "tinycolor2": "^1.6.0" + } + }, + "node_modules/@jimp/core/node_modules/file-type": { + "version": "16.5.4", + "resolved": "https://registry.npmjs.org/file-type/-/file-type-16.5.4.tgz", + "integrity": "sha512-/yFHK0aGjFEgDJjEKP0pWCplsPFPhwyfwevf/pVxiN0tmE4L9LmwWxWukdJSHdoCli4VgQLehjJtwQBnqmsKcw==", + "license": "MIT", + "peer": true, + "dependencies": { + "readable-web-to-node-stream": "^3.0.0", + "strtok3": "^6.2.4", + "token-types": "^4.1.1" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/file-type?sponsor=1" + } + }, + "node_modules/@jimp/core/node_modules/strtok3": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/strtok3/-/strtok3-6.3.0.tgz", + "integrity": "sha512-fZtbhtvI9I48xDSywd/somNqgUHl2L2cstmXCCif0itOf96jeW18MBSyrLuNicYQVkvpOxkZtkzujiTJ9LW5Jw==", + "license": "MIT", + "peer": true, + "dependencies": { + "@tokenizer/token": "^0.3.0", + "peek-readable": "^4.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Borewit" + } + }, + "node_modules/@jimp/core/node_modules/token-types": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/token-types/-/token-types-4.2.1.tgz", + "integrity": "sha512-6udB24Q737UD/SDsKAHI9FCRP7Bqc9D/MQUV02ORQg5iskjtLJlZJNdN4kKtcdtwCeWIwIHDGaUsTsCCAa8sFQ==", + "license": "MIT", + "peer": true, + "dependencies": { + "@tokenizer/token": "^0.3.0", + "ieee754": "^1.2.1" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Borewit" + } + }, + "node_modules/@jimp/custom": { + "version": "0.22.12", + "resolved": "https://registry.npmjs.org/@jimp/custom/-/custom-0.22.12.tgz", + "integrity": "sha512-xcmww1O/JFP2MrlGUMd3Q78S3Qu6W3mYTXYuIqFq33EorgYHV/HqymHfXy9GjiCJ7OI+7lWx6nYFOzU7M4rd1Q==", + "license": "MIT", + "peer": true, + "dependencies": { + "@jimp/core": "^0.22.12" + } + }, + "node_modules/@jimp/utils": { + "version": "0.22.12", + "resolved": "https://registry.npmjs.org/@jimp/utils/-/utils-0.22.12.tgz", + "integrity": "sha512-yJ5cWUknGnilBq97ZXOyOS0HhsHOyAyjHwYfHxGbSyMTohgQI6sVyE8KPgDwH8HHW/nMKXk8TrSwAE71zt716Q==", + "license": "MIT", + "dependencies": { + "regenerator-runtime": "^0.13.3" + } + }, + "node_modules/@mongodb-js/saslprep": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/@mongodb-js/saslprep/-/saslprep-1.4.4.tgz", + "integrity": "sha512-p7X/ytJDIdwUfFL/CLOhKgdfJe1Fa8uw9seJYvdOmnP9JBWGWHW69HkOixXS6Wy9yvGf1MbhcS6lVmrhy4jm2g==", + "license": "MIT", + "dependencies": { + "sparse-bitfield": "^3.0.3" + } + }, + "node_modules/@tokenizer/inflate": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@tokenizer/inflate/-/inflate-0.4.1.tgz", + "integrity": "sha512-2mAv+8pkG6GIZiF1kNg1jAjh27IDxEPKwdGul3snfztFerfPGI1LjDezZp3i7BElXompqEtPmoPx6c2wgtWsOA==", + "license": "MIT", + "dependencies": { + "debug": "^4.4.3", + "token-types": "^6.1.1" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Borewit" + } + }, + "node_modules/@tokenizer/token": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@tokenizer/token/-/token-0.3.0.tgz", + "integrity": "sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A==", + "license": "MIT" + }, + "node_modules/@types/webidl-conversions": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/@types/webidl-conversions/-/webidl-conversions-7.0.3.tgz", + "integrity": "sha512-CiJJvcRtIgzadHCYXw7dqEnMNRjhGZlYK05Mj9OyktqV8uVT8fD2BFOB7S1uwBE3Kj2Z+4UyPmFw/Ixgw/LAlA==", + "license": "MIT" + }, + "node_modules/@types/whatwg-url": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/@types/whatwg-url/-/whatwg-url-13.0.0.tgz", + "integrity": "sha512-N8WXpbE6Wgri7KUSvrmQcqrMllKZ9uxkYWMt+mCSGwNc0Hsw9VQTW7ApqI4XNrx6/SaM2QQJCzMPDEXE058s+Q==", + "license": "MIT", + "dependencies": { + "@types/webidl-conversions": "*" + } + }, + "node_modules/abort-controller": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", + "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", + "license": "MIT", + "peer": true, + "dependencies": { + "event-target-shim": "^5.0.0" + }, + "engines": { + "node": ">=6.5" + } + }, + "node_modules/accepts": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-2.0.0.tgz", + "integrity": "sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==", + "license": "MIT", + "dependencies": { + "mime-types": "^3.0.0", + "negotiator": "^1.0.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/any-base": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/any-base/-/any-base-1.1.0.tgz", + "integrity": "sha512-uMgjozySS8adZZYePpaWs8cxB9/kdzmpX6SgJZ+wbz1K5eYk5QMYDVJaZKhxyIHUdnnJkfR7SVgStgH7LkGUyg==", + "license": "MIT", + "peer": true + }, + "node_modules/append-field": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/append-field/-/append-field-1.0.0.tgz", + "integrity": "sha512-klpgFSWLW1ZEs8svjfb7g4qWY0YS5imI82dTg+QahUvJ8YqAY0P10Uk8tTyh9ZGuYEZEMaeJYCF5BFuX552hsw==", + "license": "MIT" + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "license": "MIT" + }, + "node_modules/axios": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.13.2.tgz", + "integrity": "sha512-VPk9ebNqPcy5lRGuSlKx752IlDatOjT9paPlm8A7yOuW2Fbvp4X3JznJtT4f0GzGLLiWE9W8onz51SqLYwzGaA==", + "license": "MIT", + "dependencies": { + "follow-redirects": "^1.15.6", + "form-data": "^4.0.4", + "proxy-from-env": "^1.1.0" + } + }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "peer": true + }, + "node_modules/bcryptjs": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/bcryptjs/-/bcryptjs-3.0.3.tgz", + "integrity": "sha512-GlF5wPWnSa/X5LKM1o0wz0suXIINz1iHRLvTS+sLyi7XPbe5ycmYI3DlZqVGZZtDgl4DmasFg7gOB3JYbphV5g==", + "license": "BSD-3-Clause", + "bin": { + "bcrypt": "bin/bcrypt" + } + }, + "node_modules/bmp-js": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/bmp-js/-/bmp-js-0.1.0.tgz", + "integrity": "sha512-vHdS19CnY3hwiNdkaqk93DvjVLfbEcI8mys4UjuWrlX1haDmroo8o4xCzh4wD6DGV6HxRCyauwhHRqMTfERtjw==", + "license": "MIT" + }, + "node_modules/body-parser": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.2.1.tgz", + "integrity": "sha512-nfDwkulwiZYQIGwxdy0RUmowMhKcFVcYXUU7m4QlKYim1rUtg83xm2yjZ40QjDuc291AJjjeSc9b++AWHSgSHw==", + "license": "MIT", + "dependencies": { + "bytes": "^3.1.2", + "content-type": "^1.0.5", + "debug": "^4.4.3", + "http-errors": "^2.0.0", + "iconv-lite": "^0.7.0", + "on-finished": "^2.4.1", + "qs": "^6.14.0", + "raw-body": "^3.0.1", + "type-is": "^2.0.1" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/boolbase": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", + "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==", + "license": "ISC" + }, + "node_modules/bson": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/bson/-/bson-7.0.0.tgz", + "integrity": "sha512-Kwc6Wh4lQ5OmkqqKhYGKIuELXl+EPYSCObVE6bWsp1T/cGkOCBN0I8wF/T44BiuhHyNi1mmKVPXk60d41xZ7kw==", + "license": "Apache-2.0", + "engines": { + "node": ">=20.19.0" + } + }, + "node_modules/buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "peer": true, + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "node_modules/buffer-equal-constant-time": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", + "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==", + "license": "BSD-3-Clause" + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "license": "MIT" + }, + "node_modules/busboy": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz", + "integrity": "sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==", + "dependencies": { + "streamsearch": "^1.1.0" + }, + "engines": { + "node": ">=10.16.0" + } + }, + "node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/call-bound": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", + "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "get-intrinsic": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/cheerio": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.1.2.tgz", + "integrity": "sha512-IkxPpb5rS/d1IiLbHMgfPuS0FgiWTtFIm/Nj+2woXDLTZ7fOT2eqzgYbdMlLweqlHbsZjxEChoVK+7iph7jyQg==", + "license": "MIT", + "dependencies": { + "cheerio-select": "^2.1.0", + "dom-serializer": "^2.0.0", + "domhandler": "^5.0.3", + "domutils": "^3.2.2", + "encoding-sniffer": "^0.2.1", + "htmlparser2": "^10.0.0", + "parse5": "^7.3.0", + "parse5-htmlparser2-tree-adapter": "^7.1.0", + "parse5-parser-stream": "^7.1.2", + "undici": "^7.12.0", + "whatwg-mimetype": "^4.0.0" + }, + "engines": { + "node": ">=20.18.1" + }, + "funding": { + "url": "https://github.com/cheeriojs/cheerio?sponsor=1" + } + }, + "node_modules/cheerio-select": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cheerio-select/-/cheerio-select-2.1.0.tgz", + "integrity": "sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==", + "license": "BSD-2-Clause", + "dependencies": { + "boolbase": "^1.0.0", + "css-select": "^5.1.0", + "css-what": "^6.1.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3", + "domutils": "^3.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "license": "MIT", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/concat-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-2.0.0.tgz", + "integrity": "sha512-MWufYdFw53ccGjCA+Ol7XJYpAlW6/prSMzuPOTRnJGcGzuhLn4Scrz7qf6o8bROZ514ltazcIFJZevcfbo0x7A==", + "engines": [ + "node >= 6.0" + ], + "license": "MIT", + "dependencies": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.0.2", + "typedarray": "^0.0.6" + } + }, + "node_modules/content-disposition": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-1.0.1.tgz", + "integrity": "sha512-oIXISMynqSqm241k6kcQ5UwttDILMK4BiurCfGEREw6+X9jkkpEe5T9FZaApyLGGOnFuyMWZpdolTXMtvEJ08Q==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/content-type": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz", + "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie-signature": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.2.2.tgz", + "integrity": "sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==", + "license": "MIT", + "engines": { + "node": ">=6.6.0" + } + }, + "node_modules/cors": { + "version": "2.8.5", + "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", + "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", + "license": "MIT", + "dependencies": { + "object-assign": "^4", + "vary": "^1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/css-select": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.2.2.tgz", + "integrity": "sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw==", + "license": "BSD-2-Clause", + "dependencies": { + "boolbase": "^1.0.0", + "css-what": "^6.1.0", + "domhandler": "^5.0.2", + "domutils": "^3.0.1", + "nth-check": "^2.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/css-what": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.2.2.tgz", + "integrity": "sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA==", + "license": "BSD-2-Clause", + "engines": { + "node": ">= 6" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/decode-bmp": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/decode-bmp/-/decode-bmp-0.2.1.tgz", + "integrity": "sha512-NiOaGe+GN0KJqi2STf24hfMkFitDUaIoUU3eKvP/wAbLe8o6FuW5n/x7MHPR0HKvBokp6MQY/j7w8lewEeVCIA==", + "license": "MIT", + "dependencies": { + "@canvas/image-data": "^1.0.0", + "to-data-view": "^1.1.0" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/decode-bmp/node_modules/to-data-view": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/to-data-view/-/to-data-view-1.1.0.tgz", + "integrity": "sha512-1eAdufMg6mwgmlojAx3QeMnzB/BTVp7Tbndi3U7ftcT2zCZadjxkkmLmd97zmaxWi+sgGcgWrokmpEoy0Dn0vQ==", + "license": "MIT" + }, + "node_modules/decode-ico": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/decode-ico/-/decode-ico-0.4.1.tgz", + "integrity": "sha512-69NZfbKIzux1vBOd31al3XnMnH+2mqDhEgLdpygErm4d60N+UwA5Sq5WFjmEDQzumgB9fElojGwWG0vybVfFmA==", + "license": "MIT", + "dependencies": { + "@canvas/image-data": "^1.0.0", + "decode-bmp": "^0.2.0", + "to-data-view": "^1.1.0" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/decode-ico/node_modules/to-data-view": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/to-data-view/-/to-data-view-1.1.0.tgz", + "integrity": "sha512-1eAdufMg6mwgmlojAx3QeMnzB/BTVp7Tbndi3U7ftcT2zCZadjxkkmLmd97zmaxWi+sgGcgWrokmpEoy0Dn0vQ==", + "license": "MIT" + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/detect-libc": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", + "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", + "license": "Apache-2.0", + "engines": { + "node": ">=8" + } + }, + "node_modules/dom-serializer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", + "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", + "license": "MIT", + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.2", + "entities": "^4.2.0" + }, + "funding": { + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" + } + }, + "node_modules/domelementtype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", + "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "license": "BSD-2-Clause" + }, + "node_modules/domhandler": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", + "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", + "license": "BSD-2-Clause", + "dependencies": { + "domelementtype": "^2.3.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, + "node_modules/domutils": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.2.2.tgz", + "integrity": "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==", + "license": "BSD-2-Clause", + "dependencies": { + "dom-serializer": "^2.0.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3" + }, + "funding": { + "url": "https://github.com/fb55/domutils?sponsor=1" + } + }, + "node_modules/dotenv": { + "version": "17.2.3", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-17.2.3.tgz", + "integrity": "sha512-JVUnt+DUIzu87TABbhPmNfVdBDt18BLOWjMUFJMSi/Qqg7NTYtabbvSNJGOJ7afbRuv9D/lngizHtP7QyLQ+9w==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" + } + }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/ecdsa-sig-formatter": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", + "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", + "license": "Apache-2.0", + "dependencies": { + "safe-buffer": "^5.0.1" + } + }, + "node_modules/ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", + "license": "MIT" + }, + "node_modules/encodeurl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", + "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/encoding-sniffer": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/encoding-sniffer/-/encoding-sniffer-0.2.1.tgz", + "integrity": "sha512-5gvq20T6vfpekVtqrYQsSCFZ1wEg5+wW0/QaZMWkFr6BqD3NfKs0rLCx4rrVlSWJeZb5NBJgVLswK/w2MWU+Gw==", + "license": "MIT", + "dependencies": { + "iconv-lite": "^0.6.3", + "whatwg-encoding": "^3.1.1" + }, + "funding": { + "url": "https://github.com/fb55/encoding-sniffer?sponsor=1" + } + }, + "node_modules/encoding-sniffer/node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-object-atoms": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-set-tostringtag": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", + "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", + "license": "MIT" + }, + "node_modules/etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/event-target-shim": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", + "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/events": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">=0.8.x" + } + }, + "node_modules/exif-parser": { + "version": "0.1.12", + "resolved": "https://registry.npmjs.org/exif-parser/-/exif-parser-0.1.12.tgz", + "integrity": "sha512-c2bQfLNbMzLPmzQuOr8fy0csy84WmwnER81W88DzTp9CYNPJ6yzOj2EZAh9pywYpqHnshVLHQJ8WzldAyfY+Iw==", + "peer": true + }, + "node_modules/express": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/express/-/express-5.2.1.tgz", + "integrity": "sha512-hIS4idWWai69NezIdRt2xFVofaF4j+6INOpJlVOLDO8zXGpUVEVzIYk12UUi2JzjEzWL3IOAxcTubgz9Po0yXw==", + "license": "MIT", + "dependencies": { + "accepts": "^2.0.0", + "body-parser": "^2.2.1", + "content-disposition": "^1.0.0", + "content-type": "^1.0.5", + "cookie": "^0.7.1", + "cookie-signature": "^1.2.1", + "debug": "^4.4.0", + "depd": "^2.0.0", + "encodeurl": "^2.0.0", + "escape-html": "^1.0.3", + "etag": "^1.8.1", + "finalhandler": "^2.1.0", + "fresh": "^2.0.0", + "http-errors": "^2.0.0", + "merge-descriptors": "^2.0.0", + "mime-types": "^3.0.0", + "on-finished": "^2.4.1", + "once": "^1.4.0", + "parseurl": "^1.3.3", + "proxy-addr": "^2.0.7", + "qs": "^6.14.0", + "range-parser": "^1.2.1", + "router": "^2.2.0", + "send": "^1.1.0", + "serve-static": "^2.2.0", + "statuses": "^2.0.1", + "type-is": "^2.0.1", + "vary": "^1.1.2" + }, + "engines": { + "node": ">= 18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/file-type": { + "version": "21.3.0", + "resolved": "https://registry.npmjs.org/file-type/-/file-type-21.3.0.tgz", + "integrity": "sha512-8kPJMIGz1Yt/aPEwOsrR97ZyZaD1Iqm8PClb1nYFclUCkBi0Ma5IsYNQzvSFS9ib51lWyIw5mIT9rWzI/xjpzA==", + "license": "MIT", + "dependencies": { + "@tokenizer/inflate": "^0.4.1", + "strtok3": "^10.3.4", + "token-types": "^6.1.1", + "uint8array-extras": "^1.4.0" + }, + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sindresorhus/file-type?sponsor=1" + } + }, + "node_modules/finalhandler": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-2.1.1.tgz", + "integrity": "sha512-S8KoZgRZN+a5rNwqTxlZZePjT/4cnm0ROV70LedRHZ0p8u9fRID0hJUZQpkKLzro8LfmC8sx23bY6tVNxv8pQA==", + "license": "MIT", + "dependencies": { + "debug": "^4.4.0", + "encodeurl": "^2.0.0", + "escape-html": "^1.0.3", + "on-finished": "^2.4.1", + "parseurl": "^1.3.3", + "statuses": "^2.0.1" + }, + "engines": { + "node": ">= 18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/follow-redirects": { + "version": "1.15.11", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.11.tgz", + "integrity": "sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "license": "MIT", + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/form-data": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.5.tgz", + "integrity": "sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==", + "license": "MIT", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "es-set-tostringtag": "^2.1.0", + "hasown": "^2.0.2", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/form-data/node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/form-data/node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fresh": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-2.0.0.tgz", + "integrity": "sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-intrinsic": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "license": "MIT", + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/htmlparser2": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-10.0.0.tgz", + "integrity": "sha512-TwAZM+zE5Tq3lrEHvOlvwgj1XLWQCtaaibSN11Q+gGBAS7Y1uZSWwXXRe4iF6OXnaq1riyQAPFOBtYc77Mxq0g==", + "funding": [ + "https://github.com/fb55/htmlparser2?sponsor=1", + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "license": "MIT", + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3", + "domutils": "^3.2.1", + "entities": "^6.0.0" + } + }, + "node_modules/htmlparser2/node_modules/entities": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-6.0.1.tgz", + "integrity": "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/http-errors": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.1.tgz", + "integrity": "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==", + "license": "MIT", + "dependencies": { + "depd": "~2.0.0", + "inherits": "~2.0.4", + "setprototypeof": "~1.2.0", + "statuses": "~2.0.2", + "toidentifier": "~1.0.1" + }, + "engines": { + "node": ">= 0.8" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/icojs": { + "version": "0.20.1", + "resolved": "https://registry.npmjs.org/icojs/-/icojs-0.20.1.tgz", + "integrity": "sha512-5CgDmAMlXmqMLFSCKTKrWK5FJl9WaA5Y8y3vtuNSas0HZx9O7dtS+xgeIu7jG8W3VQSXWAXdoGaILtF6ktjE7Q==", + "license": "MIT", + "dependencies": { + "@jimp/bmp": "^0.22.12", + "decode-ico": "^0.4.1", + "file-type": "^21.0.0", + "jpeg-js": "^0.4.4", + "pngjs": "^7.0.0", + "to-data-view": "^2.0.0" + }, + "engines": { + "node": ">=20.19.4" + } + }, + "node_modules/iconv-lite": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.1.tgz", + "integrity": "sha512-2Tth85cXwGFHfvRgZWszZSvdo+0Xsqmw8k8ZwxScfcBneNUraK+dxRxRm24nszx80Y0TVio8kKLt5sLE7ZCLlw==", + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "BSD-3-Clause" + }, + "node_modules/image-size": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/image-size/-/image-size-2.0.2.tgz", + "integrity": "sha512-IRqXKlaXwgSMAMtpNzZa1ZAe8m+Sa1770Dhk8VkSsP9LS+iHD62Zd8FQKs8fbPiagBE7BzoFX23cxFnwshpV6w==", + "license": "MIT", + "bin": { + "image-size": "bin/image-size.js" + }, + "engines": { + "node": ">=16.x" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "license": "ISC" + }, + "node_modules/ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "license": "MIT", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/is-promise": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-4.0.0.tgz", + "integrity": "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==", + "license": "MIT" + }, + "node_modules/isomorphic-fetch": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/isomorphic-fetch/-/isomorphic-fetch-3.0.0.tgz", + "integrity": "sha512-qvUtwJ3j6qwsF3jLxkZ72qCgjMysPzDfeV240JHiGZsANBYd+EEuu35v7dfrJ9Up0Ak07D7GGSkGhCHTqg/5wA==", + "license": "MIT", + "peer": true, + "dependencies": { + "node-fetch": "^2.6.1", + "whatwg-fetch": "^3.4.1" + } + }, + "node_modules/jpeg-js": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/jpeg-js/-/jpeg-js-0.4.4.tgz", + "integrity": "sha512-WZzeDOEtTOBK4Mdsar0IqEU5sMr3vSV2RqkAIzUEV2BHnUfKGyswWFPFwK5EeDo93K3FohSHbLAjj0s1Wzd+dg==", + "license": "BSD-3-Clause" + }, + "node_modules/jsonwebtoken": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.3.tgz", + "integrity": "sha512-MT/xP0CrubFRNLNKvxJ2BYfy53Zkm++5bX9dtuPbqAeQpTVe0MQTFhao8+Cp//EmJp244xt6Drw/GVEGCUj40g==", + "license": "MIT", + "dependencies": { + "jws": "^4.0.1", + "lodash.includes": "^4.3.0", + "lodash.isboolean": "^3.0.3", + "lodash.isinteger": "^4.0.4", + "lodash.isnumber": "^3.0.3", + "lodash.isplainobject": "^4.0.6", + "lodash.isstring": "^4.0.1", + "lodash.once": "^4.0.0", + "ms": "^2.1.1", + "semver": "^7.5.4" + }, + "engines": { + "node": ">=12", + "npm": ">=6" + } + }, + "node_modules/jwa": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/jwa/-/jwa-2.0.1.tgz", + "integrity": "sha512-hRF04fqJIP8Abbkq5NKGN0Bbr3JxlQ+qhZufXVr0DvujKy93ZCbXZMHDL4EOtodSbCWxOqR8MS1tXA5hwqCXDg==", + "license": "MIT", + "dependencies": { + "buffer-equal-constant-time": "^1.0.1", + "ecdsa-sig-formatter": "1.0.11", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/jws": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/jws/-/jws-4.0.1.tgz", + "integrity": "sha512-EKI/M/yqPncGUUh44xz0PxSidXFr/+r0pA70+gIYhjv+et7yxM+s29Y+VGDkovRofQem0fs7Uvf4+YmAdyRduA==", + "license": "MIT", + "dependencies": { + "jwa": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/kareem": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/kareem/-/kareem-3.0.0.tgz", + "integrity": "sha512-RKhaOBSPN8L7y4yAgNhDT2602G5FD6QbOIISbjN9D6mjHPeqeg7K+EB5IGSU5o81/X2Gzm3ICnAvQW3x3OP8HA==", + "license": "Apache-2.0", + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/lodash.includes": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz", + "integrity": "sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==", + "license": "MIT" + }, + "node_modules/lodash.isboolean": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz", + "integrity": "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==", + "license": "MIT" + }, + "node_modules/lodash.isinteger": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz", + "integrity": "sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA==", + "license": "MIT" + }, + "node_modules/lodash.isnumber": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz", + "integrity": "sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw==", + "license": "MIT" + }, + "node_modules/lodash.isplainobject": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", + "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==", + "license": "MIT" + }, + "node_modules/lodash.isstring": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", + "integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==", + "license": "MIT" + }, + "node_modules/lodash.once": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", + "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==", + "license": "MIT" + }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/media-typer": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-1.1.0.tgz", + "integrity": "sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/memory-pager": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/memory-pager/-/memory-pager-1.5.0.tgz", + "integrity": "sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg==", + "license": "MIT" + }, + "node_modules/merge-descriptors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-2.0.0.tgz", + "integrity": "sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mime-db": { + "version": "1.54.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz", + "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.2.tgz", + "integrity": "sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==", + "license": "MIT", + "dependencies": { + "mime-db": "^1.54.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/mkdirp": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", + "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", + "license": "MIT", + "dependencies": { + "minimist": "^1.2.6" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/mongodb": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-7.0.0.tgz", + "integrity": "sha512-vG/A5cQrvGGvZm2mTnCSz1LUcbOPl83hfB6bxULKQ8oFZauyox/2xbZOoGNl+64m8VBrETkdGCDBdOsCr3F3jg==", + "license": "Apache-2.0", + "dependencies": { + "@mongodb-js/saslprep": "^1.3.0", + "bson": "^7.0.0", + "mongodb-connection-string-url": "^7.0.0" + }, + "engines": { + "node": ">=20.19.0" + }, + "peerDependencies": { + "@aws-sdk/credential-providers": "^3.806.0", + "@mongodb-js/zstd": "^7.0.0", + "gcp-metadata": "^7.0.1", + "kerberos": "^7.0.0", + "mongodb-client-encryption": ">=7.0.0 <7.1.0", + "snappy": "^7.3.2", + "socks": "^2.8.6" + }, + "peerDependenciesMeta": { + "@aws-sdk/credential-providers": { + "optional": true + }, + "@mongodb-js/zstd": { + "optional": true + }, + "gcp-metadata": { + "optional": true + }, + "kerberos": { + "optional": true + }, + "mongodb-client-encryption": { + "optional": true + }, + "snappy": { + "optional": true + }, + "socks": { + "optional": true + } + } + }, + "node_modules/mongodb-connection-string-url": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/mongodb-connection-string-url/-/mongodb-connection-string-url-7.0.0.tgz", + "integrity": "sha512-irhhjRVLE20hbkRl4zpAYLnDMM+zIZnp0IDB9akAFFUZp/3XdOfwwddc7y6cNvF2WCEtfTYRwYbIfYa2kVY0og==", + "license": "Apache-2.0", + "dependencies": { + "@types/whatwg-url": "^13.0.0", + "whatwg-url": "^14.1.0" + }, + "engines": { + "node": ">=20.19.0" + } + }, + "node_modules/mongoose": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-9.0.2.tgz", + "integrity": "sha512-+GCaqwE+X//yN9eo2M2L/n+mVti9J6vH5iQKbhD+2AArZd5iaZqK/DkmkE4S6/iYYMyVQPTXsRk7jyVOYEtJzA==", + "license": "MIT", + "dependencies": { + "kareem": "3.0.0", + "mongodb": "~7.0", + "mpath": "0.9.0", + "mquery": "6.0.0", + "ms": "2.1.3", + "sift": "17.1.3" + }, + "engines": { + "node": ">=20.19.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mongoose" + } + }, + "node_modules/mpath": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/mpath/-/mpath-0.9.0.tgz", + "integrity": "sha512-ikJRQTk8hw5DEoFVxHG1Gn9T/xcjtdnOKIU1JTmGjZZlg9LST2mBLmcX3/ICIbgJydT2GOc15RnNy5mHmzfSew==", + "license": "MIT", + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/mquery": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/mquery/-/mquery-6.0.0.tgz", + "integrity": "sha512-b2KQNsmgtkscfeDgkYMcWGn9vZI9YoXh802VDEwE6qc50zxBFQ0Oo8ROkawbPAsXCY1/Z1yp0MagqsZStPWJjw==", + "license": "MIT", + "engines": { + "node": ">=20.19.0" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" + }, + "node_modules/multer": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/multer/-/multer-2.0.2.tgz", + "integrity": "sha512-u7f2xaZ/UG8oLXHvtF/oWTRvT44p9ecwBBqTwgJVq0+4BW1g8OW01TyMEGWBHbyMOYVHXslaut7qEQ1meATXgw==", + "license": "MIT", + "dependencies": { + "append-field": "^1.0.0", + "busboy": "^1.6.0", + "concat-stream": "^2.0.0", + "mkdirp": "^0.5.6", + "object-assign": "^4.1.1", + "type-is": "^1.6.18", + "xtend": "^4.0.2" + }, + "engines": { + "node": ">= 10.16.0" + } + }, + "node_modules/multer/node_modules/media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/multer/node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/multer/node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/multer/node_modules/type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "license": "MIT", + "dependencies": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/negotiator": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-1.0.0.tgz", + "integrity": "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/node-fetch": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", + "license": "MIT", + "peer": true, + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, + "node_modules/node-fetch/node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", + "license": "MIT", + "peer": true + }, + "node_modules/node-fetch/node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", + "license": "BSD-2-Clause", + "peer": true + }, + "node_modules/node-fetch/node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "license": "MIT", + "peer": true, + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, + "node_modules/nth-check": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", + "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", + "license": "BSD-2-Clause", + "dependencies": { + "boolbase": "^1.0.0" + }, + "funding": { + "url": "https://github.com/fb55/nth-check?sponsor=1" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-inspect": { + "version": "1.13.4", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", + "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "license": "MIT", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "license": "ISC", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/parse5": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.3.0.tgz", + "integrity": "sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==", + "license": "MIT", + "dependencies": { + "entities": "^6.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/parse5-htmlparser2-tree-adapter": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-7.1.0.tgz", + "integrity": "sha512-ruw5xyKs6lrpo9x9rCZqZZnIUntICjQAd0Wsmp396Ul9lN/h+ifgVV1x1gZHi8euej6wTfpqX8j+BFQxF0NS/g==", + "license": "MIT", + "dependencies": { + "domhandler": "^5.0.3", + "parse5": "^7.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/parse5-parser-stream": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/parse5-parser-stream/-/parse5-parser-stream-7.1.2.tgz", + "integrity": "sha512-JyeQc9iwFLn5TbvvqACIF/VXG6abODeB3Fwmv/TGdLk2LfbWkaySGY72at4+Ty7EkPZj854u4CrICqNk2qIbow==", + "license": "MIT", + "dependencies": { + "parse5": "^7.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/parse5/node_modules/entities": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-6.0.1.tgz", + "integrity": "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/path-to-regexp": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.3.0.tgz", + "integrity": "sha512-7jdwVIRtsP8MYpdXSwOS0YdD0Du+qOoF/AEPIt88PcCFrZCzx41oxku1jD88hZBwbNUIEfpqvuhjFaMAqMTWnA==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/peek-readable": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/peek-readable/-/peek-readable-4.1.0.tgz", + "integrity": "sha512-ZI3LnwUv5nOGbQzD9c2iDG6toheuXSZP5esSHBjopsXH4dg19soufvpUGA3uohi5anFtGb2lhAVdHzH6R/Evvg==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">=8" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Borewit" + } + }, + "node_modules/pixelmatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/pixelmatch/-/pixelmatch-4.0.2.tgz", + "integrity": "sha512-J8B6xqiO37sU/gkcMglv6h5Jbd9xNER7aHzpfRdNmV4IbQBzBpe4l9XmbG+xPF/znacgu2jfEw+wHffaq/YkXA==", + "license": "ISC", + "peer": true, + "dependencies": { + "pngjs": "^3.0.0" + }, + "bin": { + "pixelmatch": "bin/pixelmatch" + } + }, + "node_modules/pixelmatch/node_modules/pngjs": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/pngjs/-/pngjs-3.4.0.tgz", + "integrity": "sha512-NCrCHhWmnQklfH4MtJMRjZ2a8c80qXeMlQMv2uVp9ISJMTt562SbGd6n2oq0PaPgKm7Z6pL9E2UlLIhC+SHL3w==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/pngjs": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/pngjs/-/pngjs-7.0.0.tgz", + "integrity": "sha512-LKWqWJRhstyYo9pGvgor/ivk2w94eSjE3RGVuzLGlr3NmD8bf7RcYGze1mNdEHRP6TRP6rMuDHk5t44hnTRyow==", + "license": "MIT", + "engines": { + "node": ">=14.19.0" + } + }, + "node_modules/process": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">= 0.6.0" + } + }, + "node_modules/proxy-addr": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "license": "MIT", + "dependencies": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "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==", + "license": "MIT" + }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/qs": { + "version": "6.14.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.0.tgz", + "integrity": "sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==", + "license": "BSD-3-Clause", + "dependencies": { + "side-channel": "^1.1.0" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/raw-body": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-3.0.2.tgz", + "integrity": "sha512-K5zQjDllxWkf7Z5xJdV0/B0WTNqx6vxG70zJE4N0kBs4LovmEYWJzQGxC9bS9RAKu3bgM40lrd5zoLJ12MQ5BA==", + "license": "MIT", + "dependencies": { + "bytes": "~3.1.2", + "http-errors": "~2.0.1", + "iconv-lite": "~0.7.0", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/readable-web-to-node-stream": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/readable-web-to-node-stream/-/readable-web-to-node-stream-3.0.4.tgz", + "integrity": "sha512-9nX56alTf5bwXQ3ZDipHJhusu9NTQJ/CVPtb/XHAJCXihZeitfJvIRS4GqQ/mfIoOE3IelHMrpayVrosdHBuLw==", + "license": "MIT", + "peer": true, + "dependencies": { + "readable-stream": "^4.7.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Borewit" + } + }, + "node_modules/readable-web-to-node-stream/node_modules/buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "peer": true, + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, + "node_modules/readable-web-to-node-stream/node_modules/readable-stream": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.7.0.tgz", + "integrity": "sha512-oIGGmcpTLwPga8Bn6/Z75SVaH1z5dUut2ibSyAMVhmUggWpmDn2dapB0n7f8nwaSiRtepAsfJyfXIO5DCVAODg==", + "license": "MIT", + "peer": true, + "dependencies": { + "abort-controller": "^3.0.0", + "buffer": "^6.0.3", + "events": "^3.3.0", + "process": "^0.11.10", + "string_decoder": "^1.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/regenerator-runtime": { + "version": "0.13.11", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz", + "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==", + "license": "MIT" + }, + "node_modules/router": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/router/-/router-2.2.0.tgz", + "integrity": "sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==", + "license": "MIT", + "dependencies": { + "debug": "^4.4.0", + "depd": "^2.0.0", + "is-promise": "^4.0.0", + "parseurl": "^1.3.3", + "path-to-regexp": "^8.0.0" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "license": "MIT" + }, + "node_modules/semver": { + "version": "7.7.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", + "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/send": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/send/-/send-1.2.1.tgz", + "integrity": "sha512-1gnZf7DFcoIcajTjTwjwuDjzuz4PPcY2StKPlsGAQ1+YH20IRVrBaXSWmdjowTJ6u8Rc01PoYOGHXfP1mYcZNQ==", + "license": "MIT", + "dependencies": { + "debug": "^4.4.3", + "encodeurl": "^2.0.0", + "escape-html": "^1.0.3", + "etag": "^1.8.1", + "fresh": "^2.0.0", + "http-errors": "^2.0.1", + "mime-types": "^3.0.2", + "ms": "^2.1.3", + "on-finished": "^2.4.1", + "range-parser": "^1.2.1", + "statuses": "^2.0.2" + }, + "engines": { + "node": ">= 18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/serve-static": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-2.2.1.tgz", + "integrity": "sha512-xRXBn0pPqQTVQiC8wyQrKs2MOlX24zQ0POGaj0kultvoOCstBQM5yvOhAVSUwOMjQtTvsPWoNCHfPGwaaQJhTw==", + "license": "MIT", + "dependencies": { + "encodeurl": "^2.0.0", + "escape-html": "^1.0.3", + "parseurl": "^1.3.3", + "send": "^1.2.0" + }, + "engines": { + "node": ">= 18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", + "license": "ISC" + }, + "node_modules/sharp": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.34.5.tgz", + "integrity": "sha512-Ou9I5Ft9WNcCbXrU9cMgPBcCK8LiwLqcbywW3t4oDV37n1pzpuNLsYiAV8eODnjbtQlSDwZ2cUEeQz4E54Hltg==", + "hasInstallScript": true, + "license": "Apache-2.0", + "dependencies": { + "@img/colour": "^1.0.0", + "detect-libc": "^2.1.2", + "semver": "^7.7.3" + }, + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-darwin-arm64": "0.34.5", + "@img/sharp-darwin-x64": "0.34.5", + "@img/sharp-libvips-darwin-arm64": "1.2.4", + "@img/sharp-libvips-darwin-x64": "1.2.4", + "@img/sharp-libvips-linux-arm": "1.2.4", + "@img/sharp-libvips-linux-arm64": "1.2.4", + "@img/sharp-libvips-linux-ppc64": "1.2.4", + "@img/sharp-libvips-linux-riscv64": "1.2.4", + "@img/sharp-libvips-linux-s390x": "1.2.4", + "@img/sharp-libvips-linux-x64": "1.2.4", + "@img/sharp-libvips-linuxmusl-arm64": "1.2.4", + "@img/sharp-libvips-linuxmusl-x64": "1.2.4", + "@img/sharp-linux-arm": "0.34.5", + "@img/sharp-linux-arm64": "0.34.5", + "@img/sharp-linux-ppc64": "0.34.5", + "@img/sharp-linux-riscv64": "0.34.5", + "@img/sharp-linux-s390x": "0.34.5", + "@img/sharp-linux-x64": "0.34.5", + "@img/sharp-linuxmusl-arm64": "0.34.5", + "@img/sharp-linuxmusl-x64": "0.34.5", + "@img/sharp-wasm32": "0.34.5", + "@img/sharp-win32-arm64": "0.34.5", + "@img/sharp-win32-ia32": "0.34.5", + "@img/sharp-win32-x64": "0.34.5" + } + }, + "node_modules/side-channel": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", + "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3", + "side-channel-list": "^1.0.0", + "side-channel-map": "^1.0.1", + "side-channel-weakmap": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-list": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", + "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-map": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", + "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-weakmap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", + "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3", + "side-channel-map": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/sift": { + "version": "17.1.3", + "resolved": "https://registry.npmjs.org/sift/-/sift-17.1.3.tgz", + "integrity": "sha512-Rtlj66/b0ICeFzYTuNvX/EF1igRbbnGSvEyT79McoZa/DeGhMyC5pWKOEsZKnpkqtSeovd5FL/bjHWC3CIIvCQ==", + "license": "MIT" + }, + "node_modules/sparse-bitfield": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz", + "integrity": "sha512-kvzhi7vqKTfkh0PZU+2D2PIllw2ymqJKujUcyPMd9Y75Nv4nPbGJZXNhxsgdQab2BmlDct1YnfQCguEvHr7VsQ==", + "license": "MIT", + "dependencies": { + "memory-pager": "^1.0.2" + } + }, + "node_modules/statuses": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz", + "integrity": "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/streamsearch": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz", + "integrity": "sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==", + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/string_decoder": { + "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==", + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/strtok3": { + "version": "10.3.4", + "resolved": "https://registry.npmjs.org/strtok3/-/strtok3-10.3.4.tgz", + "integrity": "sha512-KIy5nylvC5le1OdaaoCJ07L+8iQzJHGH6pWDuzS+d07Cu7n1MZ2x26P8ZKIWfbK02+XIL8Mp4RkWeqdUCrDMfg==", + "license": "MIT", + "dependencies": { + "@tokenizer/token": "^0.3.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Borewit" + } + }, + "node_modules/tinycolor2": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/tinycolor2/-/tinycolor2-1.6.0.tgz", + "integrity": "sha512-XPaBkWQJdsf3pLKJV9p4qN/S+fm2Oj8AIPo1BTUhg5oxkvm9+SVEGFdhyOz7tTdUTfvxMiAs4sp6/eZO2Ew+pw==", + "license": "MIT", + "peer": true + }, + "node_modules/to-data-view": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-data-view/-/to-data-view-2.0.0.tgz", + "integrity": "sha512-RGEM5KqlPHr+WVTPmGNAXNeFEmsBnlkxXaIfEpUYV0AST2Z5W1EGq9L/MENFrMMmL2WQr1wjkmZy/M92eKhjYA==", + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + } + }, + "node_modules/toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "license": "MIT", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/token-types": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/token-types/-/token-types-6.1.2.tgz", + "integrity": "sha512-dRXchy+C0IgK8WPC6xvCHFRIWYUbqqdEIKPaKo/AcTUNzwLTK6AH7RjdLWsEZcAN/TBdtfUw3PYEgPr5VPr6ww==", + "license": "MIT", + "dependencies": { + "@borewit/text-codec": "^0.2.1", + "@tokenizer/token": "^0.3.0", + "ieee754": "^1.2.1" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Borewit" + } + }, + "node_modules/tr46": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-5.1.1.tgz", + "integrity": "sha512-hdF5ZgjTqgAntKkklYw0R03MG2x/bSzTtkxmIRw/sTNV8YXsCJ1tfLAX23lhxhHJlEf3CRCOCGGWw3vI3GaSPw==", + "license": "MIT", + "dependencies": { + "punycode": "^2.3.1" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD", + "optional": true + }, + "node_modules/type-is": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-2.0.1.tgz", + "integrity": "sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==", + "license": "MIT", + "dependencies": { + "content-type": "^1.0.5", + "media-typer": "^1.1.0", + "mime-types": "^3.0.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==", + "license": "MIT" + }, + "node_modules/uint8array-extras": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/uint8array-extras/-/uint8array-extras-1.5.0.tgz", + "integrity": "sha512-rvKSBiC5zqCCiDZ9kAOszZcDvdAHwwIKJG33Ykj43OKcWsnmcBRL09YTU4nOeHZ8Y2a7l1MgTd08SBe9A8Qj6A==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/undici": { + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/undici/-/undici-7.16.0.tgz", + "integrity": "sha512-QEg3HPMll0o3t2ourKwOeUAZ159Kn9mx5pnzHRQO8+Wixmh88YdZRiIwat0iNzNNXn0yoEtXJqFpyW7eM8BV7g==", + "license": "MIT", + "engines": { + "node": ">=20.18.1" + } + }, + "node_modules/unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "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==", + "license": "MIT" + }, + "node_modules/vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/webidl-conversions": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", + "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=12" + } + }, + "node_modules/whatwg-encoding": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-3.1.1.tgz", + "integrity": "sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==", + "deprecated": "Use @exodus/bytes instead for a more spec-conformant and faster implementation", + "license": "MIT", + "dependencies": { + "iconv-lite": "0.6.3" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/whatwg-encoding/node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/whatwg-fetch": { + "version": "3.6.20", + "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.6.20.tgz", + "integrity": "sha512-EqhiFU6daOA8kpjOWTL0olhVOF3i7OrFzSYiGsEMB8GcXS+RrzauAERX65xMeNWVqxA6HXH2m69Z9LaKKdisfg==", + "license": "MIT", + "peer": true + }, + "node_modules/whatwg-mimetype": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-4.0.0.tgz", + "integrity": "sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==", + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/whatwg-url": { + "version": "14.2.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-14.2.0.tgz", + "integrity": "sha512-De72GdQZzNTUBBChsXueQUnPKDkg/5A5zp7pFDuQAj5UFoENpiACU0wlCvzpAGnTkj++ihpKwKyYewn/XNUbKw==", + "license": "MIT", + "dependencies": { + "tr46": "^5.1.0", + "webidl-conversions": "^7.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "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==", + "license": "ISC" + }, + "node_modules/xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "license": "MIT", + "engines": { + "node": ">=0.4" + } + } + } +} diff --git a/server/package.json b/server/package.json new file mode 100644 index 0000000..642109e --- /dev/null +++ b/server/package.json @@ -0,0 +1,20 @@ +{ + "type": "module", + "dependencies": { + "axios": "^1.13.2", + "bcryptjs": "^3.0.3", + "cheerio": "^1.1.2", + "cors": "^2.8.5", + "dotenv": "^17.2.3", + "express": "^5.2.1", + "icojs": "^0.20.1", + "image-size": "^2.0.2", + "jsonwebtoken": "^9.0.3", + "mongoose": "^9.0.2", + "multer": "^2.0.2", + "sharp": "^0.34.5" + }, + "scripts": { + "start": "node index.js" + } +} diff --git a/server/routes/auth.js b/server/routes/auth.js new file mode 100644 index 0000000..2f0d618 --- /dev/null +++ b/server/routes/auth.js @@ -0,0 +1,42 @@ +import express from "express"; +import bcrypt from "bcryptjs"; +import jwt from "jsonwebtoken"; +import User from "../models/User.js"; + +const router = express.Router(); + +// Registrazione +router.post("/register", async (req, res) => { + const { email, password } = req.body; + if (!email || !password) + return res.status(400).json({ error: "Email e password richiesti" }); + + const existing = await User.findOne({ email }); + if (existing) return res.status(400).json({ error: "Email già registrata" }); + + const passwordHash = await bcrypt.hash(password, 10); + + const user = await User.create({ email, passwordHash }); + + res.json({ id: user._id, email: user.email }); +}); + +// Login +router.post("/login", async (req, res) => { + const { email, password } = req.body; + const user = await User.findOne({ email }); + if (!user) return res.status(400).json({ error: "Credenziali non valide" }); + + const valid = await bcrypt.compare(password, user.passwordHash); + if (!valid) return res.status(400).json({ error: "Credenziali non valide" }); + + const token = jwt.sign( + { userId: user._id }, + process.env.JWT_SECRET || "devsecret", + { expiresIn: "7d" } + ); + + res.json({ token }); +}); + +export default router; diff --git a/server/routes/links.js b/server/routes/links.js new file mode 100644 index 0000000..2aa9160 --- /dev/null +++ b/server/routes/links.js @@ -0,0 +1,162 @@ +import express from "express"; +import multer from "multer"; +import axios from "axios"; +import sharp from "sharp"; +import Link from "../models/Link.js"; +import { authMiddleware } from "../middleware/auth.js"; +import { parseICO } from "icojs"; + +const router = express.Router(); + +// Multer in-memory (niente filesystem) +const upload = multer({ storage: multer.memoryStorage() }); + +router.use(authMiddleware); + +// Scarica immagine remota come Buffer +async function downloadImageAsBuffer(url) { + const response = await axios.get(url, { + responseType: "arraybuffer", + maxRedirects: 5, + headers: { + "User-Agent": "Mozilla/5.0", + "Accept": "image/*" + } + }); + + return { + buffer: Buffer.from(response.data), + mime: response.headers["content-type"] || "" + }; +} + +// Converte immagine → WebP 128x128 contain +async function processIcon(buffer, mime) { + let inputBuffer = buffer; + + // Se è ICO → converti in PNG + if (mime === "image/x-icon" || mime === "image/vnd.microsoft.icon") { + const images = await parseICO(buffer); + + if (!images.length) { + throw new Error("ICO non valido"); + } + + // Prendiamo l’immagine più grande dentro l’ICO + const best = images.reduce((a, b) => (a.width > b.width ? a : b)); + + inputBuffer = Buffer.from(best.buffer); + } + + // Ora Sharp può lavorare + return await sharp(inputBuffer) + .resize(128, 128, { + fit: "contain", + background: { r: 0, g: 0, b: 0, alpha: 0 } + }) + .webp({ quality: 90 }) + .toBuffer(); +} + +// =============================== +// GET LINKS +// =============================== +router.get("/", async (req, res) => { + const links = await Link.find({ owner: req.userId }); + res.json(links); +}); + +// =============================== +// CREATE LINK +// =============================== +router.post("/", upload.single("icon"), async (req, res) => { + const { url, name, iconURL } = req.body; + + let originalBuffer = null; + + // Caso 1: upload file + if (req.file) { + originalBuffer = req.file.buffer; + } + + // Caso 2: URL remoto + else if (iconURL) { + originalBuffer = await downloadImageAsBuffer(iconURL); + } + + let processedIcon = null; + + if (originalBuffer) { + processedIcon = await processIcon(originalBuffer.buffer, originalBuffer.mime); + } + + + const link = await Link.create({ + url, + name, + owner: req.userId, + icon: processedIcon + ? { + data: processedIcon, + mime: "image/webp", + size: processedIcon.length + } + : null + }); + + res.json(link); +}); + +// =============================== +// UPDATE LINK +// =============================== +router.put("/:id", upload.single("icon"), async (req, res) => { + const { id } = req.params; + const { name, url, iconURL } = req.body; + + const link = await Link.findOne({ _id: id, owner: req.userId }); + if (!link) return res.status(404).json({ error: "Link non trovato" }); + + let originalBuffer = null; + + if (req.file) { + originalBuffer = req.file.buffer; + } else if (iconURL) { + originalBuffer = await downloadImageAsBuffer(iconURL); + } + + const update = { name, url }; + + if (originalBuffer) { + const processedIcon = await processIcon(originalBuffer.buffer, originalBuffer.mime); + update.icon = { + data: processedIcon, + mime: "image/webp", + size: processedIcon.length + }; + } + + const updated = await Link.findOneAndUpdate( + { _id: id, owner: req.userId }, + update, + { new: true } + ); + + res.json(updated); +}); + +// =============================== +// DELETE LINK +// =============================== +router.delete("/:id", async (req, res) => { + const link = await Link.findOneAndDelete({ + _id: req.params.id, + owner: req.userId + }); + + if (!link) return res.status(404).json({ error: "Link non trovato" }); + + res.json({ success: true }); +}); + +export default router; diff --git a/server/routes/metadata.js b/server/routes/metadata.js new file mode 100644 index 0000000..6fd61b3 --- /dev/null +++ b/server/routes/metadata.js @@ -0,0 +1,104 @@ +import express from "express"; +import axios from "axios"; +import * as cheerio from "cheerio"; +import { URL } from "url"; + +const router = express.Router(); + +// Normalizza URL relativi → assoluti +function normalize(base, relative) { + try { + return new URL(relative, base).href; + } catch { + return null; + } +} + +// Scarica HTML con fallback CORS +async function fetchHTML(url) { + try { + const res = await axios.get(url, { + timeout: 8000, + headers: { + "User-Agent": "Mozilla/5.0" + } + }); + return res.data; + } catch (err) { + return null; + } +} + +router.get("/", async (req, res) => { + const siteUrl = req.query.url; + if (!siteUrl) return res.json({ error: "Missing URL" }); + + const html = await fetchHTML(siteUrl); + if (!html) return res.json({ name: null, icon: null }); + + const $ = cheerio.load(html); + + // ----------------------------------------- + // 1. Trova il nome più corto + // ----------------------------------------- + let names = []; + + const title = $("title").text().trim(); + if (title) names.push(title); + + $('meta[name="application-name"]').each((i, el) => { + const v = $(el).attr("content"); + if (v) names.push(v.trim()); + }); + + $('meta[property="og:site_name"]').each((i, el) => { + const v = $(el).attr("content"); + if (v) names.push(v.trim()); + }); + + const shortestName = names.length + ? names.sort((a, b) => a.length - b.length)[0] + : null; + + // ----------------------------------------- + // 2. Trova l’icona più grande + // ----------------------------------------- + let icons = []; + + $('link[rel="icon"], link[rel="shortcut icon"], link[rel="apple-touch-icon"], link[rel="apple-touch-icon-precomposed"]').each((i, el) => { + const href = $(el).attr("href"); + if (!href) return; + + const sizeAttr = $(el).attr("sizes"); + let size = 0; + + if (sizeAttr && sizeAttr.includes("x")) { + const parts = sizeAttr.split("x"); + size = parseInt(parts[0]) || 0; + } + + icons.push({ + url: normalize(siteUrl, href), + size + }); + }); + + // fallback favicon + icons.push({ + url: normalize(siteUrl, "/favicon.ico"), + size: 16 + }); + + // Ordina per dimensione + icons = icons.filter(i => i.url); + icons.sort((a, b) => b.size - a.size); + + const bestIcon = icons.length ? icons[0].url : null; + + res.json({ + name: shortestName, + icon: bestIcon + }); +}); + +export default router; diff --git a/server/uploads/1767548820927-1000084863.jpg b/server/uploads/1767548820927-1000084863.jpg new file mode 100644 index 0000000000000000000000000000000000000000..2d04eaf73952dc5ee43bb50a7e16507bb7772767 GIT binary patch literal 88040 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 B{@nlo literal 0 HcmV?d00001 diff --git a/server/uploads/1767548868131.png b/server/uploads/1767548868131.png new file mode 100644 index 0000000000000000000000000000000000000000..a59308e2e7ef39c9aa77eb03d70fa1c02c738429 GIT binary patch literal 6518 zcmeHKOK4nG7``(#F-UJFcjmrkGEJv3HpTdY_(DMjK}3)WLN-!CT_}P(LpOp<2i&Sv zV^wq`U5FcTrMntXi3QPiAx0%w3w5EXO`1MJ$By4ObN`uh&zw7xPU>z34(FWzeBbx~ z_dn0Etdy0u#>OnvC2QZ1W$m>rt5k~mu4V0qZ69oa0MWFgvMktp{TwHEFqg}HGden& z6>KJxaU93}9QGH*W~yD+eK(hLYbdK2&nuYF^MX1H^j}l#t)}B-7r{FVM-yZCwFa6E z8)FyR8t!N6IQ+iPvEgCoHpG1Z@h+lF3I^@FA=&UR8sNOaaoF$5*qJ(-o2gW4HJwh^ zQ7%H~e&LUdjFe&fOSn=a*4tgz`w*oLZVhR=V%yGx!qaQp&OU(e_*3}VZ1w}>bXodn zKcREJ_Yu>?x<{!O{dQpPz7^eGHL>9B5VB~fxk%C=#=vb! zAwLg6{|L%5Vqa%rn>LQMfP+RO13V{7C}k9$r;Q)Z(0+fOH?wnMV#4XgA0HntPEAdX z_QGv--1m3g90cK8ST}3FADl0j%Qtl6`hK`d9O{K)v3N^2Y_~Cd!;R3WpfvWhtlLtl zG}4U++*QGXyNOcm#nJVcLwv)JqNCO`Gc&_FUhM<>uZm|IS|&!I&8rb1Xc)o}8S_1VQjH=IIsie{J(S z=K^QS+vHDAPusw)Ct$C_Z*_Kdb_*}ecr?rrxbx6W+7Ix_9Os`*@Qr;N&c{`+y@%XA zldMnQ`NQV%@OZsmZ@ew8-D{kI@A$&(BYzlU-!F#(P%rLH`%9PtL2hD6W<5dyFe!9UkxW zL*HTRe}ar7u8r%p_9O~u8s?e4&1V+RUg2)H#{7@Tx5ex57~)!p+nQ$;><72&SNQnG zXA^uZblDpl`Fwu2X!Kj-9?RidVt1ItLf?GPpx^l4CU&VY{&c^7g~vC9=xOzuyrmG| z5pAq-XX5*3MW^4I?=F)zeTruE#@Ntti2WYHu;zUM+pVVim-_{|-mAaSagOcLb>SPn zN};L^TUE#Ly+aJ&+|YRrXGP;bKF7;rFL#R?>G8VeX||C zx0m8Egg-&+6X5@j+dJ=b!}veoev0zFItHyJ)BB4tFekvDR`J)jP3?Hz=~w;ve({d~ zCx-AewN+n9?Pxt}bFrnIcf2*3KjysGck8i4>!Av6$G+I=oREuBO`31rr>P(1g6D(r zj7o?F|5bUWbf0UJza$&?6VFTN;=bUW6)s2nFuFsVcZr;-Njd}jAOnL83^E`Y_zzV~ B;@1EG literal 0 HcmV?d00001