Index: nv.example
===================================================================
--- .env.example	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,20 +1,0 @@
-PG_DB_HOST=your_postgres_host
-PG_DB_PORT=your_postgres_port
-PG_DB_NAME=your_postgres_db_name
-PG_DB_USER=your_postgres_user
-PG_DB_PASSWORD=your_postgres_password
-
-POSTGRES_DB=your_postgres_db_name
-POSTGRES_USER=your_postgres_user
-POSTGRES_PASSWORD=your_postgres_password
-
-MAIL_HOST=your_mail_host
-MAIL_PORT=your_mail_port
-MAIL_USERNAME=your_mail_username
-MAIL_PASSWORD=your_mail_password
-
-CLIENT_ID=your_oauth_client_id
-CLIENT_SECRET=your_oauth_client_secret
-
-VITE_API_BASE_URL=your_vite_api_base_url
-VITE_GOOGLE_CLIENT_ID=your_vite_google_client_id
Index: itignore
===================================================================
--- .gitignore	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,3 +1,0 @@
-# Environment config
-.env
-.idea
Index: serveNGo-backend/.env.example
===================================================================
--- ReserveNGo-backend/.env.example	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,10 +1,0 @@
-H2_DB_USER=your_h2_db_user
-H2_DB_PASSWORD=your_h2_db_password
-
-MAIL_HOST=your_mail_host
-MAIL_PORT=your_mail_port
-MAIL_USERNAME=your_mail_username
-MAIL_PASSWORD=your_mail_password
-
-CLIENT_ID=your_oauth_client_id
-CLIENT_SECRET=your_oauth_client_secret
Index: serveNGo-backend/.gitattributes
===================================================================
--- ReserveNGo-backend/.gitattributes	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,2 +1,0 @@
-/mvnw text eol=lf
-*.cmd text eol=crlf
Index: serveNGo-backend/.gitignore
===================================================================
--- ReserveNGo-backend/.gitignore	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,37 +1,0 @@
-HELP.md
-target/
-!.mvn/wrapper/maven-wrapper.jar
-!**/src/main/**/target/
-!**/src/test/**/target/
-
-### STS ###
-.apt_generated
-.classpath
-.factorypath
-.project
-.settings
-.springBeans
-.sts4-cache
-
-### IntelliJ IDEA ###
-.idea
-*.iws
-*.iml
-*.ipr
-
-### NetBeans ###
-/nbproject/private/
-/nbbuild/
-/dist/
-/nbdist/
-/.nb-gradle/
-build/
-!**/src/main/**/build/
-!**/src/test/**/build/
-
-### VS Code ###
-.vscode/
-
-.env
-
-/ReserveNgo-backend/uploads/
Index: serveNGo-backend/.mvn/wrapper/maven-wrapper.properties
===================================================================
--- ReserveNGo-backend/.mvn/wrapper/maven-wrapper.properties	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,19 +1,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License.  You may obtain a copy of the License at
-#
-#   http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied.  See the License for the
-# specific language governing permissions and limitations
-# under the License.
-wrapperVersion=3.3.2
-distributionType=only-script
-distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.9/apache-maven-3.9.9-bin.zip
Index: serveNGo-backend/Dockerfile
===================================================================
--- ReserveNGo-backend/Dockerfile	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,13 +1,0 @@
-# Build stage
-FROM maven:3.9.6-eclipse-temurin-21 AS build
-WORKDIR /app
-COPY . .
-RUN mvn clean package -DskipTests
-
-# Run stage
-FROM eclipse-temurin:21-jdk-alpine
-WORKDIR /app
-COPY --from=build /app/target/*.jar app.jar
-EXPOSE 8080
-ENTRYPOINT ["java", "-jar", "app.jar"]
-
Index: serveNGo-backend/mvnw
===================================================================
--- ReserveNGo-backend/mvnw	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,259 +1,0 @@
-#!/bin/sh
-# ----------------------------------------------------------------------------
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License.  You may obtain a copy of the License at
-#
-#    http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied.  See the License for the
-# specific language governing permissions and limitations
-# under the License.
-# ----------------------------------------------------------------------------
-
-# ----------------------------------------------------------------------------
-# Apache Maven Wrapper startup batch script, version 3.3.2
-#
-# Optional ENV vars
-# -----------------
-#   JAVA_HOME - location of a JDK home dir, required when download maven via java source
-#   MVNW_REPOURL - repo url base for downloading maven distribution
-#   MVNW_USERNAME/MVNW_PASSWORD - user and password for downloading maven
-#   MVNW_VERBOSE - true: enable verbose log; debug: trace the mvnw script; others: silence the output
-# ----------------------------------------------------------------------------
-
-set -euf
-[ "${MVNW_VERBOSE-}" != debug ] || set -x
-
-# OS specific support.
-native_path() { printf %s\\n "$1"; }
-case "$(uname)" in
-CYGWIN* | MINGW*)
-  [ -z "${JAVA_HOME-}" ] || JAVA_HOME="$(cygpath --unix "$JAVA_HOME")"
-  native_path() { cygpath --path --windows "$1"; }
-  ;;
-esac
-
-# set JAVACMD and JAVACCMD
-set_java_home() {
-  # For Cygwin and MinGW, ensure paths are in Unix format before anything is touched
-  if [ -n "${JAVA_HOME-}" ]; then
-    if [ -x "$JAVA_HOME/jre/sh/java" ]; then
-      # IBM's JDK on AIX uses strange locations for the executables
-      JAVACMD="$JAVA_HOME/jre/sh/java"
-      JAVACCMD="$JAVA_HOME/jre/sh/javac"
-    else
-      JAVACMD="$JAVA_HOME/bin/java"
-      JAVACCMD="$JAVA_HOME/bin/javac"
-
-      if [ ! -x "$JAVACMD" ] || [ ! -x "$JAVACCMD" ]; then
-        echo "The JAVA_HOME environment variable is not defined correctly, so mvnw cannot run." >&2
-        echo "JAVA_HOME is set to \"$JAVA_HOME\", but \"\$JAVA_HOME/bin/java\" or \"\$JAVA_HOME/bin/javac\" does not exist." >&2
-        return 1
-      fi
-    fi
-  else
-    JAVACMD="$(
-      'set' +e
-      'unset' -f command 2>/dev/null
-      'command' -v java
-    )" || :
-    JAVACCMD="$(
-      'set' +e
-      'unset' -f command 2>/dev/null
-      'command' -v javac
-    )" || :
-
-    if [ ! -x "${JAVACMD-}" ] || [ ! -x "${JAVACCMD-}" ]; then
-      echo "The java/javac command does not exist in PATH nor is JAVA_HOME set, so mvnw cannot run." >&2
-      return 1
-    fi
-  fi
-}
-
-# hash string like Java String::hashCode
-hash_string() {
-  str="${1:-}" h=0
-  while [ -n "$str" ]; do
-    char="${str%"${str#?}"}"
-    h=$(((h * 31 + $(LC_CTYPE=C printf %d "'$char")) % 4294967296))
-    str="${str#?}"
-  done
-  printf %x\\n $h
-}
-
-verbose() { :; }
-[ "${MVNW_VERBOSE-}" != true ] || verbose() { printf %s\\n "${1-}"; }
-
-die() {
-  printf %s\\n "$1" >&2
-  exit 1
-}
-
-trim() {
-  # MWRAPPER-139:
-  #   Trims trailing and leading whitespace, carriage returns, tabs, and linefeeds.
-  #   Needed for removing poorly interpreted newline sequences when running in more
-  #   exotic environments such as mingw bash on Windows.
-  printf "%s" "${1}" | tr -d '[:space:]'
-}
-
-# parse distributionUrl and optional distributionSha256Sum, requires .mvn/wrapper/maven-wrapper.properties
-while IFS="=" read -r key value; do
-  case "${key-}" in
-  distributionUrl) distributionUrl=$(trim "${value-}") ;;
-  distributionSha256Sum) distributionSha256Sum=$(trim "${value-}") ;;
-  esac
-done <"${0%/*}/.mvn/wrapper/maven-wrapper.properties"
-[ -n "${distributionUrl-}" ] || die "cannot read distributionUrl property in ${0%/*}/.mvn/wrapper/maven-wrapper.properties"
-
-case "${distributionUrl##*/}" in
-maven-mvnd-*bin.*)
-  MVN_CMD=mvnd.sh _MVNW_REPO_PATTERN=/maven/mvnd/
-  case "${PROCESSOR_ARCHITECTURE-}${PROCESSOR_ARCHITEW6432-}:$(uname -a)" in
-  *AMD64:CYGWIN* | *AMD64:MINGW*) distributionPlatform=windows-amd64 ;;
-  :Darwin*x86_64) distributionPlatform=darwin-amd64 ;;
-  :Darwin*arm64) distributionPlatform=darwin-aarch64 ;;
-  :Linux*x86_64*) distributionPlatform=linux-amd64 ;;
-  *)
-    echo "Cannot detect native platform for mvnd on $(uname)-$(uname -m), use pure java version" >&2
-    distributionPlatform=linux-amd64
-    ;;
-  esac
-  distributionUrl="${distributionUrl%-bin.*}-$distributionPlatform.zip"
-  ;;
-maven-mvnd-*) MVN_CMD=mvnd.sh _MVNW_REPO_PATTERN=/maven/mvnd/ ;;
-*) MVN_CMD="mvn${0##*/mvnw}" _MVNW_REPO_PATTERN=/org/apache/maven/ ;;
-esac
-
-# apply MVNW_REPOURL and calculate MAVEN_HOME
-# maven home pattern: ~/.m2/wrapper/dists/{apache-maven-<version>,maven-mvnd-<version>-<platform>}/<hash>
-[ -z "${MVNW_REPOURL-}" ] || distributionUrl="$MVNW_REPOURL$_MVNW_REPO_PATTERN${distributionUrl#*"$_MVNW_REPO_PATTERN"}"
-distributionUrlName="${distributionUrl##*/}"
-distributionUrlNameMain="${distributionUrlName%.*}"
-distributionUrlNameMain="${distributionUrlNameMain%-bin}"
-MAVEN_USER_HOME="${MAVEN_USER_HOME:-${HOME}/.m2}"
-MAVEN_HOME="${MAVEN_USER_HOME}/wrapper/dists/${distributionUrlNameMain-}/$(hash_string "$distributionUrl")"
-
-exec_maven() {
-  unset MVNW_VERBOSE MVNW_USERNAME MVNW_PASSWORD MVNW_REPOURL || :
-  exec "$MAVEN_HOME/bin/$MVN_CMD" "$@" || die "cannot exec $MAVEN_HOME/bin/$MVN_CMD"
-}
-
-if [ -d "$MAVEN_HOME" ]; then
-  verbose "found existing MAVEN_HOME at $MAVEN_HOME"
-  exec_maven "$@"
-fi
-
-case "${distributionUrl-}" in
-*?-bin.zip | *?maven-mvnd-?*-?*.zip) ;;
-*) die "distributionUrl is not valid, must match *-bin.zip or maven-mvnd-*.zip, but found '${distributionUrl-}'" ;;
-esac
-
-# prepare tmp dir
-if TMP_DOWNLOAD_DIR="$(mktemp -d)" && [ -d "$TMP_DOWNLOAD_DIR" ]; then
-  clean() { rm -rf -- "$TMP_DOWNLOAD_DIR"; }
-  trap clean HUP INT TERM EXIT
-else
-  die "cannot create temp dir"
-fi
-
-mkdir -p -- "${MAVEN_HOME%/*}"
-
-# Download and Install Apache Maven
-verbose "Couldn't find MAVEN_HOME, downloading and installing it ..."
-verbose "Downloading from: $distributionUrl"
-verbose "Downloading to: $TMP_DOWNLOAD_DIR/$distributionUrlName"
-
-# select .zip or .tar.gz
-if ! command -v unzip >/dev/null; then
-  distributionUrl="${distributionUrl%.zip}.tar.gz"
-  distributionUrlName="${distributionUrl##*/}"
-fi
-
-# verbose opt
-__MVNW_QUIET_WGET=--quiet __MVNW_QUIET_CURL=--silent __MVNW_QUIET_UNZIP=-q __MVNW_QUIET_TAR=''
-[ "${MVNW_VERBOSE-}" != true ] || __MVNW_QUIET_WGET='' __MVNW_QUIET_CURL='' __MVNW_QUIET_UNZIP='' __MVNW_QUIET_TAR=v
-
-# normalize http auth
-case "${MVNW_PASSWORD:+has-password}" in
-'') MVNW_USERNAME='' MVNW_PASSWORD='' ;;
-has-password) [ -n "${MVNW_USERNAME-}" ] || MVNW_USERNAME='' MVNW_PASSWORD='' ;;
-esac
-
-if [ -z "${MVNW_USERNAME-}" ] && command -v wget >/dev/null; then
-  verbose "Found wget ... using wget"
-  wget ${__MVNW_QUIET_WGET:+"$__MVNW_QUIET_WGET"} "$distributionUrl" -O "$TMP_DOWNLOAD_DIR/$distributionUrlName" || die "wget: Failed to fetch $distributionUrl"
-elif [ -z "${MVNW_USERNAME-}" ] && command -v curl >/dev/null; then
-  verbose "Found curl ... using curl"
-  curl ${__MVNW_QUIET_CURL:+"$__MVNW_QUIET_CURL"} -f -L -o "$TMP_DOWNLOAD_DIR/$distributionUrlName" "$distributionUrl" || die "curl: Failed to fetch $distributionUrl"
-elif set_java_home; then
-  verbose "Falling back to use Java to download"
-  javaSource="$TMP_DOWNLOAD_DIR/Downloader.java"
-  targetZip="$TMP_DOWNLOAD_DIR/$distributionUrlName"
-  cat >"$javaSource" <<-END
-	public class Downloader extends java.net.Authenticator
-	{
-	  protected java.net.PasswordAuthentication getPasswordAuthentication()
-	  {
-	    return new java.net.PasswordAuthentication( System.getenv( "MVNW_USERNAME" ), System.getenv( "MVNW_PASSWORD" ).toCharArray() );
-	  }
-	  public static void main( String[] args ) throws Exception
-	  {
-	    setDefault( new Downloader() );
-	    java.nio.file.Files.copy( java.net.URI.create( args[0] ).toURL().openStream(), java.nio.file.Paths.get( args[1] ).toAbsolutePath().normalize() );
-	  }
-	}
-	END
-  # For Cygwin/MinGW, switch paths to Windows format before running javac and java
-  verbose " - Compiling Downloader.java ..."
-  "$(native_path "$JAVACCMD")" "$(native_path "$javaSource")" || die "Failed to compile Downloader.java"
-  verbose " - Running Downloader.java ..."
-  "$(native_path "$JAVACMD")" -cp "$(native_path "$TMP_DOWNLOAD_DIR")" Downloader "$distributionUrl" "$(native_path "$targetZip")"
-fi
-
-# If specified, validate the SHA-256 sum of the Maven distribution zip file
-if [ -n "${distributionSha256Sum-}" ]; then
-  distributionSha256Result=false
-  if [ "$MVN_CMD" = mvnd.sh ]; then
-    echo "Checksum validation is not supported for maven-mvnd." >&2
-    echo "Please disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." >&2
-    exit 1
-  elif command -v sha256sum >/dev/null; then
-    if echo "$distributionSha256Sum  $TMP_DOWNLOAD_DIR/$distributionUrlName" | sha256sum -c >/dev/null 2>&1; then
-      distributionSha256Result=true
-    fi
-  elif command -v shasum >/dev/null; then
-    if echo "$distributionSha256Sum  $TMP_DOWNLOAD_DIR/$distributionUrlName" | shasum -a 256 -c >/dev/null 2>&1; then
-      distributionSha256Result=true
-    fi
-  else
-    echo "Checksum validation was requested but neither 'sha256sum' or 'shasum' are available." >&2
-    echo "Please install either command, or disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." >&2
-    exit 1
-  fi
-  if [ $distributionSha256Result = false ]; then
-    echo "Error: Failed to validate Maven distribution SHA-256, your Maven distribution might be compromised." >&2
-    echo "If you updated your Maven version, you need to update the specified distributionSha256Sum property." >&2
-    exit 1
-  fi
-fi
-
-# unzip and move
-if command -v unzip >/dev/null; then
-  unzip ${__MVNW_QUIET_UNZIP:+"$__MVNW_QUIET_UNZIP"} "$TMP_DOWNLOAD_DIR/$distributionUrlName" -d "$TMP_DOWNLOAD_DIR" || die "failed to unzip"
-else
-  tar xzf${__MVNW_QUIET_TAR:+"$__MVNW_QUIET_TAR"} "$TMP_DOWNLOAD_DIR/$distributionUrlName" -C "$TMP_DOWNLOAD_DIR" || die "failed to untar"
-fi
-printf %s\\n "$distributionUrl" >"$TMP_DOWNLOAD_DIR/$distributionUrlNameMain/mvnw.url"
-mv -- "$TMP_DOWNLOAD_DIR/$distributionUrlNameMain" "$MAVEN_HOME" || [ -d "$MAVEN_HOME" ] || die "fail to move MAVEN_HOME"
-
-clean || :
-exec_maven "$@"
Index: serveNGo-backend/mvnw.cmd
===================================================================
--- ReserveNGo-backend/mvnw.cmd	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,149 +1,0 @@
-<# : batch portion
-@REM ----------------------------------------------------------------------------
-@REM Licensed to the Apache Software Foundation (ASF) under one
-@REM or more contributor license agreements.  See the NOTICE file
-@REM distributed with this work for additional information
-@REM regarding copyright ownership.  The ASF licenses this file
-@REM to you under the Apache License, Version 2.0 (the
-@REM "License"); you may not use this file except in compliance
-@REM with the License.  You may obtain a copy of the License at
-@REM
-@REM    http://www.apache.org/licenses/LICENSE-2.0
-@REM
-@REM Unless required by applicable law or agreed to in writing,
-@REM software distributed under the License is distributed on an
-@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-@REM KIND, either express or implied.  See the License for the
-@REM specific language governing permissions and limitations
-@REM under the License.
-@REM ----------------------------------------------------------------------------
-
-@REM ----------------------------------------------------------------------------
-@REM Apache Maven Wrapper startup batch script, version 3.3.2
-@REM
-@REM Optional ENV vars
-@REM   MVNW_REPOURL - repo url base for downloading maven distribution
-@REM   MVNW_USERNAME/MVNW_PASSWORD - user and password for downloading maven
-@REM   MVNW_VERBOSE - true: enable verbose log; others: silence the output
-@REM ----------------------------------------------------------------------------
-
-@IF "%__MVNW_ARG0_NAME__%"=="" (SET __MVNW_ARG0_NAME__=%~nx0)
-@SET __MVNW_CMD__=
-@SET __MVNW_ERROR__=
-@SET __MVNW_PSMODULEP_SAVE=%PSModulePath%
-@SET PSModulePath=
-@FOR /F "usebackq tokens=1* delims==" %%A IN (`powershell -noprofile "& {$scriptDir='%~dp0'; $script='%__MVNW_ARG0_NAME__%'; icm -ScriptBlock ([Scriptblock]::Create((Get-Content -Raw '%~f0'))) -NoNewScope}"`) DO @(
-  IF "%%A"=="MVN_CMD" (set __MVNW_CMD__=%%B) ELSE IF "%%B"=="" (echo %%A) ELSE (echo %%A=%%B)
-)
-@SET PSModulePath=%__MVNW_PSMODULEP_SAVE%
-@SET __MVNW_PSMODULEP_SAVE=
-@SET __MVNW_ARG0_NAME__=
-@SET MVNW_USERNAME=
-@SET MVNW_PASSWORD=
-@IF NOT "%__MVNW_CMD__%"=="" (%__MVNW_CMD__% %*)
-@echo Cannot start maven from wrapper >&2 && exit /b 1
-@GOTO :EOF
-: end batch / begin powershell #>
-
-$ErrorActionPreference = "Stop"
-if ($env:MVNW_VERBOSE -eq "true") {
-  $VerbosePreference = "Continue"
-}
-
-# calculate distributionUrl, requires .mvn/wrapper/maven-wrapper.properties
-$distributionUrl = (Get-Content -Raw "$scriptDir/.mvn/wrapper/maven-wrapper.properties" | ConvertFrom-StringData).distributionUrl
-if (!$distributionUrl) {
-  Write-Error "cannot read distributionUrl property in $scriptDir/.mvn/wrapper/maven-wrapper.properties"
-}
-
-switch -wildcard -casesensitive ( $($distributionUrl -replace '^.*/','') ) {
-  "maven-mvnd-*" {
-    $USE_MVND = $true
-    $distributionUrl = $distributionUrl -replace '-bin\.[^.]*$',"-windows-amd64.zip"
-    $MVN_CMD = "mvnd.cmd"
-    break
-  }
-  default {
-    $USE_MVND = $false
-    $MVN_CMD = $script -replace '^mvnw','mvn'
-    break
-  }
-}
-
-# apply MVNW_REPOURL and calculate MAVEN_HOME
-# maven home pattern: ~/.m2/wrapper/dists/{apache-maven-<version>,maven-mvnd-<version>-<platform>}/<hash>
-if ($env:MVNW_REPOURL) {
-  $MVNW_REPO_PATTERN = if ($USE_MVND) { "/org/apache/maven/" } else { "/maven/mvnd/" }
-  $distributionUrl = "$env:MVNW_REPOURL$MVNW_REPO_PATTERN$($distributionUrl -replace '^.*'+$MVNW_REPO_PATTERN,'')"
-}
-$distributionUrlName = $distributionUrl -replace '^.*/',''
-$distributionUrlNameMain = $distributionUrlName -replace '\.[^.]*$','' -replace '-bin$',''
-$MAVEN_HOME_PARENT = "$HOME/.m2/wrapper/dists/$distributionUrlNameMain"
-if ($env:MAVEN_USER_HOME) {
-  $MAVEN_HOME_PARENT = "$env:MAVEN_USER_HOME/wrapper/dists/$distributionUrlNameMain"
-}
-$MAVEN_HOME_NAME = ([System.Security.Cryptography.MD5]::Create().ComputeHash([byte[]][char[]]$distributionUrl) | ForEach-Object {$_.ToString("x2")}) -join ''
-$MAVEN_HOME = "$MAVEN_HOME_PARENT/$MAVEN_HOME_NAME"
-
-if (Test-Path -Path "$MAVEN_HOME" -PathType Container) {
-  Write-Verbose "found existing MAVEN_HOME at $MAVEN_HOME"
-  Write-Output "MVN_CMD=$MAVEN_HOME/bin/$MVN_CMD"
-  exit $?
-}
-
-if (! $distributionUrlNameMain -or ($distributionUrlName -eq $distributionUrlNameMain)) {
-  Write-Error "distributionUrl is not valid, must end with *-bin.zip, but found $distributionUrl"
-}
-
-# prepare tmp dir
-$TMP_DOWNLOAD_DIR_HOLDER = New-TemporaryFile
-$TMP_DOWNLOAD_DIR = New-Item -Itemtype Directory -Path "$TMP_DOWNLOAD_DIR_HOLDER.dir"
-$TMP_DOWNLOAD_DIR_HOLDER.Delete() | Out-Null
-trap {
-  if ($TMP_DOWNLOAD_DIR.Exists) {
-    try { Remove-Item $TMP_DOWNLOAD_DIR -Recurse -Force | Out-Null }
-    catch { Write-Warning "Cannot remove $TMP_DOWNLOAD_DIR" }
-  }
-}
-
-New-Item -Itemtype Directory -Path "$MAVEN_HOME_PARENT" -Force | Out-Null
-
-# Download and Install Apache Maven
-Write-Verbose "Couldn't find MAVEN_HOME, downloading and installing it ..."
-Write-Verbose "Downloading from: $distributionUrl"
-Write-Verbose "Downloading to: $TMP_DOWNLOAD_DIR/$distributionUrlName"
-
-$webclient = New-Object System.Net.WebClient
-if ($env:MVNW_USERNAME -and $env:MVNW_PASSWORD) {
-  $webclient.Credentials = New-Object System.Net.NetworkCredential($env:MVNW_USERNAME, $env:MVNW_PASSWORD)
-}
-[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
-$webclient.DownloadFile($distributionUrl, "$TMP_DOWNLOAD_DIR/$distributionUrlName") | Out-Null
-
-# If specified, validate the SHA-256 sum of the Maven distribution zip file
-$distributionSha256Sum = (Get-Content -Raw "$scriptDir/.mvn/wrapper/maven-wrapper.properties" | ConvertFrom-StringData).distributionSha256Sum
-if ($distributionSha256Sum) {
-  if ($USE_MVND) {
-    Write-Error "Checksum validation is not supported for maven-mvnd. `nPlease disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties."
-  }
-  Import-Module $PSHOME\Modules\Microsoft.PowerShell.Utility -Function Get-FileHash
-  if ((Get-FileHash "$TMP_DOWNLOAD_DIR/$distributionUrlName" -Algorithm SHA256).Hash.ToLower() -ne $distributionSha256Sum) {
-    Write-Error "Error: Failed to validate Maven distribution SHA-256, your Maven distribution might be compromised. If you updated your Maven version, you need to update the specified distributionSha256Sum property."
-  }
-}
-
-# unzip and move
-Expand-Archive "$TMP_DOWNLOAD_DIR/$distributionUrlName" -DestinationPath "$TMP_DOWNLOAD_DIR" | Out-Null
-Rename-Item -Path "$TMP_DOWNLOAD_DIR/$distributionUrlNameMain" -NewName $MAVEN_HOME_NAME | Out-Null
-try {
-  Move-Item -Path "$TMP_DOWNLOAD_DIR/$MAVEN_HOME_NAME" -Destination $MAVEN_HOME_PARENT | Out-Null
-} catch {
-  if (! (Test-Path -Path "$MAVEN_HOME" -PathType Container)) {
-    Write-Error "fail to move MAVEN_HOME"
-  }
-} finally {
-  try { Remove-Item $TMP_DOWNLOAD_DIR -Recurse -Force | Out-Null }
-  catch { Write-Warning "Cannot remove $TMP_DOWNLOAD_DIR" }
-}
-
-Write-Output "MVN_CMD=$MAVEN_HOME/bin/$MVN_CMD"
Index: serveNGo-backend/pom.xml
===================================================================
--- ReserveNGo-backend/pom.xml	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,145 +1,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
-    <modelVersion>4.0.0</modelVersion>
-    <parent>
-        <groupId>org.springframework.boot</groupId>
-        <artifactId>spring-boot-starter-parent</artifactId>
-        <version>3.4.3</version>
-        <relativePath/>
-    </parent>
-    <groupId>mk.ukim.finki.it</groupId>
-    <artifactId>ReserveNGo</artifactId>
-    <version>0.0.1-SNAPSHOT</version>
-    <name>ReserveNGo</name>
-    <description>ReserveNGo</description>
-    <url/>
-    <licenses>
-        <license/>
-    </licenses>
-    <developers>
-        <developer/>
-    </developers>
-    <scm>
-        <connection/>
-        <developerConnection/>
-        <tag/>
-        <url/>
-    </scm>
-    <properties>
-        <java.version>21</java.version>
-    </properties>
-    <dependencies>
-        <dependency>
-            <groupId>org.projectlombok</groupId>
-            <artifactId>lombok</artifactId>
-            <version>1.18.36</version>
-            <scope>provided</scope>
-        </dependency>
-        <dependency>
-            <groupId>org.springframework.boot</groupId>
-            <artifactId>spring-boot-starter-web</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>org.springframework.boot</groupId>
-            <artifactId>spring-boot-starter-data-jpa</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>org.springframework.boot</groupId>
-            <artifactId>spring-boot-starter-security</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>org.postgresql</groupId>
-            <artifactId>postgresql</artifactId>
-            <scope>runtime</scope>
-        </dependency>
-        <dependency>
-            <groupId>io.jsonwebtoken</groupId>
-            <artifactId>jjwt-api</artifactId>
-            <version>0.11.5</version>
-        </dependency>
-        <dependency>
-            <groupId>io.jsonwebtoken</groupId>
-            <artifactId>jjwt-impl</artifactId>
-            <version>0.11.5</version>
-        </dependency>
-        <dependency>
-            <groupId>io.jsonwebtoken</groupId>
-            <artifactId>jjwt-jackson</artifactId>
-            <version>0.11.5</version>
-        </dependency>
-        <dependency>
-            <groupId>com.h2database</groupId>
-            <artifactId>h2</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>org.springframework.boot</groupId>
-            <artifactId>spring-boot-starter-mail</artifactId>
-            <version>3.4.3</version>
-        </dependency>
-        <dependency>
-            <groupId>org.springframework.boot</groupId>
-            <artifactId>spring-boot-starter-test</artifactId>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
-            <groupId>org.springframework.boot</groupId>
-            <artifactId>spring-boot-starter-oauth2-client</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>com.google.api-client</groupId>
-            <artifactId>google-api-client</artifactId>
-            <version>2.7.2</version>
-        </dependency>
-        <dependency>
-            <groupId>com.google.http-client</groupId>
-            <artifactId>google-http-client</artifactId>
-            <version>2.0.2</version>
-        </dependency>
-        <dependency>
-            <groupId>com.google.http-client</groupId>
-            <artifactId>google-http-client-gson</artifactId>
-            <version>2.0.2</version>
-        </dependency>
-        <dependency>
-            <groupId>io.github.cdimascio</groupId>
-            <artifactId>dotenv-java</artifactId>
-            <version>3.2.0</version>
-        </dependency>
-        <dependency>
-            <groupId>com.twilio.sdk</groupId>
-            <artifactId>twilio</artifactId>
-            <version>10.9.2</version>
-        </dependency>
-    </dependencies>
-    <build>
-        <plugins>
-            <plugin>
-                <groupId>org.apache.maven.plugins</groupId>
-                <artifactId>maven-compiler-plugin</artifactId>
-                <configuration>
-                    <annotationProcessorPaths>
-                        <path>
-                            <groupId>org.projectlombok</groupId>
-                            <artifactId>lombok</artifactId>
-                            <version>1.18.36</version>
-                        </path>
-                    </annotationProcessorPaths>
-                </configuration>
-            </plugin>
-            <plugin>
-                <groupId>org.springframework.boot</groupId>
-                <artifactId>spring-boot-maven-plugin</artifactId>
-                <configuration>
-                    <excludes>
-                        <exclude>
-                            <groupId>org.projectlombok</groupId>
-                            <artifactId>lombok</artifactId>
-                        </exclude>
-                    </excludes>
-                </configuration>
-            </plugin>
-        </plugins>
-    </build>
-
-</project>
Index: serveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/ReserveNGoApplication.java
===================================================================
--- ReserveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/ReserveNGoApplication.java	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,25 +1,0 @@
-package mk.ukim.finki.it.reservengo;
-
-import io.github.cdimascio.dotenv.Dotenv;
-import org.springframework.boot.SpringApplication;
-import org.springframework.boot.autoconfigure.SpringBootApplication;
-import org.springframework.data.jpa.repository.config.EnableJpaAuditing;
-import org.springframework.scheduling.annotation.EnableScheduling;
-
-@EnableJpaAuditing
-@EnableScheduling
-@SpringBootApplication
-public class ReserveNGoApplication {
-    public static void main(String[] args) {
-        Dotenv dotenv = Dotenv.configure()
-                .directory("./")
-                .ignoreIfMissing()
-                .load();
-
-        dotenv.entries().forEach(e ->
-                System.setProperty(e.getKey(), e.getValue())
-        );
-
-        SpringApplication.run(ReserveNGoApplication.class, args);
-    }
-}
Index: serveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/bootstrap/DataHolder.java
===================================================================
--- ReserveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/bootstrap/DataHolder.java	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,158 +1,0 @@
-package mk.ukim.finki.it.reservengo.bootstrap;
-
-import jakarta.annotation.PostConstruct;
-import mk.ukim.finki.it.reservengo.model.domain.*;
-import mk.ukim.finki.it.reservengo.model.enumerations.*;
-import mk.ukim.finki.it.reservengo.repository.*;
-import org.springframework.context.annotation.Profile;
-import org.springframework.security.crypto.password.PasswordEncoder;
-import org.springframework.stereotype.Component;
-
-import java.time.DayOfWeek;
-import java.time.LocalDateTime;
-import java.time.LocalTime;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-@Component
-@Profile("dev")
-public class DataHolder {
-    public static Admin admin = null;
-    public static List<Customer> customers = new ArrayList<>();
-    public static List<LocalWorker> workers = new ArrayList<>();
-    public static List<LocalManager> managers = new ArrayList<>();
-    public static List<Local> locals = new ArrayList<>();
-    public static List<Event> events = new ArrayList<>();
-
-
-    private final AdminRepository adminRepository;
-    private final CustomerRepository customerRepository;
-    private final LocalManagerRepository localManagerRepository;
-    private final LocalRepository localRepository;
-    private final LocalWorkerRepository localWorkerRepository;
-    private final PasswordEncoder passwordEncoder;
-    private final EventRepository eventRepository;
-
-    public DataHolder(AdminRepository adminRepository, CustomerRepository customerRepository, LocalManagerRepository localManagerRepository, LocalRepository localRepository, LocalWorkerRepository localWorkerRepository, PasswordEncoder passwordEncoder, EventRepository eventRepository) {
-        this.adminRepository = adminRepository;
-        this.customerRepository = customerRepository;
-        this.localManagerRepository = localManagerRepository;
-        this.localRepository = localRepository;
-        this.localWorkerRepository = localWorkerRepository;
-        this.passwordEncoder = passwordEncoder;
-        this.eventRepository = eventRepository;
-    }
-
-    @PostConstruct
-    public void init() {
-        // Admin
-        admin = new Admin("admin", passwordEncoder.encode("admin"), Role.ROLE_ADMIN);
-        adminRepository.save(admin);
-
-        // Customers
-        for (int i = 1; i <= 3; i++) {
-            Customer customer = new Customer(
-                    "FirstName " + i,
-                    "LastName " + i,
-                    "customer" + i + "@example.com",
-                    passwordEncoder.encode("password" + i),
-                    "Phone" + i,
-                    Role.ROLE_CUSTOMER,
-                    Provider.LOCAL,
-                    null
-            );
-            customer.setEnabled(true);
-            customers.add(customer);
-        }
-        customerRepository.saveAll(customers);
-
-        //Local worker
-        for (int i = 1; i <= 3; i++) {
-            LocalWorker localWorker = new LocalWorker(
-                    "FirstName" + i,
-                    "LastName" + i,
-                    "worker" + i + "@example.com",
-                    passwordEncoder.encode("password" + i),
-                    "Phone" + i,
-                    Role.ROLE_LOCAL_WORKER,
-                    Provider.LOCAL,
-                    null
-            );
-            localWorker.setEnabled(true);
-            workers.add(localWorker);
-        }
-        localWorkerRepository.saveAll(workers);
-
-        //Local manager
-        for (int i = 1; i <= 3; i++) {
-            LocalManager manager = new LocalManager(
-                    "FirstName" + i,
-                    "LastName" + i,
-                    "manager" + i + "@example.com",
-                    passwordEncoder.encode("password" + i),
-                    "Phone" + i,
-                    Role.ROLE_LOCAL_MANAGER,
-                    Provider.LOCAL,
-                    null
-            );
-            manager.setEnabled(true);
-            managers.add(manager);
-        }
-        localManagerRepository.saveAll(managers);
-
-        //Local
-        List<ProvidedService> serviceList = new ArrayList<>(Arrays.asList(ProvidedService.values()));
-        for (int i = 1; i <= 3; i++) {
-            Local local = new Local(
-                    "Name" + i,
-                    "Description" + i,
-                    "Address" + i,
-                    new ArrayList<>(Arrays.asList(
-                            new WorkingHour(DayOfWeek.MONDAY, LocalTime.of(9, 0), LocalTime.of(17, 0)),
-                            new WorkingHour(DayOfWeek.TUESDAY, LocalTime.of(9, 0), LocalTime.of(17, 0)),
-                            new WorkingHour(DayOfWeek.WEDNESDAY, LocalTime.of(9, 0), LocalTime.of(17, 0)),
-                            new WorkingHour(DayOfWeek.SATURDAY, LocalTime.of(9, 0), LocalTime.of(21, 0))
-                    )),
-                    serviceList,
-                    null,
-                    null,
-                    null,
-                    null,
-                    "MenuLink" + i,
-                    null,
-                    null,
-                    LocalType.RESTAURANT
-            );
-
-            locals.add(local);
-        }
-        localRepository.saveAll(locals);
-
-        for (Local local : locals) {
-            // Active event
-            Event activeEvent = new Event(
-                    "Upcoming Event for " + local.getName(),
-                    "Description for active event",
-                    EventType.DJ_NIGHT,
-                    LocalDateTime.now().plusDays(7), // Future date
-                    LocalDateTime.now().plusDays(8),
-                    local
-            );
-
-            // Finished event
-            Event finishedEvent = new Event(
-                    "Finished Event for " + local.getName(),
-                    "Description for finished event",
-                    EventType.COOKING_WORKSHOP,
-                    LocalDateTime.now().minusDays(7), // Past date
-                    LocalDateTime.now().minusDays(6),
-                    local
-            );
-
-            events.add(activeEvent);
-            events.add(finishedEvent);
-        }
-        eventRepository.saveAll(events);
-    }
-}
Index: serveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/config/ApplicationConfig.java
===================================================================
--- ReserveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/config/ApplicationConfig.java	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,59 +1,0 @@
-package mk.ukim.finki.it.reservengo.config;
-
-import com.google.api.client.googleapis.auth.oauth2.GoogleIdTokenVerifier;
-import com.google.api.client.http.javanet.NetHttpTransport;
-import com.google.api.client.json.gson.GsonFactory;
-import mk.ukim.finki.it.reservengo.model.exceptions.EmailNotFoundException;
-import mk.ukim.finki.it.reservengo.repository.UserRepository;
-import org.springframework.beans.factory.annotation.Value;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.security.authentication.AuthenticationManager;
-import org.springframework.security.authentication.AuthenticationProvider;
-import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
-import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration;
-import org.springframework.security.core.userdetails.UserDetailsService;
-import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
-import org.springframework.security.crypto.password.PasswordEncoder;
-
-import java.util.Collections;
-
-@Configuration
-public class ApplicationConfig {
-
-    private final UserRepository userRepository;
-
-    public ApplicationConfig(UserRepository userRepository) {
-        this.userRepository = userRepository;
-    }
-
-    @Bean
-    public PasswordEncoder passwordEncoder() {
-        return new BCryptPasswordEncoder(10);
-    }
-
-    @Bean
-    public UserDetailsService userDetailsService() {
-        return username -> this.userRepository.findByEmail(username).orElseThrow(() -> new EmailNotFoundException(username));
-    }
-
-    @Bean
-    public AuthenticationProvider authenticationProvider() {
-        DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider();
-        authProvider.setUserDetailsService(userDetailsService());
-        authProvider.setPasswordEncoder(passwordEncoder());
-        return authProvider;
-    }
-
-    @Bean
-    public AuthenticationManager authenticationManager(AuthenticationConfiguration config) throws Exception {
-        return config.getAuthenticationManager();
-    }
-
-    @Bean
-    public GoogleIdTokenVerifier googleIdTokenVerifier(@Value("${spring.security.oauth2.client.registration.google.client-id}") String clientId) {
-        return new GoogleIdTokenVerifier.Builder(new NetHttpTransport(), new GsonFactory())
-                .setAudience(Collections.singletonList(clientId))
-                .build();
-    }
-}
Index: serveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/config/WebSecurityConfig.java
===================================================================
--- ReserveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/config/WebSecurityConfig.java	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,100 +1,0 @@
-package mk.ukim.finki.it.reservengo.config;
-
-import mk.ukim.finki.it.reservengo.config.filter.InviteFilter;
-import mk.ukim.finki.it.reservengo.config.filter.JWTAuthenticationFilter;
-import mk.ukim.finki.it.reservengo.config.filter.UserActivityFilter;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.http.HttpMethod;
-import org.springframework.lang.NonNull;
-import org.springframework.security.authentication.AuthenticationProvider;
-import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
-import org.springframework.security.config.annotation.web.builders.HttpSecurity;
-import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
-import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
-import org.springframework.security.config.annotation.web.configurers.HeadersConfigurer;
-import org.springframework.security.config.http.SessionCreationPolicy;
-import org.springframework.security.web.SecurityFilterChain;
-import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
-import org.springframework.web.servlet.config.annotation.CorsRegistry;
-import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
-import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
-
-@Configuration
-@EnableWebSecurity
-@EnableMethodSecurity
-public class WebSecurityConfig {
-
-    private final JWTAuthenticationFilter jwtAuthFilter;
-    private final AuthenticationProvider authenticationProvider;
-    private final UserActivityFilter userActivityFilter;
-    private final InviteFilter inviteFilter;
-
-    public WebSecurityConfig(JWTAuthenticationFilter jwtAuthFilter, AuthenticationProvider authenticationProvider, UserActivityFilter userActivityFilter, InviteFilter inviteFilter) {
-        this.jwtAuthFilter = jwtAuthFilter;
-        this.authenticationProvider = authenticationProvider;
-        this.userActivityFilter = userActivityFilter;
-        this.inviteFilter = inviteFilter;
-    }
-
-    @Bean
-    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
-
-        http.csrf(AbstractHttpConfigurer::disable)
-                .cors(cors -> cors.configure(http))
-                .headers((headers) -> headers
-                        .frameOptions(HeadersConfigurer.FrameOptionsConfig::sameOrigin))
-                .authorizeHttpRequests((requests) -> requests
-                        .requestMatchers(HttpMethod.OPTIONS, "/**").permitAll()
-                        .requestMatchers(
-                                "/api/auth/**",
-                                "/h2/**",
-                                "/favicon.ico",
-                                "/api/locals/**",
-                                "/api/events/**",
-                                "/uploads/**")
-                        .permitAll()
-                        .requestMatchers("/api/user/**").authenticated()
-                        .requestMatchers("/api/customer/**").hasRole("CUSTOMER")
-                        .requestMatchers("/api/local-manager/**").hasRole("LOCAL_MANAGER")
-                        .requestMatchers("/api/local-worker/**").hasRole("LOCAL_WORKER")
-                        .requestMatchers("/api/admin/**").hasRole("ADMIN")
-                        .anyRequest()
-                        .authenticated()
-                )
-                .sessionManagement(manager -> manager
-                        .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
-                )
-                .authenticationProvider(authenticationProvider)
-                .addFilterBefore(jwtAuthFilter, UsernamePasswordAuthenticationFilter.class)
-                .addFilterAfter(userActivityFilter, JWTAuthenticationFilter.class)
-                .addFilterBefore(inviteFilter, JWTAuthenticationFilter.class);
-
-        return http.build();
-    }
-
-    @Bean
-    public WebMvcConfigurer corsConfigurer() {
-        return new WebMvcConfigurer() {
-            @Override
-            public void addCorsMappings(@NonNull CorsRegistry registry) {
-                registry.addMapping("/api/**")
-                        .allowedOrigins("http://localhost:5173")
-                        .allowedMethods("*")
-                        .allowedHeaders("*")
-                        .allowCredentials(true);
-
-                registry.addMapping("/uploads/**")
-                        .allowedOrigins("http://localhost:5173")
-                        .allowedMethods("*")
-                        .allowedHeaders("*");
-            }
-
-            @Override
-            public void addResourceHandlers(@NonNull ResourceHandlerRegistry registry) {
-                registry.addResourceHandler("/uploads/**")
-                        .addResourceLocations("file:uploads/");
-            }
-        };
-    }
-}
Index: serveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/config/filter/InviteFilter.java
===================================================================
--- ReserveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/config/filter/InviteFilter.java	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,62 +1,0 @@
-package mk.ukim.finki.it.reservengo.config.filter;
-
-import jakarta.servlet.FilterChain;
-import jakarta.servlet.ServletException;
-import jakarta.servlet.http.HttpServletRequest;
-import jakarta.servlet.http.HttpServletResponse;
-import lombok.NonNull;
-import mk.ukim.finki.it.reservengo.constants.JWTConstants;
-import mk.ukim.finki.it.reservengo.service.intf.JWTService;
-import org.springframework.stereotype.Component;
-import org.springframework.web.filter.OncePerRequestFilter;
-
-import java.io.IOException;
-
-@Component
-public class InviteFilter extends OncePerRequestFilter {
-    private final JWTService jwtService;
-
-    public InviteFilter(JWTService jwtService) {
-        this.jwtService = jwtService;
-    }
-
-    @Override
-    protected void doFilterInternal(@NonNull HttpServletRequest request,
-                                    @NonNull HttpServletResponse response,
-                                    @NonNull FilterChain filterChain) throws ServletException, IOException {
-        String token = request.getHeader(JWTConstants.INVITE_TOKEN_HEADER);
-        String path = request.getRequestURI();
-
-        if (path.contains("/register/local-manager") || path.contains("/register/local-worker") || path.contains("/register/invite/check")) {
-
-            if (request.getMethod().equals("OPTIONS")) {
-                filterChain.doFilter(request, response);
-                return;
-            }
-
-            if (token == null || token.isEmpty()) {
-                response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
-                return;
-            }
-
-            if (jwtService.isTokenExpired(token)) {
-                response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
-                return;
-            }
-
-            String role = jwtService.extractAllClaims(token).get("role", String.class);
-
-            if (path.contains("/local-manager") && !role.equals("ROLE_LOCAL_MANAGER")) {
-                response.setStatus(HttpServletResponse.SC_FORBIDDEN);
-                return;
-            }
-
-            if (path.contains("/local-worker") && !role.equals("ROLE_LOCAL_WORKER")) {
-                response.setStatus(HttpServletResponse.SC_FORBIDDEN);
-                return;
-            }
-        }
-
-        filterChain.doFilter(request, response);
-    }
-}
Index: serveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/config/filter/JWTAuthenticationFilter.java
===================================================================
--- ReserveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/config/filter/JWTAuthenticationFilter.java	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,57 +1,0 @@
-package mk.ukim.finki.it.reservengo.config.filter;
-
-import jakarta.servlet.FilterChain;
-import jakarta.servlet.ServletException;
-import jakarta.servlet.http.HttpServletRequest;
-import jakarta.servlet.http.HttpServletResponse;
-import lombok.NonNull;
-import mk.ukim.finki.it.reservengo.constants.JWTConstants;
-import mk.ukim.finki.it.reservengo.service.intf.JWTService;
-import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
-import org.springframework.security.core.context.SecurityContextHolder;
-import org.springframework.security.core.userdetails.UserDetails;
-import org.springframework.security.core.userdetails.UserDetailsService;
-import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
-import org.springframework.stereotype.Component;
-import org.springframework.web.filter.OncePerRequestFilter;
-
-import java.io.IOException;
-
-@Component
-public class JWTAuthenticationFilter extends OncePerRequestFilter {
-
-    private final JWTService jwtService;
-    private final UserDetailsService userDetailsService;
-
-    public JWTAuthenticationFilter(JWTService jwtService, UserDetailsService userDetailsService) {
-        this.jwtService = jwtService;
-        this.userDetailsService = userDetailsService;
-    }
-
-    @Override
-    protected void doFilterInternal(@NonNull HttpServletRequest request,
-                                    @NonNull HttpServletResponse response,
-                                    @NonNull FilterChain filterChain) throws ServletException, IOException {
-        final String authHeader = request.getHeader(JWTConstants.BEARER_TOKEN_HEADER);
-        final String jwt;
-        final String userEmail;
-
-        if (authHeader == null || !authHeader.startsWith(JWTConstants.TOKEN_PREFIX)) {
-            filterChain.doFilter(request, response);
-            return;
-        }
-
-        jwt = authHeader.substring(JWTConstants.TOKEN_PREFIX.length());
-        userEmail = jwtService.extractUsername(jwt);
-
-        if (userEmail != null && SecurityContextHolder.getContext().getAuthentication() == null) {
-            UserDetails userDetails = userDetailsService.loadUserByUsername(userEmail);
-            if (jwtService.isTokenValid(jwt, userDetails) && userDetails.isEnabled()) {
-                UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
-                authenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
-                SecurityContextHolder.getContext().setAuthentication(authenticationToken);
-            }
-        }
-        filterChain.doFilter(request, response);
-    }
-}
Index: serveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/config/filter/UserActivityFilter.java
===================================================================
--- ReserveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/config/filter/UserActivityFilter.java	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,38 +1,0 @@
-package mk.ukim.finki.it.reservengo.config.filter;
-
-import jakarta.servlet.FilterChain;
-import jakarta.servlet.ServletException;
-import jakarta.servlet.http.HttpServletRequest;
-import jakarta.servlet.http.HttpServletResponse;
-import lombok.NonNull;
-import mk.ukim.finki.it.reservengo.model.domain.User;
-import mk.ukim.finki.it.reservengo.service.intf.UserService;
-import org.springframework.security.core.Authentication;
-import org.springframework.security.core.context.SecurityContextHolder;
-import org.springframework.stereotype.Component;
-import org.springframework.web.filter.OncePerRequestFilter;
-
-import java.io.IOException;
-
-@Component
-public class UserActivityFilter extends OncePerRequestFilter {
-    private final UserService userService;
-
-    public UserActivityFilter(UserService userService) {
-        this.userService = userService;
-    }
-
-    @Override
-    protected void doFilterInternal(@NonNull HttpServletRequest request,
-                                    @NonNull HttpServletResponse response,
-                                    @NonNull FilterChain filterChain) throws ServletException, IOException {
-        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
-
-        if (authentication != null && authentication.getPrincipal() instanceof User user) {
-            userService.updateUserActivity(user.getId());
-        }
-
-        filterChain.doFilter(request, response);
-    }
-}
-
Index: serveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/config/listeners/Auditable.java
===================================================================
--- ReserveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/config/listeners/Auditable.java	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,25 +1,0 @@
-package mk.ukim.finki.it.reservengo.config.listeners;
-
-import jakarta.persistence.Column;
-import jakarta.persistence.EntityListeners;
-import jakarta.persistence.MappedSuperclass;
-import lombok.Data;
-import org.springframework.data.annotation.CreatedDate;
-import org.springframework.data.annotation.LastModifiedDate;
-import org.springframework.data.jpa.domain.support.AuditingEntityListener;
-
-import java.time.LocalDateTime;
-
-@MappedSuperclass
-@EntityListeners(AuditingEntityListener.class)
-@Data
-public abstract class Auditable {
-
-    @CreatedDate
-    @Column(nullable = false, updatable = false)
-    private LocalDateTime createdAt;
-
-    @LastModifiedDate
-    @Column(nullable = false)
-    private LocalDateTime modifiedAt;
-}
Index: serveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/constants/JWTConstants.java
===================================================================
--- ReserveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/constants/JWTConstants.java	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,9 +1,0 @@
-package mk.ukim.finki.it.reservengo.constants;
-
-public class JWTConstants {
-    public static final String SECRET_KEY = "7bce06d6331e532e8c4c85e6eaae4217711768fe1aa582b4549c2722a8ef0497";
-    public static final Long EXPIRATION_TIME = 86400000L; // 1 day
-    public static final String BEARER_TOKEN_HEADER = "Authorization";
-    public static final String TOKEN_PREFIX = "Bearer ";
-    public static final String INVITE_TOKEN_HEADER = "Invite-Token";
-}
Index: serveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/constants/LocalDateTimeConstants.java
===================================================================
--- ReserveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/constants/LocalDateTimeConstants.java	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,7 +1,0 @@
-package mk.ukim.finki.it.reservengo.constants;
-
-import java.time.format.DateTimeFormatter;
-
-public class LocalDateTimeConstants {
-    public static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm");
-}
Index: serveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/dto/adminDTO/DisplayAdminLocalsDTO.java
===================================================================
--- ReserveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/dto/adminDTO/DisplayAdminLocalsDTO.java	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,31 +1,0 @@
-package mk.ukim.finki.it.reservengo.dto.adminDTO;
-
-import mk.ukim.finki.it.reservengo.model.domain.Local;
-
-import java.util.List;
-
-import static mk.ukim.finki.it.reservengo.constants.LocalDateTimeConstants.FORMATTER;
-
-public record DisplayAdminLocalsDTO(
-        Long localId,
-        String localName,
-        String localLogo,
-        String createdAt,
-        String modifiedAt
-) {
-    public static DisplayAdminLocalsDTO fromLocal(Local local) {
-        return new DisplayAdminLocalsDTO(
-                local.getId(),
-                local.getName(),
-                local.getLogoUrl(),
-                local.getCreatedAt().format(FORMATTER),
-                local.getModifiedAt().format(FORMATTER)
-        );
-    }
-
-    public static List<DisplayAdminLocalsDTO> fromLocals(List<Local> locals) {
-        return locals.stream()
-                .map(DisplayAdminLocalsDTO::fromLocal)
-                .toList();
-    }
-}
Index: serveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/dto/contactDTO/ContactDTO.java
===================================================================
--- ReserveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/dto/contactDTO/ContactDTO.java	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,25 +1,0 @@
-package mk.ukim.finki.it.reservengo.dto.contactDTO;
-
-import mk.ukim.finki.it.reservengo.model.domain.Contact;
-
-import java.util.Map;
-
-public record ContactDTO(
-        String phone,
-        String email,
-        Map<String, String> socialLinks
-) {
-    public static ContactDTO from(Contact contact) {
-        return new ContactDTO(
-                contact.getPhone(),
-                contact.getEmail(),
-                contact.getSocialLinks()
-        );
-    }
-
-    public Contact toContact() {
-        return new Contact(
-                phone, email, socialLinks
-        );
-    }
-}
Index: serveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/dto/customerDTO/RatingDTO.java
===================================================================
--- ReserveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/dto/customerDTO/RatingDTO.java	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,9 +1,0 @@
-package mk.ukim.finki.it.reservengo.dto.customerDTO;
-
-public record RatingDTO(
-        int rating
-) {
-    public static RatingDTO from(int localRating) {
-        return new RatingDTO(localRating);
-    }
-}
Index: serveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/dto/eventDTO/CreateEventDTO.java
===================================================================
--- ReserveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/dto/eventDTO/CreateEventDTO.java	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,19 +1,0 @@
-package mk.ukim.finki.it.reservengo.dto.eventDTO;
-
-import mk.ukim.finki.it.reservengo.model.domain.Event;
-import mk.ukim.finki.it.reservengo.model.domain.Local;
-import mk.ukim.finki.it.reservengo.model.enumerations.EventType;
-
-import java.time.LocalDateTime;
-
-public record CreateEventDTO(
-        String name,
-        String description,
-        EventType eventType,
-        LocalDateTime eventStart,
-        LocalDateTime eventEnd
-) {
-    public Event toEvent(Local local){
-        return new Event(name, description, eventType, eventStart, eventEnd, local);
-    }
-}
Index: serveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/dto/eventDTO/DisplayEventDTO.java
===================================================================
--- ReserveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/dto/eventDTO/DisplayEventDTO.java	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,40 +1,0 @@
-package mk.ukim.finki.it.reservengo.dto.eventDTO;
-
-import mk.ukim.finki.it.reservengo.model.domain.Event;
-import mk.ukim.finki.it.reservengo.model.enumerations.EventStatus;
-import mk.ukim.finki.it.reservengo.model.enumerations.EventType;
-
-import java.time.LocalDateTime;
-import java.util.List;
-
-public record DisplayEventDTO(
-        Long id,
-        String name,
-        String description,
-        EventType eventType,
-        LocalDateTime eventStart,
-        LocalDateTime eventEnd,
-        Long localId,
-        EventStatus status,
-        String localLogo
-) {
-    public static DisplayEventDTO fromEvent(Event event) {
-        return new DisplayEventDTO(
-                event.getId(),
-                event.getName(),
-                event.getDescription(),
-                event.getEventType(),
-                event.getEventStart(),
-                event.getEventEnd(),
-                event.getLocal().getId(),
-                event.getStatus(),
-                event.getLocal().getLogoUrl()
-        );
-    }
-
-    public static List<DisplayEventDTO> fromEvents(List<Event> events) {
-        return events.stream()
-                .map(DisplayEventDTO::fromEvent)
-                .toList();
-    }
-}
Index: serveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/dto/eventDTO/PagedEventDTO.java
===================================================================
--- ReserveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/dto/eventDTO/PagedEventDTO.java	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,21 +1,0 @@
-package mk.ukim.finki.it.reservengo.dto.eventDTO;
-
-import org.springframework.data.domain.Page;
-
-import java.util.List;
-
-public record PagedEventDTO(
-        List<DisplayEventDTO> events,
-        int currentPage,
-        int totalPages,
-        long itemsPerPage
-) {
-    public static PagedEventDTO from(Page<DisplayEventDTO> page) {
-        return new PagedEventDTO(
-                page.getContent(),
-                page.getNumber(),
-                page.getTotalPages(),
-                page.getTotalElements()
-        );
-    }
-}
Index: serveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/dto/jwtDTO/JWTAuthenticationRequestDTO.java
===================================================================
--- ReserveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/dto/jwtDTO/JWTAuthenticationRequestDTO.java	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,56 +1,0 @@
-package mk.ukim.finki.it.reservengo.dto.jwtDTO;
-
-import mk.ukim.finki.it.reservengo.model.domain.Customer;
-import mk.ukim.finki.it.reservengo.model.domain.LocalManager;
-import mk.ukim.finki.it.reservengo.model.domain.LocalWorker;
-import mk.ukim.finki.it.reservengo.model.enumerations.Provider;
-import mk.ukim.finki.it.reservengo.model.enumerations.Role;
-
-public record JWTAuthenticationRequestDTO(
-        String firstName,
-        String lastName,
-        String email,
-        String password,
-        String phoneNumber
-) {
-
-
-    public Customer toCustomer(String encodedPassword, Provider provider, String providerId) {
-        return new Customer(
-                firstName,
-                lastName,
-                email,
-                encodedPassword,
-                phoneNumber,
-                Role.ROLE_CUSTOMER,
-                provider,
-                providerId
-        );
-    }
-
-    public LocalWorker toLocalWorker(String encodedPassword, Provider provider, String providerId) {
-        return new LocalWorker(
-                firstName,
-                lastName,
-                email,
-                encodedPassword,
-                phoneNumber,
-                Role.ROLE_LOCAL_WORKER,
-                provider,
-                providerId
-        );
-    }
-
-    public LocalManager toLocalManager(String encodedPassword, Provider provider, String providerId) {
-        return new LocalManager(
-                firstName,
-                lastName,
-                email,
-                encodedPassword,
-                phoneNumber,
-                Role.ROLE_LOCAL_MANAGER,
-                provider,
-                providerId
-        );
-    }
-}
Index: serveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/dto/jwtDTO/JWTAuthenticationResponseDTO.java
===================================================================
--- ReserveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/dto/jwtDTO/JWTAuthenticationResponseDTO.java	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,27 +1,0 @@
-package mk.ukim.finki.it.reservengo.dto.jwtDTO;
-
-import mk.ukim.finki.it.reservengo.model.domain.User;
-import mk.ukim.finki.it.reservengo.model.enumerations.Role;
-
-
-public record JWTAuthenticationResponseDTO(
-        Long id,
-        String firstName,
-        String lastName,
-        String email,
-        String logoUrl,
-        Role role,
-        String token
-) {
-    public static JWTAuthenticationResponseDTO fromUser(User user, String jwt) {
-        return new JWTAuthenticationResponseDTO(
-                user.getId(),
-                user.getFirstName(),
-                user.getLastName(),
-                user.getEmail(),
-                user.getProfilePhotoUrl(),
-                user.getUserRole(),
-                jwt
-        );
-    }
-}
Index: serveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/dto/jwtDTO/JWTLoginDTO.java
===================================================================
--- ReserveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/dto/jwtDTO/JWTLoginDTO.java	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,7 +1,0 @@
-package mk.ukim.finki.it.reservengo.dto.jwtDTO;
-
-public record JWTLoginDTO(
-        String email,
-        String password
-) {
-}
Index: serveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/dto/jwtDTO/VerificationDTO.java
===================================================================
--- ReserveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/dto/jwtDTO/VerificationDTO.java	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,7 +1,0 @@
-package mk.ukim.finki.it.reservengo.dto.jwtDTO;
-
-public record VerificationDTO(
-        String email,
-        String verificationCode
-) {
-}
Index: serveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/dto/localDTO/CreateLocalDTO.java
===================================================================
--- ReserveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/dto/localDTO/CreateLocalDTO.java	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,6 +1,0 @@
-package mk.ukim.finki.it.reservengo.dto.localDTO;
-
-public record CreateLocalDTO(
-        String name
-) {
-}
Index: serveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/dto/localDTO/CreateLocalDetailsDTO.java
===================================================================
--- ReserveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/dto/localDTO/CreateLocalDetailsDTO.java	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,19 +1,0 @@
-package mk.ukim.finki.it.reservengo.dto.localDTO;
-
-import mk.ukim.finki.it.reservengo.dto.contactDTO.ContactDTO;
-import mk.ukim.finki.it.reservengo.model.enumerations.LocalType;
-import mk.ukim.finki.it.reservengo.model.enumerations.ProvidedService;
-
-import java.util.List;
-
-public record CreateLocalDetailsDTO(
-        String name,
-        String description,
-        String address,
-        List<WorkingHourDTO> workingHours,
-        List<ProvidedService> services,
-        LocalType localType,
-        String menuLink,
-        ContactDTO contact
-) {
-}
Index: serveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/dto/localDTO/DeleteLocalPhotosDTO.java
===================================================================
--- ReserveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/dto/localDTO/DeleteLocalPhotosDTO.java	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,8 +1,0 @@
-package mk.ukim.finki.it.reservengo.dto.localDTO;
-
-import java.util.List;
-
-public record DeleteLocalPhotosDTO(
-        List<String> localPhotosUrls
-) {
-}
Index: serveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/dto/localDTO/DeleteLocalPhotosResultDTO.java
===================================================================
--- ReserveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/dto/localDTO/DeleteLocalPhotosResultDTO.java	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,9 +1,0 @@
-package mk.ukim.finki.it.reservengo.dto.localDTO;
-
-import java.util.List;
-
-public record DeleteLocalPhotosResultDTO(
-        List<String> deletedPhotos,
-        List<String> notFoundPhotos
-) {
-}
Index: serveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/dto/localDTO/DisplayLocalDTO.java
===================================================================
--- ReserveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/dto/localDTO/DisplayLocalDTO.java	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,36 +1,0 @@
-package mk.ukim.finki.it.reservengo.dto.localDTO;
-
-import mk.ukim.finki.it.reservengo.model.domain.Local;
-import mk.ukim.finki.it.reservengo.model.enumerations.LocalType;
-
-import java.util.List;
-
-public record DisplayLocalDTO(
-        Long id,
-        String name,
-        String description,
-        String address,
-        Boolean open,
-        String logo,
-        LocalType localType,
-        Double averageRating
-) {
-    public static DisplayLocalDTO fromLocal(Local local) {
-        return new DisplayLocalDTO(
-                local.getId(),
-                local.getName(),
-                local.getDescription(),
-                local.getAddress(),
-                local.isOpenNow(),
-                local.getLogoUrl(),
-                local.getLocalType(),
-                local.getAverageRating()
-        );
-    }
-
-    public static List<DisplayLocalDTO> fromLocals(List<Local> locals) {
-        return locals.stream()
-                .map(DisplayLocalDTO::fromLocal)
-                .toList();
-    }
-}
Index: serveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/dto/localDTO/DisplayLocalDetailsDTO.java
===================================================================
--- ReserveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/dto/localDTO/DisplayLocalDetailsDTO.java	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,43 +1,0 @@
-package mk.ukim.finki.it.reservengo.dto.localDTO;
-
-import mk.ukim.finki.it.reservengo.dto.contactDTO.ContactDTO;
-import mk.ukim.finki.it.reservengo.dto.eventDTO.DisplayEventDTO;
-import mk.ukim.finki.it.reservengo.model.domain.Local;
-import mk.ukim.finki.it.reservengo.model.enumerations.LocalType;
-import mk.ukim.finki.it.reservengo.model.enumerations.ProvidedService;
-
-import java.util.List;
-
-public record DisplayLocalDetailsDTO(
-        Long id,
-        String name,
-        String description,
-        String address,
-        List<WorkingHourDTO> workingHours,
-        List<ProvidedService> services,
-        Double ratingAvg,
-        List<DisplayEventDTO> events,
-        List<String> localPhotos,
-        String menuLink,
-        ContactDTO contact,
-        String logo,
-        LocalType localType
-) {
-    public static DisplayLocalDetailsDTO from(Local local) {
-        return new DisplayLocalDetailsDTO(
-                local.getId(),
-                local.getName(),
-                local.getDescription(),
-                local.getAddress(),
-                WorkingHourDTO.from(local.getWorkingHours()),
-                local.getAvailableServices(),
-                local.getAverageRating(),
-                DisplayEventDTO.fromEvents(local.getEvents()),
-                local.getPhotos(),
-                local.getMenuLink(),
-                ContactDTO.from(local.getContact()),
-                local.getLogoUrl(),
-                local.getLocalType()
-        );
-    }
-}
Index: serveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/dto/localDTO/PagedLocalDTO.java
===================================================================
--- ReserveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/dto/localDTO/PagedLocalDTO.java	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,22 +1,0 @@
-package mk.ukim.finki.it.reservengo.dto.localDTO;
-
-import org.springframework.data.domain.Page;
-
-
-import java.util.List;
-
-public record PagedLocalDTO(
-        List<DisplayLocalDTO> locals,
-        int currentPage,
-        int totalPages,
-        long itemsPerPage
-) {
-    public static PagedLocalDTO from(Page<DisplayLocalDTO> page) {
-        return new PagedLocalDTO(
-                page.getContent(),
-                page.getNumber(),
-                page.getTotalPages(),
-                page.getTotalElements()
-        );
-    }
-}
Index: serveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/dto/localDTO/WorkingHourDTO.java
===================================================================
--- ReserveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/dto/localDTO/WorkingHourDTO.java	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,41 +1,0 @@
-package mk.ukim.finki.it.reservengo.dto.localDTO;
-
-import mk.ukim.finki.it.reservengo.model.domain.WorkingHour;
-
-import java.time.DayOfWeek;
-import java.time.LocalTime;
-import java.util.List;
-
-public record WorkingHourDTO(
-        DayOfWeek dayOfWeek,
-        LocalTime openTime,
-        LocalTime closeTime
-) {
-    public static WorkingHourDTO from(WorkingHour workingHour) {
-        return new WorkingHourDTO(
-                workingHour.getDayOfWeek(),
-                workingHour.getOpenTime(),
-                workingHour.getCloseTime()
-        );
-    }
-
-    public static List<WorkingHourDTO> from(List<WorkingHour> workingHours) {
-        return workingHours.stream()
-                .map(WorkingHourDTO::from)
-                .toList();
-    }
-
-    public WorkingHour to() {
-        return new WorkingHour(
-                dayOfWeek,
-                openTime,
-                closeTime
-        );
-    }
-
-    public static List<WorkingHour> to(List<WorkingHourDTO> list) {
-        return list.stream()
-                .map(WorkingHourDTO::to)
-                .toList();
-    }
-}
Index: serveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/dto/reservationDTO/CreateReservationDTO.java
===================================================================
--- ReserveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/dto/reservationDTO/CreateReservationDTO.java	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,10 +1,0 @@
-package mk.ukim.finki.it.reservengo.dto.reservationDTO;
-
-import java.time.LocalDateTime;
-
-public record CreateReservationDTO(
-        LocalDateTime timeOfReservation,
-        Integer capacity,
-        String description
-) {
-}
Index: serveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/dto/reservationDTO/DeleteReservationDTO.java
===================================================================
--- ReserveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/dto/reservationDTO/DeleteReservationDTO.java	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,8 +1,0 @@
-package mk.ukim.finki.it.reservengo.dto.reservationDTO;
-
-import java.util.List;
-
-public record DeleteReservationDTO(
-        List<Long> reservationIds
-) {
-}
Index: serveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/dto/reservationDTO/DisplayReservationDTO.java
===================================================================
--- ReserveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/dto/reservationDTO/DisplayReservationDTO.java	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,36 +1,0 @@
-package mk.ukim.finki.it.reservengo.dto.reservationDTO;
-
-import mk.ukim.finki.it.reservengo.model.domain.Reservation;
-import mk.ukim.finki.it.reservengo.model.enumerations.ReservationStatus;
-
-import java.time.LocalDateTime;
-import java.util.List;
-
-public record DisplayReservationDTO(
-        Long id,
-        String localName,
-        String localLogo,
-        LocalDateTime timeOfReservation,
-        Integer capacity,
-        String description,
-        ReservationStatus status
-) {
-
-    public static DisplayReservationDTO from(Reservation reservation) {
-        return new DisplayReservationDTO(
-                reservation.getId(),
-                reservation.getLocal().getName(),
-                reservation.getLocal().getLogoUrl(),
-                reservation.getTimeOfReservation(),
-                reservation.getTable().getCapacity(),
-                reservation.getTable().getDescription(),
-                reservation.getStatus()
-        );
-    }
-
-    public static List<DisplayReservationDTO> from(List<Reservation> reservations) {
-        return reservations.stream()
-                .map(DisplayReservationDTO::from)
-                .toList();
-    }
-}
Index: serveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/dto/reservationDTO/EditReservationDTO.java
===================================================================
--- ReserveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/dto/reservationDTO/EditReservationDTO.java	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,11 +1,0 @@
-package mk.ukim.finki.it.reservengo.dto.reservationDTO;
-
-
-import java.time.LocalDateTime;
-
-public record EditReservationDTO(
-        LocalDateTime timeOfReservation,
-        Integer capacity,
-        String description
-) {
-}
Index: serveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/dto/userDTO/DisplayUserDTO.java
===================================================================
--- ReserveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/dto/userDTO/DisplayUserDTO.java	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,34 +1,0 @@
-package mk.ukim.finki.it.reservengo.dto.userDTO;
-
-import mk.ukim.finki.it.reservengo.model.domain.User;
-import mk.ukim.finki.it.reservengo.model.enumerations.Role;
-
-import java.util.List;
-
-public record DisplayUserDTO(
-        Long id,
-        String firstName,
-        String lastName,
-        String email,
-        String phoneNumber,
-        Role role,
-        String profilePhoto
-) {
-    public static DisplayUserDTO fromUser(User user) {
-        return new DisplayUserDTO(
-                user.getId(),
-                user.getFirstName(),
-                user.getLastName(),
-                user.getEmail(),
-                user.getPhoneNumber(),
-                user.getUserRole(),
-                user.getProfilePhotoUrl()
-        );
-    }
-
-    public static List<DisplayUserDTO> fromUsers(List<? extends User> users) {
-        return users.stream()
-                .map(DisplayUserDTO::fromUser)
-                .toList();
-    }
-}
Index: serveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/dto/userDTO/DisplayUserEmailDTO.java
===================================================================
--- ReserveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/dto/userDTO/DisplayUserEmailDTO.java	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,17 +1,0 @@
-package mk.ukim.finki.it.reservengo.dto.userDTO;
-
-import mk.ukim.finki.it.reservengo.model.domain.User;
-
-public record DisplayUserEmailDTO(
-        Long id,
-        String email,
-        String jwt
-) {
-    public static DisplayUserEmailDTO fromUser(User user, String jwt) {
-        return new DisplayUserEmailDTO(
-                user.getId(),
-                user.getEmail(),
-                jwt
-        );
-    }
-}
Index: serveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/dto/userDTO/EditUserEmailDTO.java
===================================================================
--- ReserveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/dto/userDTO/EditUserEmailDTO.java	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,6 +1,0 @@
-package mk.ukim.finki.it.reservengo.dto.userDTO;
-
-public record EditUserEmailDTO(
-        String newEmail
-) {
-}
Index: serveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/dto/userDTO/EditUserPasswordDTO.java
===================================================================
--- ReserveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/dto/userDTO/EditUserPasswordDTO.java	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,7 +1,0 @@
-package mk.ukim.finki.it.reservengo.dto.userDTO;
-
-public record EditUserPasswordDTO(
-        String currentPassword,
-        String newPassword
-) {
-}
Index: serveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/dto/userDTO/EditUserProfileDTO.java
===================================================================
--- ReserveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/dto/userDTO/EditUserProfileDTO.java	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,9 +1,0 @@
-package mk.ukim.finki.it.reservengo.dto.userDTO;
-
-
-public record EditUserProfileDTO(
-        String firstName,
-        String lastName,
-        String phoneNumber
-) {
-}
Index: serveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/dto/workerDTO/DisplayLocalReservationDTO.java
===================================================================
--- ReserveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/dto/workerDTO/DisplayLocalReservationDTO.java	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,35 +1,0 @@
-package mk.ukim.finki.it.reservengo.dto.workerDTO;
-
-import mk.ukim.finki.it.reservengo.model.domain.Reservation;
-import mk.ukim.finki.it.reservengo.model.enumerations.ReservationStatus;
-
-import java.time.LocalDateTime;
-import java.util.List;
-
-public record DisplayLocalReservationDTO(
-        Long reservationId,
-        String customerName,
-        Long customerId,
-        LocalDateTime timeOfReservation,
-        Integer capacity,
-        String description,
-        ReservationStatus reservationStatus
-) {
-    public static DisplayLocalReservationDTO from(Reservation reservation) {
-        return new DisplayLocalReservationDTO(
-                reservation.getId(),
-                reservation.getCustomer().getFirstName(),
-                reservation.getCustomer().getId(),
-                reservation.getTimeOfReservation(),
-                reservation.getTable().getCapacity(),
-                reservation.getTable().getDescription(),
-                reservation.getStatus()
-        );
-    }
-
-    public static List<DisplayLocalReservationDTO> from(List<Reservation> reservations) {
-        return reservations.stream()
-                .map(DisplayLocalReservationDTO::from)
-                .toList();
-    }
-}
Index: serveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/dto/workerDTO/DisplayWorkerDTO.java
===================================================================
--- ReserveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/dto/workerDTO/DisplayWorkerDTO.java	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,35 +1,0 @@
-package mk.ukim.finki.it.reservengo.dto.workerDTO;
-
-import mk.ukim.finki.it.reservengo.model.domain.LocalWorker;
-import mk.ukim.finki.it.reservengo.model.enumerations.Position;
-import mk.ukim.finki.it.reservengo.model.enumerations.Role;
-
-import java.util.List;
-
-public record DisplayWorkerDTO(
-        Long id,
-        String firstName,
-        String lastName,
-        String email,
-        String phoneNumber,
-        Role role,
-        Position position
-) {
-    public static DisplayWorkerDTO fromWorker(LocalWorker worker) {
-        return new DisplayWorkerDTO(
-                worker.getId(),
-                worker.getFirstName(),
-                worker.getLastName(),
-                worker.getEmail(),
-                worker.getPhoneNumber(),
-                worker.getUserRole(),
-                worker.getPosition()
-        );
-    }
-
-    public static List<DisplayWorkerDTO> fromWorkers(List<LocalWorker> workers) {
-        return workers.stream()
-                .map(DisplayWorkerDTO::fromWorker)
-                .toList();
-    }
-}
Index: serveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/dto/workerDTO/PositionDTO.java
===================================================================
--- ReserveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/dto/workerDTO/PositionDTO.java	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,8 +1,0 @@
-package mk.ukim.finki.it.reservengo.dto.workerDTO;
-
-import mk.ukim.finki.it.reservengo.model.enumerations.Position;
-
-public record PositionDTO(
-        Position position
-) {
-}
Index: serveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/model/domain/Admin.java
===================================================================
--- ReserveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/model/domain/Admin.java	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,18 +1,0 @@
-package mk.ukim.finki.it.reservengo.model.domain;
-
-import jakarta.persistence.Entity;
-import lombok.Data;
-import lombok.EqualsAndHashCode;
-import lombok.NoArgsConstructor;
-import mk.ukim.finki.it.reservengo.model.enumerations.Role;
-
-@EqualsAndHashCode(callSuper = true)
-@Entity
-@NoArgsConstructor
-@Data
-public class Admin extends User {
-    public Admin(String email, String password, Role userRole) {
-        super(null, null, email, password, null, userRole);
-    }
-
-}
Index: serveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/model/domain/Contact.java
===================================================================
--- ReserveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/model/domain/Contact.java	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,24 +1,0 @@
-package mk.ukim.finki.it.reservengo.model.domain;
-
-import jakarta.persistence.Column;
-import jakarta.persistence.ElementCollection;
-import jakarta.persistence.Embeddable;
-import jakarta.persistence.MapKeyColumn;
-import lombok.AllArgsConstructor;
-import lombok.Data;
-import lombok.NoArgsConstructor;
-
-import java.util.Map;
-
-@Data
-@AllArgsConstructor
-@NoArgsConstructor
-@Embeddable
-public class Contact {
-    private String phone;
-    private String email;
-    @ElementCollection
-    @MapKeyColumn(name = "social_app_name")
-    @Column(name = "social_app_link")
-    private Map<String, String> socialLinks;
-}
Index: serveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/model/domain/Customer.java
===================================================================
--- ReserveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/model/domain/Customer.java	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,28 +1,0 @@
-package mk.ukim.finki.it.reservengo.model.domain;
-
-import jakarta.persistence.*;
-import lombok.*;
-import mk.ukim.finki.it.reservengo.model.enumerations.Provider;
-import mk.ukim.finki.it.reservengo.model.enumerations.Role;
-
-import java.util.List;
-
-@EqualsAndHashCode(callSuper = true)
-@Entity
-@NoArgsConstructor
-@AllArgsConstructor
-@Data
-public class Customer extends User {
-    @OneToMany(mappedBy = "customer", cascade = CascadeType.ALL)
-    private List<Reservation> reservations;
-
-    @ManyToMany
-    private List<Local> favouriteLocals;
-
-    @ManyToMany
-    private List<Event> favouriteEvents;
-
-    public Customer(String firstName, String lastName, String email, String password, String phoneNumber, Role userRole, Provider provider, String providerId) {
-        super(firstName, lastName, email, password, phoneNumber, userRole, provider, providerId);
-    }
-}
Index: serveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/model/domain/DiningTable.java
===================================================================
--- ReserveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/model/domain/DiningTable.java	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,17 +1,0 @@
-package mk.ukim.finki.it.reservengo.model.domain;
-
-import jakarta.persistence.*;
-import lombok.AllArgsConstructor;
-import lombok.Data;
-import lombok.NoArgsConstructor;
-import lombok.NonNull;
-
-@Embeddable
-@AllArgsConstructor
-@NoArgsConstructor
-@Data
-public class DiningTable {
-    @NonNull
-    private Integer capacity;
-    private String description;
-}
Index: serveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/model/domain/Event.java
===================================================================
--- ReserveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/model/domain/Event.java	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,56 +1,0 @@
-package mk.ukim.finki.it.reservengo.model.domain;
-
-import jakarta.persistence.*;
-import lombok.*;
-import mk.ukim.finki.it.reservengo.config.listeners.Auditable;
-import mk.ukim.finki.it.reservengo.model.enumerations.EventStatus;
-import mk.ukim.finki.it.reservengo.model.enumerations.EventType;
-
-import java.time.LocalDateTime;
-
-@EqualsAndHashCode(callSuper = true)
-@Data
-@Entity
-@AllArgsConstructor
-@NoArgsConstructor
-public class Event extends Auditable {
-
-    @Id
-    @GeneratedValue(strategy = GenerationType.IDENTITY)
-    private Long id;
-
-    @ManyToOne
-    private Local local;
-
-    private String name;
-
-    private String description;
-
-    @Enumerated(EnumType.STRING)
-    private EventType eventType;
-
-    private LocalDateTime eventStart;
-
-    private LocalDateTime eventEnd;
-
-    public Event(String name, String description, EventType eventType, LocalDateTime eventStart, LocalDateTime eventEnd, Local local) {
-        this.name = name;
-        this.description = description;
-        this.eventType = eventType;
-        this.eventStart = eventStart;
-        this.eventEnd = eventEnd;
-        this.local = local;
-    }
-
-    public EventStatus getStatus() {
-        LocalDateTime now = LocalDateTime.now();
-
-        if (now.isBefore(eventStart)) {
-            return EventStatus.UPCOMING;
-        } else if (now.isAfter(eventEnd)) {
-            return EventStatus.FINISHED;
-        } else {
-            return EventStatus.ACTIVE;
-        }
-    }
-}
Index: serveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/model/domain/Local.java
===================================================================
--- ReserveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/model/domain/Local.java	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,114 +1,0 @@
-package mk.ukim.finki.it.reservengo.model.domain;
-
-import jakarta.persistence.*;
-import lombok.AllArgsConstructor;
-import lombok.Data;
-import lombok.EqualsAndHashCode;
-import lombok.NoArgsConstructor;
-import mk.ukim.finki.it.reservengo.config.listeners.Auditable;
-import mk.ukim.finki.it.reservengo.model.enumerations.LocalType;
-import mk.ukim.finki.it.reservengo.model.enumerations.ProvidedService;
-import org.springframework.data.jpa.domain.support.AuditingEntityListener;
-
-import java.time.DayOfWeek;
-import java.time.LocalDateTime;
-import java.time.LocalTime;
-import java.util.List;
-import java.util.Map;
-
-
-@EqualsAndHashCode(callSuper = true)
-@Entity
-@Table(name = "local_")
-@Data
-@AllArgsConstructor
-@NoArgsConstructor
-@EntityListeners(AuditingEntityListener.class)
-public class Local extends Auditable {
-    @Id
-    @GeneratedValue(strategy = GenerationType.IDENTITY)
-    private Long id;
-
-    private String name;
-
-    private String description;
-
-    private String address;
-
-    @ElementCollection
-    private List<WorkingHour> workingHours;
-
-    @Enumerated(EnumType.STRING)
-    @ElementCollection
-    private List<ProvidedService> availableServices;
-
-    @Enumerated(EnumType.STRING)
-    private LocalType localType;
-
-    @ElementCollection
-    @MapKeyColumn(name = "customer_id")
-    private Map<Long, Integer> ratings;
-
-    @OneToMany(mappedBy = "local", cascade = CascadeType.ALL, orphanRemoval = true)
-    private List<Event> events;
-
-    @ElementCollection
-    private List<String> photos;
-
-    private String menuLink;
-
-    @Embedded
-    private Contact contact;
-
-    @OneToMany(mappedBy = "local", cascade = CascadeType.ALL)
-    private List<Reservation> reservations;
-
-    private String logoUrl;
-
-    public Local(String name, String description, String address, List<WorkingHour> workingHours, List<ProvidedService> availableServices, Map<Long, Integer> ratings, List<Event> events, String logoUrl, List<String> photos, String menuLink, Contact contact, List<Reservation> reservations, LocalType localType) {
-        this.name = name;
-        this.description = description;
-        this.address = address;
-        this.workingHours = workingHours;
-        this.availableServices = availableServices;
-        this.ratings = ratings;
-        this.events = events;
-        this.logoUrl = logoUrl;
-        this.photos = photos;
-        this.menuLink = menuLink;
-        this.contact = contact;
-        this.reservations = reservations;
-        this.localType = localType;
-    }
-
-    public Local(String name) {
-        this.name = name;
-    }
-
-    public double getAverageRating() {
-        if (ratings == null || ratings.isEmpty()) {
-            return 0;
-        }
-
-        return ratings.values().stream()
-                .mapToInt(Integer::intValue)
-                .average()
-                .orElse(0.0);
-    }
-
-    public boolean isOpenNow() {
-        if (workingHours == null || workingHours.isEmpty()) {
-            return false;
-        }
-
-        LocalDateTime now = LocalDateTime.now();
-        DayOfWeek today = now.getDayOfWeek();
-        LocalTime currentTime = now.toLocalTime();
-
-        return workingHours.stream()
-                .filter(wh -> wh.getDayOfWeek().name().equals(today.name()))
-                .anyMatch(wh ->
-                        currentTime.isAfter(wh.getOpenTime()) && currentTime.isBefore(wh.getCloseTime())
-                );
-    }
-}
Index: serveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/model/domain/LocalManager.java
===================================================================
--- ReserveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/model/domain/LocalManager.java	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,30 +1,0 @@
-package mk.ukim.finki.it.reservengo.model.domain;
-
-import jakarta.persistence.Entity;
-import jakarta.persistence.EnumType;
-import jakarta.persistence.Enumerated;
-import jakarta.persistence.ManyToOne;
-import lombok.AllArgsConstructor;
-import lombok.Data;
-import lombok.EqualsAndHashCode;
-import lombok.NoArgsConstructor;
-import mk.ukim.finki.it.reservengo.model.enumerations.Position;
-import mk.ukim.finki.it.reservengo.model.enumerations.Provider;
-import mk.ukim.finki.it.reservengo.model.enumerations.Role;
-
-@EqualsAndHashCode(callSuper = true)
-@Entity
-@NoArgsConstructor
-@AllArgsConstructor
-@Data
-public class LocalManager extends User {
-    @ManyToOne
-    private Local local;
-
-    @Enumerated(EnumType.STRING)
-    private Position position;
-
-    public LocalManager(String firstName, String lastName, String email, String password, String phoneNumber, Role userRole, Provider provider, String providerId) {
-        super(firstName, lastName, email, password, phoneNumber, userRole, provider, providerId);
-    }
-}
Index: serveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/model/domain/LocalWorker.java
===================================================================
--- ReserveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/model/domain/LocalWorker.java	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,30 +1,0 @@
-package mk.ukim.finki.it.reservengo.model.domain;
-
-import jakarta.persistence.Entity;
-import jakarta.persistence.EnumType;
-import jakarta.persistence.Enumerated;
-import jakarta.persistence.ManyToOne;
-import lombok.AllArgsConstructor;
-import lombok.Data;
-import lombok.EqualsAndHashCode;
-import lombok.NoArgsConstructor;
-import mk.ukim.finki.it.reservengo.model.enumerations.Position;
-import mk.ukim.finki.it.reservengo.model.enumerations.Provider;
-import mk.ukim.finki.it.reservengo.model.enumerations.Role;
-
-@EqualsAndHashCode(callSuper = true)
-@Entity
-@AllArgsConstructor
-@NoArgsConstructor
-@Data
-public class LocalWorker extends User {
-    @ManyToOne
-    private Local local;
-
-    @Enumerated(EnumType.STRING)
-    private Position position;
-
-    public LocalWorker(String firstName, String lastName, String email, String password, String phoneNumber, Role userRole, Provider provider, String providerId) {
-        super(firstName, lastName, email, password, phoneNumber, userRole, provider, providerId);
-    }
-}
Index: serveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/model/domain/Reservation.java
===================================================================
--- ReserveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/model/domain/Reservation.java	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,33 +1,0 @@
-package mk.ukim.finki.it.reservengo.model.domain;
-
-import jakarta.persistence.*;
-import lombok.*;
-import mk.ukim.finki.it.reservengo.config.listeners.Auditable;
-import mk.ukim.finki.it.reservengo.model.enumerations.ReservationStatus;
-
-import java.time.LocalDateTime;
-
-@EqualsAndHashCode(callSuper = true)
-@Data
-@Entity
-@AllArgsConstructor
-@NoArgsConstructor
-public class Reservation extends Auditable {
-    @Id
-    @GeneratedValue(strategy = GenerationType.IDENTITY)
-    private Long id;
-
-    @ManyToOne
-    private Customer customer;
-
-    @ManyToOne
-    private Local local;
-
-    private LocalDateTime timeOfReservation;
-
-    @Embedded
-    private DiningTable table;
-
-    @Enumerated(EnumType.STRING)
-    private ReservationStatus status;
-}
Index: serveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/model/domain/User.java
===================================================================
--- ReserveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/model/domain/User.java	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,121 +1,0 @@
-package mk.ukim.finki.it.reservengo.model.domain;
-
-import com.fasterxml.jackson.annotation.JsonIgnore;
-import jakarta.persistence.*;
-import lombok.AllArgsConstructor;
-import lombok.Data;
-import lombok.EqualsAndHashCode;
-import lombok.NoArgsConstructor;
-import mk.ukim.finki.it.reservengo.config.listeners.Auditable;
-import mk.ukim.finki.it.reservengo.model.enumerations.Provider;
-import mk.ukim.finki.it.reservengo.model.enumerations.Role;
-import org.springframework.security.core.GrantedAuthority;
-import org.springframework.security.core.authority.SimpleGrantedAuthority;
-import org.springframework.security.core.userdetails.UserDetails;
-
-import java.time.LocalDateTime;
-import java.util.Collection;
-import java.util.List;
-
-@EqualsAndHashCode(callSuper = true)
-@Entity
-@Inheritance(strategy = InheritanceType.JOINED)
-@Table(name = "app_user")
-@Data
-@AllArgsConstructor
-@NoArgsConstructor
-public class User extends Auditable implements UserDetails {
-    @Id
-    @GeneratedValue(strategy = GenerationType.IDENTITY)
-    private Long id;
-
-    private String firstName;
-
-    private String lastName;
-
-    @Column(unique = true, nullable = false)
-    private String email;
-
-    @JsonIgnore
-    @Column(nullable = false)
-    private String password;
-
-    private String phoneNumber;
-
-    @Enumerated(EnumType.STRING)
-    private Role userRole;
-
-    private String profilePhotoUrl;
-
-    @Column(nullable = false)
-    private boolean enabled;
-
-    private LocalDateTime lastActivityDate;
-
-    private String verificationCode;
-
-    private LocalDateTime verificationCodeExpiryDate;
-
-    private Provider provider;
-
-    private String providerId;
-
-    public User(String firstName, String lastName, String email, String password, String phoneNumber, Role userRole) {
-        this.firstName = firstName;
-        this.lastName = lastName;
-        this.email = email;
-        this.password = password;
-        this.phoneNumber = phoneNumber;
-        this.userRole = userRole;
-        this.enabled = true;
-        this.provider = Provider.LOCAL;
-        this.lastActivityDate = LocalDateTime.now();
-    }
-
-    public User(String firstName, String lastName, String email, String password, String phoneNumber, Role userRole, Provider provider, String providerId) {
-        this.firstName = firstName;
-        this.lastName = lastName;
-        this.email = email;
-        this.password = password;
-        this.phoneNumber = phoneNumber;
-        this.userRole = userRole;
-        this.provider = provider;
-        this.providerId = providerId;
-        this.lastActivityDate = LocalDateTime.now();
-    }
-
-    @Override
-    public Collection<? extends GrantedAuthority> getAuthorities() {
-        return List.of(new SimpleGrantedAuthority(userRole.name()));
-    }
-
-    @Override
-    public String getPassword() {
-        return password;
-    }
-
-    @Override
-    public String getUsername() {
-        return email;
-    }
-
-    @Override
-    public boolean isAccountNonExpired() {
-        return true;
-    }
-
-    @Override
-    public boolean isAccountNonLocked() {
-        return true;
-    }
-
-    @Override
-    public boolean isCredentialsNonExpired() {
-        return true;
-    }
-
-    @Override
-    public boolean isEnabled() {
-        return this.enabled;
-    }
-}
Index: serveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/model/domain/WorkingHour.java
===================================================================
--- ReserveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/model/domain/WorkingHour.java	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,19 +1,0 @@
-package mk.ukim.finki.it.reservengo.model.domain;
-
-import jakarta.persistence.*;
-import lombok.AllArgsConstructor;
-import lombok.Data;
-import lombok.NoArgsConstructor;
-
-import java.time.DayOfWeek;
-import java.time.LocalTime;
-
-@Embeddable
-@Data
-@AllArgsConstructor
-@NoArgsConstructor
-public class WorkingHour {
-    private DayOfWeek dayOfWeek;
-    private LocalTime openTime;
-    private LocalTime closeTime;
-}
Index: serveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/model/enumerations/EventStatus.java
===================================================================
--- ReserveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/model/enumerations/EventStatus.java	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,7 +1,0 @@
-package mk.ukim.finki.it.reservengo.model.enumerations;
-
-public enum EventStatus {
-    UPCOMING,
-    ACTIVE,
-    FINISHED
-}
Index: serveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/model/enumerations/EventType.java
===================================================================
--- ReserveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/model/enumerations/EventType.java	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,19 +1,0 @@
-package mk.ukim.finki.it.reservengo.model.enumerations;
-
-public enum EventType {
-    LIVE_MUSIC,
-    DJ_NIGHT,
-    FOOD_SPECIAL,
-    DRINK_SPECIAL,
-    HAPPY_HOUR,
-    SPORTS_SCREENING,
-    KARAOKE,
-    THEME_PARTY,
-    OPEN_MIC,
-    COOKING_WORKSHOP,
-    ART_EXHIBITION,
-    COMEDY_SHOW,
-    GAME_NIGHT,
-    PRIVATE_EVENT,
-    SEASONAL_EVENT
-}
Index: serveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/model/enumerations/LocalType.java
===================================================================
--- ReserveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/model/enumerations/LocalType.java	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,14 +1,0 @@
-package mk.ukim.finki.it.reservengo.model.enumerations;
-
-public enum LocalType {
-    RESTAURANT,
-    CAFE,
-    BAR,
-    PUB,
-    BISTRO,
-    FOOD_TRUCK,
-    BUFFET,
-    FAST_FOOD,
-    LOUNGE,
-    DELI
-}
Index: serveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/model/enumerations/Position.java
===================================================================
--- ReserveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/model/enumerations/Position.java	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,9 +1,0 @@
-package mk.ukim.finki.it.reservengo.model.enumerations;
-
-public enum Position {
-    CHEF,
-    COOK,
-    WAITER,
-    BARTENDER,
-    MANAGER
-}
Index: serveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/model/enumerations/ProvidedService.java
===================================================================
--- ReserveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/model/enumerations/ProvidedService.java	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,15 +1,0 @@
-package mk.ukim.finki.it.reservengo.model.enumerations;
-
-public enum ProvidedService {
-    WIFI,
-    PET_FRIENDLY,
-    PARKING,
-    OUTDOOR,
-    INDOOR,
-    PLAYGROUND,
-    VEGAN_FRIENDLY,
-    VEGETARIAN_FRIENDLY,
-    GLUTEN_FREE_FRIENDLY,
-    FAMILY_KIDS_FRIENDLY,
-    SMOKING_FRIENDLY
-}
Index: serveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/model/enumerations/Provider.java
===================================================================
--- ReserveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/model/enumerations/Provider.java	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,7 +1,0 @@
-package mk.ukim.finki.it.reservengo.model.enumerations;
-
-public enum Provider {
-    LOCAL,
-    GOOGLE,
-    FACEBOOK
-}
Index: serveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/model/enumerations/ReservationStatus.java
===================================================================
--- ReserveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/model/enumerations/ReservationStatus.java	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,9 +1,0 @@
-package mk.ukim.finki.it.reservengo.model.enumerations;
-
-public enum ReservationStatus {
-    EXPIRED,
-    PENDING,
-    ACCEPTED,
-    CANCELED,
-    FINISHED
-}
Index: serveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/model/enumerations/Role.java
===================================================================
--- ReserveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/model/enumerations/Role.java	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,8 +1,0 @@
-package mk.ukim.finki.it.reservengo.model.enumerations;
-
-public enum Role {
-    ROLE_ADMIN,
-    ROLE_CUSTOMER,
-    ROLE_LOCAL_MANAGER,
-    ROLE_LOCAL_WORKER
-}
Index: serveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/model/exceptions/CustomerIdNotFoundException.java
===================================================================
--- ReserveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/model/exceptions/CustomerIdNotFoundException.java	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,7 +1,0 @@
-package mk.ukim.finki.it.reservengo.model.exceptions;
-
-public class CustomerIdNotFoundException extends RuntimeException {
-    public CustomerIdNotFoundException(Long id) {
-        super("Customer with id: " + id + " not found.");
-    }
-}
Index: serveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/model/exceptions/EmailNotFoundException.java
===================================================================
--- ReserveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/model/exceptions/EmailNotFoundException.java	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,7 +1,0 @@
-package mk.ukim.finki.it.reservengo.model.exceptions;
-
-public class EmailNotFoundException extends RuntimeException {
-    public EmailNotFoundException(String email) {
-        super("User with email: " + email + " not found.");
-    }
-}
Index: serveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/model/exceptions/EventAlreadyFavouredException.java
===================================================================
--- ReserveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/model/exceptions/EventAlreadyFavouredException.java	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,7 +1,0 @@
-package mk.ukim.finki.it.reservengo.model.exceptions;
-
-public class EventAlreadyFavouredException extends RuntimeException {
-    public EventAlreadyFavouredException(Long id) {
-        super("Event with id: " + id + " already favoured.");
-    }
-}
Index: serveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/model/exceptions/EventAlreadyUnfavouredException.java
===================================================================
--- ReserveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/model/exceptions/EventAlreadyUnfavouredException.java	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,7 +1,0 @@
-package mk.ukim.finki.it.reservengo.model.exceptions;
-
-public class EventAlreadyUnfavouredException extends RuntimeException {
-    public EventAlreadyUnfavouredException(Long id) {
-        super("Event with id: " + id + " already unfavoured.");
-    }
-}
Index: serveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/model/exceptions/EventIdNotFoundException.java
===================================================================
--- ReserveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/model/exceptions/EventIdNotFoundException.java	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,7 +1,0 @@
-package mk.ukim.finki.it.reservengo.model.exceptions;
-
-public class EventIdNotFoundException extends RuntimeException {
-  public EventIdNotFoundException(Long id) {
-    super("Event with id: " + id + " not found.");
-  }
-}
Index: serveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/model/exceptions/EventNotInLocalException.java
===================================================================
--- ReserveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/model/exceptions/EventNotInLocalException.java	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,7 +1,0 @@
-package mk.ukim.finki.it.reservengo.model.exceptions;
-
-public class EventNotInLocalException extends RuntimeException {
-    public EventNotInLocalException(Long id) {
-        super("Event with id: " + id + " doesn't belong to local.");
-    }
-}
Index: serveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/model/exceptions/InvalidFileException.java
===================================================================
--- ReserveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/model/exceptions/InvalidFileException.java	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,7 +1,0 @@
-package mk.ukim.finki.it.reservengo.model.exceptions;
-
-public class InvalidFileException extends RuntimeException {
-    public InvalidFileException(String message) {
-        super(message);
-    }
-}
Index: serveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/model/exceptions/LocalAlreadyFavouredException.java
===================================================================
--- ReserveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/model/exceptions/LocalAlreadyFavouredException.java	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,7 +1,0 @@
-package mk.ukim.finki.it.reservengo.model.exceptions;
-
-public class LocalAlreadyFavouredException extends RuntimeException {
-    public LocalAlreadyFavouredException(Long id) {
-        super("Local with id: " + id + " already favoured.");
-    }
-}
Index: serveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/model/exceptions/LocalAlreadyUnfavouredException.java
===================================================================
--- ReserveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/model/exceptions/LocalAlreadyUnfavouredException.java	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,7 +1,0 @@
-package mk.ukim.finki.it.reservengo.model.exceptions;
-
-public class LocalAlreadyUnfavouredException extends RuntimeException {
-    public LocalAlreadyUnfavouredException(Long id) {
-        super("Local with id: " + id + " already unfavoured.");
-    }
-}
Index: serveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/model/exceptions/LocalIdNotFoundException.java
===================================================================
--- ReserveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/model/exceptions/LocalIdNotFoundException.java	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,7 +1,0 @@
-package mk.ukim.finki.it.reservengo.model.exceptions;
-
-public class LocalIdNotFoundException extends RuntimeException {
-    public LocalIdNotFoundException(Long id) {
-        super("Local with id: " + id + " not found.");
-    }
-}
Index: serveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/model/exceptions/LocalManagerIdNotFoundException.java
===================================================================
--- ReserveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/model/exceptions/LocalManagerIdNotFoundException.java	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,7 +1,0 @@
-package mk.ukim.finki.it.reservengo.model.exceptions;
-
-public class LocalManagerIdNotFoundException extends RuntimeException{
-    public LocalManagerIdNotFoundException(Long id) {
-        super("Manager with id: " + id + " not found.");
-    }
-}
Index: serveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/model/exceptions/ManagerAlreadyAssignedException.java
===================================================================
--- ReserveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/model/exceptions/ManagerAlreadyAssignedException.java	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,7 +1,0 @@
-package mk.ukim.finki.it.reservengo.model.exceptions;
-
-public class ManagerAlreadyAssignedException extends RuntimeException {
-    public ManagerAlreadyAssignedException(Long managerId, Long localId) {
-        super("Manager with id: " + managerId + " is already assigned to local with id: " + localId + ".");
-    }
-}
Index: serveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/model/exceptions/ManagerNotAssignedException.java
===================================================================
--- ReserveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/model/exceptions/ManagerNotAssignedException.java	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,7 +1,0 @@
-package mk.ukim.finki.it.reservengo.model.exceptions;
-
-public class ManagerNotAssignedException extends RuntimeException {
-    public ManagerNotAssignedException(Long id) {
-        super("Manager with id: " + id + " is not assigned to any local.");
-    }
-}
Index: serveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/model/exceptions/PhotoDeletionException.java
===================================================================
--- ReserveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/model/exceptions/PhotoDeletionException.java	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,7 +1,0 @@
-package mk.ukim.finki.it.reservengo.model.exceptions;
-
-public class PhotoDeletionException extends RuntimeException {
-    public PhotoDeletionException(String message) {
-        super(message);
-    }
-}
Index: serveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/model/exceptions/PhotoUploadException.java
===================================================================
--- ReserveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/model/exceptions/PhotoUploadException.java	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,7 +1,0 @@
-package mk.ukim.finki.it.reservengo.model.exceptions;
-
-public class PhotoUploadException extends RuntimeException {
-    public PhotoUploadException(String message) {
-        super(message);
-    }
-}
Index: serveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/model/exceptions/RatingNotFoundException.java
===================================================================
--- ReserveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/model/exceptions/RatingNotFoundException.java	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,7 +1,0 @@
-package mk.ukim.finki.it.reservengo.model.exceptions;
-
-public class RatingNotFoundException extends RuntimeException {
-    public RatingNotFoundException(Long customerId, Long localId) {
-        super("No rating found for local with id: " + localId + " from customer with id: " + customerId + ".");
-    }
-}
Index: serveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/model/exceptions/ReservationIdNotFoundException.java
===================================================================
--- ReserveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/model/exceptions/ReservationIdNotFoundException.java	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,7 +1,0 @@
-package mk.ukim.finki.it.reservengo.model.exceptions;
-
-public class ReservationIdNotFoundException extends RuntimeException {
-    public ReservationIdNotFoundException(Long id) {
-        super("Reservation with id: " + id + " not found.");
-    }
-}
Index: serveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/model/exceptions/TableIdNotFoundException.java
===================================================================
--- ReserveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/model/exceptions/TableIdNotFoundException.java	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,7 +1,0 @@
-package mk.ukim.finki.it.reservengo.model.exceptions;
-
-public class TableIdNotFoundException extends RuntimeException {
-    public TableIdNotFoundException(Long id) {
-        super("Table with id " + id + " not found");
-    }
-}
Index: serveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/model/exceptions/TableNotAvailableException.java
===================================================================
--- ReserveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/model/exceptions/TableNotAvailableException.java	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,9 +1,0 @@
-package mk.ukim.finki.it.reservengo.model.exceptions;
-
-import java.time.LocalDateTime;
-
-public class TableNotAvailableException extends RuntimeException {
-    public TableNotAvailableException(Long tableId, LocalDateTime time) {
-        super("Table with id " + tableId + " is not available at time " + time);
-    }
-}
Index: serveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/model/exceptions/UnauthorizedException.java
===================================================================
--- ReserveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/model/exceptions/UnauthorizedException.java	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,7 +1,0 @@
-package mk.ukim.finki.it.reservengo.model.exceptions;
-
-public class UnauthorizedException extends RuntimeException {
-    public UnauthorizedException(Long id) {
-        super("User with id " + id + " is not a worker");
-    }
-}
Index: serveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/model/exceptions/UnauthorizedReservationAccessException.java
===================================================================
--- ReserveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/model/exceptions/UnauthorizedReservationAccessException.java	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,7 +1,0 @@
-package mk.ukim.finki.it.reservengo.model.exceptions;
-
-public class UnauthorizedReservationAccessException extends RuntimeException {
-    public UnauthorizedReservationAccessException(Long customerId, Long reservationId) {
-        super("Customer with id " + customerId + " is not authorized to access reservation with id " + reservationId + ".");
-    }
-}
Index: serveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/model/exceptions/UserEmailAlreadyExistsException.java
===================================================================
--- ReserveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/model/exceptions/UserEmailAlreadyExistsException.java	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,7 +1,0 @@
-package mk.ukim.finki.it.reservengo.model.exceptions;
-
-public class UserEmailAlreadyExistsException extends RuntimeException {
-    public UserEmailAlreadyExistsException(String email) {
-        super("User with email: " + email + " already exists.");
-    }
-}
Index: serveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/model/exceptions/UserIdNotFoundException.java
===================================================================
--- ReserveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/model/exceptions/UserIdNotFoundException.java	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,7 +1,0 @@
-package mk.ukim.finki.it.reservengo.model.exceptions;
-
-public class UserIdNotFoundException extends RuntimeException {
-    public UserIdNotFoundException(Long id) {
-        super("User with id: " + id + " not found.");
-    }
-}
Index: serveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/model/exceptions/WorkerAlreadyAssignedException.java
===================================================================
--- ReserveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/model/exceptions/WorkerAlreadyAssignedException.java	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,7 +1,0 @@
-package mk.ukim.finki.it.reservengo.model.exceptions;
-
-public class WorkerAlreadyAssignedException extends RuntimeException {
-    public WorkerAlreadyAssignedException(Long workerId, Long localId) {
-        super("Worker with id: " + workerId + " is already assigned to local with id: " + localId + ".");
-    }
-}
Index: serveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/model/exceptions/WorkerIdNotFoundException.java
===================================================================
--- ReserveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/model/exceptions/WorkerIdNotFoundException.java	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,7 +1,0 @@
-package mk.ukim.finki.it.reservengo.model.exceptions;
-
-public class WorkerIdNotFoundException extends RuntimeException {
-    public WorkerIdNotFoundException(Long id) {
-        super("Worker with id: " + id + " not found.");
-    }
-}
Index: serveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/model/exceptions/WorkerNotAssignedException.java
===================================================================
--- ReserveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/model/exceptions/WorkerNotAssignedException.java	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,7 +1,0 @@
-package mk.ukim.finki.it.reservengo.model.exceptions;
-
-public class WorkerNotAssignedException extends RuntimeException {
-    public WorkerNotAssignedException(Long id) {
-        super("Worker with id: " + id + " is not assigned to any local.");
-    }
-}
Index: serveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/repository/AdminRepository.java
===================================================================
--- ReserveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/repository/AdminRepository.java	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,9 +1,0 @@
-package mk.ukim.finki.it.reservengo.repository;
-
-import mk.ukim.finki.it.reservengo.model.domain.Admin;
-import org.springframework.data.jpa.repository.JpaRepository;
-import org.springframework.stereotype.Repository;
-
-@Repository
-public interface AdminRepository extends JpaRepository<Admin, Long> {
-}
Index: serveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/repository/CustomerRepository.java
===================================================================
--- ReserveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/repository/CustomerRepository.java	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,12 +1,0 @@
-package mk.ukim.finki.it.reservengo.repository;
-
-import mk.ukim.finki.it.reservengo.model.domain.Customer;
-import org.springframework.data.jpa.repository.JpaRepository;
-import org.springframework.stereotype.Repository;
-
-import java.util.Optional;
-
-@Repository
-public interface CustomerRepository extends JpaRepository<Customer, Long> {
-    Optional<Customer> findByEmail(String email);
-}
Index: serveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/repository/EventRepository.java
===================================================================
--- ReserveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/repository/EventRepository.java	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,10 +1,0 @@
-package mk.ukim.finki.it.reservengo.repository;
-
-import mk.ukim.finki.it.reservengo.model.domain.Event;
-import org.springframework.data.jpa.repository.JpaRepository;
-import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
-import org.springframework.stereotype.Repository;
-
-@Repository
-public interface EventRepository extends JpaRepository<Event, Long>, JpaSpecificationExecutor<Event> {
-}
Index: serveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/repository/LocalManagerRepository.java
===================================================================
--- ReserveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/repository/LocalManagerRepository.java	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,12 +1,0 @@
-package mk.ukim.finki.it.reservengo.repository;
-
-import mk.ukim.finki.it.reservengo.model.domain.LocalManager;
-import org.springframework.data.jpa.repository.JpaRepository;
-import org.springframework.stereotype.Repository;
-
-import java.util.List;
-
-@Repository
-public interface LocalManagerRepository extends JpaRepository<LocalManager, Long> {
-    List<LocalManager> findByLocal_Id(Long localId);
-}
Index: serveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/repository/LocalRepository.java
===================================================================
--- ReserveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/repository/LocalRepository.java	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,11 +1,0 @@
-package mk.ukim.finki.it.reservengo.repository;
-
-import mk.ukim.finki.it.reservengo.model.domain.Local;
-import org.springframework.data.jpa.repository.JpaRepository;
-import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
-import org.springframework.stereotype.Repository;
-
-@Repository
-public interface LocalRepository extends JpaRepository<Local, Long>, JpaSpecificationExecutor<Local> {
-//    Local findById(Long id);
-}
Index: serveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/repository/LocalWorkerRepository.java
===================================================================
--- ReserveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/repository/LocalWorkerRepository.java	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,15 +1,0 @@
-package mk.ukim.finki.it.reservengo.repository;
-
-import mk.ukim.finki.it.reservengo.model.domain.LocalWorker;
-import org.springframework.data.jpa.repository.JpaRepository;
-import org.springframework.stereotype.Repository;
-
-import java.util.List;
-import java.util.Optional;
-
-@Repository
-public interface LocalWorkerRepository extends JpaRepository<LocalWorker, Long> {
-    Optional<LocalWorker> findByEmail(String email);
-
-    List<LocalWorker> findByLocal_Id(Long localId);
-}
Index: serveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/repository/ReservationRepository.java
===================================================================
--- ReserveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/repository/ReservationRepository.java	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,24 +1,0 @@
-package mk.ukim.finki.it.reservengo.repository;
-
-import mk.ukim.finki.it.reservengo.model.domain.Reservation;
-import mk.ukim.finki.it.reservengo.model.enumerations.ReservationStatus;
-import org.springframework.data.jpa.repository.JpaRepository;
-import org.springframework.data.jpa.repository.Modifying;
-import org.springframework.data.jpa.repository.Query;
-import org.springframework.data.repository.query.Param;
-import org.springframework.stereotype.Repository;
-
-import java.time.LocalDateTime;
-import java.util.List;
-
-@Repository
-public interface ReservationRepository extends JpaRepository<Reservation, Long> {
-
-    List<Reservation> findByLocalId(Long id);
-
-    List<Reservation> findByLocalIdAndStatus(Long id, ReservationStatus status);
-
-    @Modifying
-    @Query("UPDATE Reservation r SET r.status = 'EXPIRED' WHERE r.timeOfReservation < :now AND r.status NOT IN ('CANCELED', 'EXPIRED', 'FINISHED')")
-    void expireOldReservations(@Param("now") LocalDateTime now);
-}
Index: serveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/repository/UserRepository.java
===================================================================
--- ReserveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/repository/UserRepository.java	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,17 +1,0 @@
-package mk.ukim.finki.it.reservengo.repository;
-
-import mk.ukim.finki.it.reservengo.model.domain.User;
-import org.springframework.data.jpa.repository.JpaRepository;
-import org.springframework.stereotype.Repository;
-
-import java.time.LocalDateTime;
-import java.util.List;
-import java.util.Optional;
-
-@Repository
-public interface UserRepository extends JpaRepository<User, Long> {
-    Optional<User> findByEmail(String email);
-    List<User> findAllByEnabledFalseAndLastActivityDateBefore(LocalDateTime time);
-    List<User> findAllByEnabledTrueAndLastActivityDateBefore(LocalDateTime time);
-}
-
Index: serveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/service/impl/AdminServiceImpl.java
===================================================================
--- ReserveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/service/impl/AdminServiceImpl.java	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,88 +1,0 @@
-package mk.ukim.finki.it.reservengo.service.impl;
-
-import jakarta.mail.MessagingException;
-import mk.ukim.finki.it.reservengo.dto.adminDTO.DisplayAdminLocalsDTO;
-import mk.ukim.finki.it.reservengo.dto.localDTO.CreateLocalDTO;
-import mk.ukim.finki.it.reservengo.dto.userDTO.DisplayUserDTO;
-import mk.ukim.finki.it.reservengo.dto.userDTO.EditUserEmailDTO;
-import mk.ukim.finki.it.reservengo.model.domain.Local;
-import mk.ukim.finki.it.reservengo.model.domain.LocalManager;
-import mk.ukim.finki.it.reservengo.model.enumerations.Position;
-import mk.ukim.finki.it.reservengo.model.enumerations.Role;
-import mk.ukim.finki.it.reservengo.model.exceptions.ManagerAlreadyAssignedException;
-import mk.ukim.finki.it.reservengo.model.exceptions.ManagerNotAssignedException;
-import mk.ukim.finki.it.reservengo.service.intf.*;
-import org.springframework.stereotype.Service;
-
-import java.util.List;
-
-@Service
-public class AdminServiceImpl implements AdminService {
-
-    private final LocalService localService;
-    private final LocalManagerService localManagerService;
-    private final EmailService emailService;
-    private final JWTService jwtService;
-
-    public AdminServiceImpl(LocalService localService, LocalManagerService localManagerService, EmailService emailService, JWTService jwtService) {
-        this.localService = localService;
-        this.localManagerService = localManagerService;
-        this.emailService = emailService;
-        this.jwtService = jwtService;
-    }
-
-    @Override
-    public void addLocal(CreateLocalDTO localDTO) {
-        localService.save(localDTO.name());
-    }
-
-    @Override
-    public void deleteLocal(Long id) {
-        for (LocalManager manager : localManagerService.findAllByLocalId(id)) {
-            removeManagerFromLocal(manager.getId());
-        }
-        localService.delete(id);
-    }
-
-    @Override
-    public List<DisplayAdminLocalsDTO> getLocals() {
-        return DisplayAdminLocalsDTO.fromLocals(localService.listAll());
-    }
-
-    @Override
-    public List<DisplayUserDTO> findManagersByLocalId(Long localId) {
-        List<LocalManager> managers = localManagerService.findAllByLocalId(localId);
-        return DisplayUserDTO.fromUsers(managers);
-    }
-
-    @Override
-    public List<DisplayUserDTO> findUnassignedManagers() {
-        List<LocalManager> managers = localManagerService.findAllUnassigned();
-        return DisplayUserDTO.fromUsers(managers);
-    }
-
-    @Override
-    public void assignManagerToLocal(Long localId, Long managerId) {
-        LocalManager manager = localManagerService.findManagerById(managerId);
-        if (manager.getLocal() != null) {
-            throw new ManagerAlreadyAssignedException(manager.getId(), manager.getLocal().getId());
-        }
-        Local local = localService.findLocalById(localId);
-        localManagerService.updateLocalAssignment(manager, local, Position.MANAGER);
-    }
-
-    @Override
-    public void removeManagerFromLocal(Long managerId) {
-        LocalManager manager = localManagerService.findManagerById(managerId);
-        if (manager.getLocal() == null) {
-            throw new ManagerNotAssignedException(managerId);
-        }
-        localManagerService.updateLocalAssignment(manager, null, null);
-    }
-
-    @Override
-    public void inviteManager(EditUserEmailDTO emailDTO) throws MessagingException {
-        String token = jwtService.generateInviteToken(emailDTO.newEmail(), Role.ROLE_LOCAL_MANAGER);
-        emailService.sendManagerInvitationEmail(emailDTO.newEmail(), token);
-    }
-}
Index: serveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/service/impl/AuthServiceImpl.java
===================================================================
--- ReserveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/service/impl/AuthServiceImpl.java	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,335 +1,0 @@
-package mk.ukim.finki.it.reservengo.service.impl;
-
-import com.google.api.client.googleapis.auth.oauth2.GoogleIdToken;
-import com.google.api.client.googleapis.auth.oauth2.GoogleIdTokenVerifier;
-import com.google.common.base.VerifyException;
-import jakarta.mail.MessagingException;
-import mk.ukim.finki.it.reservengo.dto.jwtDTO.JWTAuthenticationRequestDTO;
-import mk.ukim.finki.it.reservengo.dto.jwtDTO.JWTAuthenticationResponseDTO;
-import mk.ukim.finki.it.reservengo.dto.jwtDTO.JWTLoginDTO;
-import mk.ukim.finki.it.reservengo.model.domain.Customer;
-import mk.ukim.finki.it.reservengo.model.domain.LocalManager;
-import mk.ukim.finki.it.reservengo.model.domain.LocalWorker;
-import mk.ukim.finki.it.reservengo.model.domain.User;
-import mk.ukim.finki.it.reservengo.model.enumerations.Provider;
-import mk.ukim.finki.it.reservengo.model.enumerations.Role;
-import mk.ukim.finki.it.reservengo.model.exceptions.EmailNotFoundException;
-import mk.ukim.finki.it.reservengo.repository.UserRepository;
-import mk.ukim.finki.it.reservengo.service.intf.*;
-import org.springframework.security.authentication.AuthenticationManager;
-import org.springframework.security.authentication.BadCredentialsException;
-import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
-import org.springframework.security.crypto.password.PasswordEncoder;
-import org.springframework.stereotype.Service;
-
-import java.io.IOException;
-import java.security.GeneralSecurityException;
-import java.time.LocalDateTime;
-import java.util.Random;
-import java.util.UUID;
-
-@Service
-public class AuthServiceImpl implements AuthService {
-    private final CustomerService customerService;
-    private final LocalWorkerService localWorkerService;
-    private final LocalManagerService localManagerService;
-    private final JWTService jwtService;
-    private final PasswordEncoder passwordEncoder;
-    private final AuthenticationManager authenticationManager;
-    private final UserRepository userRepository;
-    private final UserService userService;
-    private final EmailService emailService;
-    private final GoogleIdTokenVerifier googleIdTokenVerifier;
-
-    public AuthServiceImpl(CustomerService customerService, LocalWorkerService localWorkerService, LocalManagerService localManagerService, JWTService jwtService, PasswordEncoder passwordEncoder, AuthenticationManager authenticationManager, UserRepository userRepository, UserService userService, EmailService emailService, GoogleIdTokenVerifier googleIdTokenVerifier) {
-        this.customerService = customerService;
-        this.localWorkerService = localWorkerService;
-        this.localManagerService = localManagerService;
-        this.jwtService = jwtService;
-        this.passwordEncoder = passwordEncoder;
-        this.authenticationManager = authenticationManager;
-        this.userRepository = userRepository;
-        this.userService = userService;
-        this.emailService = emailService;
-        this.googleIdTokenVerifier = googleIdTokenVerifier;
-    }
-
-    @Override
-    public JWTAuthenticationResponseDTO registerCustomer(JWTAuthenticationRequestDTO jwtAuthenticationRequestDTO) throws MessagingException {
-        Customer customer = jwtAuthenticationRequestDTO.toCustomer(passwordEncoder.encode(jwtAuthenticationRequestDTO.password()), Provider.LOCAL, null);
-
-        String verificationCode = generateVerificationCode();
-        customer.setVerificationCode(verificationCode);
-        customer.setVerificationCodeExpiryDate(LocalDateTime.now().plusMinutes(30));
-        customer.setEnabled(false);
-
-        customerService.save(customer);
-
-        emailService.sendVerificationEmail(customer.getEmail(), verificationCode);
-
-        return JWTAuthenticationResponseDTO.fromUser(customer, null);
-    }
-
-    @Override
-    public JWTAuthenticationResponseDTO registerLocalWorker(JWTAuthenticationRequestDTO jwtAuthenticationRequestDTO, String token) {
-        validateTokenEmail(token, jwtAuthenticationRequestDTO.email());
-
-        LocalWorker localWorker = jwtAuthenticationRequestDTO.toLocalWorker(passwordEncoder.encode(jwtAuthenticationRequestDTO.password()), Provider.LOCAL, null);
-
-        localWorkerService.save(localWorker);
-        String jwt = jwtService.generateToken(localWorker);
-
-        return JWTAuthenticationResponseDTO.fromUser(localWorker, jwt);
-    }
-
-    @Override
-    public JWTAuthenticationResponseDTO registerLocalManager(JWTAuthenticationRequestDTO jwtAuthenticationRequestDTO, String token) {
-        validateTokenEmail(token, jwtAuthenticationRequestDTO.email());
-
-        LocalManager localManager = jwtAuthenticationRequestDTO.toLocalManager(passwordEncoder.encode(jwtAuthenticationRequestDTO.password()), Provider.LOCAL, null);
-
-        localManagerService.save(localManager);
-        String jwt = jwtService.generateToken(localManager);
-
-        return JWTAuthenticationResponseDTO.fromUser(localManager, jwt);
-    }
-
-    @Override
-    public JWTAuthenticationResponseDTO login(JWTLoginDTO jwtLoginDTO) throws MessagingException {
-        User user = userRepository.findByEmail(jwtLoginDTO.email()).orElseThrow(() -> new EmailNotFoundException(jwtLoginDTO.email()));
-
-        if (user.getProvider() != Provider.LOCAL) {
-            throw new MessagingException("This account must be logged in via " + user.getProvider() + ".");
-        }
-
-        if (!user.isEnabled() && user.getVerificationCodeExpiryDate() != null && user.getVerificationCode() != null) {
-            throw new MessagingException("Account not verified. Please verify your email.");
-        }
-
-        authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(jwtLoginDTO.email(), jwtLoginDTO.password()));
-        String jwt = jwtService.generateToken(user);
-
-        userService.updateUserActivity(user.getId());
-
-        return JWTAuthenticationResponseDTO.fromUser(user, jwt);
-    }
-
-    @Override
-    public void reactivateProfile(JWTLoginDTO jwtLoginDTO) {
-        User user = userService.findUserByEmail(jwtLoginDTO.email());
-
-        if (user == null) {
-            throw new EmailNotFoundException(jwtLoginDTO.email());
-        }
-
-        if (!passwordEncoder.matches(jwtLoginDTO.password(), user.getPassword())) {
-            throw new BadCredentialsException("Bad credentials.");
-        }
-
-        if (!user.isEnabled()) {
-            userService.enableProfile(user.getId());
-        }
-    }
-
-    @Override
-    public void verifyCustomer(String email, String verificationCode) throws MessagingException {
-        User user = userRepository.findByEmail(email).orElseThrow(() -> new EmailNotFoundException(email));
-
-        if (user.getVerificationCodeExpiryDate().isBefore(LocalDateTime.now())) {
-            throw new MessagingException("Verification code expired");
-        }
-
-        if (!user.getVerificationCode().equals(verificationCode.trim())) {
-            throw new MessagingException("Invalid verification code");
-        }
-
-        user.setEnabled(true);
-        user.setVerificationCode(null);
-        user.setVerificationCodeExpiryDate(null);
-
-        userRepository.save(user);
-    }
-
-    @Override
-    public void resendVerificationCode(String email) throws MessagingException {
-        User user = userRepository.findByEmail(email).orElseThrow(() -> new EmailNotFoundException(email));
-
-        if (user.isEnabled()) {
-            throw new MessagingException("Account already verified");
-        }
-
-        String newCode = generateVerificationCode();
-        user.setVerificationCode(newCode);
-        user.setVerificationCodeExpiryDate(LocalDateTime.now().plusMinutes(30));
-
-        try {
-            emailService.sendVerificationEmail(email, newCode);
-        } catch (MessagingException e) {
-            throw new MessagingException("Failed to send email", e);
-        }
-
-        userRepository.save(user);
-    }
-
-    @Override
-    public JWTAuthenticationResponseDTO registerGoogleCustomer(String idTokenString) {
-        GoogleIdToken.Payload payload = verifyGoogleIdTokenAndGetPayload(idTokenString);
-
-        String email = payload.getEmail();
-        String givenName = (String) payload.get("given_name");
-        String familyName = (String) payload.get("family_name");
-        String providerId = payload.getSubject();
-
-        return userRepository.findByEmail(email)
-                .map(user -> {
-                    String jwt = jwtService.generateToken(user);
-                    return JWTAuthenticationResponseDTO.fromUser(user, jwt);
-                })
-                .orElseGet(() -> {
-                    Customer customer = new Customer(
-                            givenName,
-                            familyName,
-                            email,
-                            passwordEncoder.encode(UUID.randomUUID().toString()),
-                            null,
-                            Role.ROLE_CUSTOMER,
-                            Provider.GOOGLE,
-                            providerId
-                    );
-                    customer.setEnabled(true);
-
-                    customerService.save(customer);
-
-                    String jwt = jwtService.generateToken(customer);
-                    return JWTAuthenticationResponseDTO.fromUser(customer, jwt);
-                });
-    }
-
-    @Override
-    public JWTAuthenticationResponseDTO registerGoogleLocalWorker(String idTokenString, String inviteToken) {
-        GoogleIdToken.Payload payload = verifyGoogleIdTokenAndGetPayload(idTokenString);
-
-        String email = payload.getEmail();
-        String givenName = (String) payload.get("given_name");
-        String familyName = (String) payload.get("family_name");
-        String providerId = payload.getSubject();
-
-        validateTokenEmail(inviteToken, email);
-
-        return userRepository.findByEmail(email)
-                .map(user -> {
-                    String jwt = jwtService.generateToken(user);
-                    return JWTAuthenticationResponseDTO.fromUser(user, jwt);
-                })
-                .orElseGet(() -> {
-                    LocalWorker localWorker = new LocalWorker(
-                            givenName,
-                            familyName,
-                            email,
-                            passwordEncoder.encode(UUID.randomUUID().toString()),
-                            null,
-                            Role.ROLE_LOCAL_WORKER,
-                            Provider.GOOGLE,
-                            providerId
-                    );
-                    localWorker.setEnabled(true);
-
-                    localWorkerService.save(localWorker);
-
-                    String jwt = jwtService.generateToken(localWorker);
-                    return JWTAuthenticationResponseDTO.fromUser(localWorker, jwt);
-                });
-    }
-
-    @Override
-    public JWTAuthenticationResponseDTO registerGoogleLocalManager(String idTokenString, String inviteToken) {
-        GoogleIdToken.Payload payload = verifyGoogleIdTokenAndGetPayload(idTokenString);
-
-        String email = payload.getEmail();
-        String givenName = (String) payload.get("given_name");
-        String familyName = (String) payload.get("family_name");
-        String providerId = payload.getSubject();
-
-        validateTokenEmail(inviteToken, email);
-
-        return userRepository.findByEmail(email)
-                .map(user -> {
-                    String jwt = jwtService.generateToken(user);
-                    return JWTAuthenticationResponseDTO.fromUser(user, jwt);
-                })
-                .orElseGet(() -> {
-                    LocalManager localManager = new LocalManager(
-                            givenName,
-                            familyName,
-                            email,
-                            passwordEncoder.encode(UUID.randomUUID().toString()),
-                            null,
-                            Role.ROLE_LOCAL_MANAGER,
-                            Provider.GOOGLE,
-                            providerId
-                    );
-                    localManager.setEnabled(true);
-
-                    localManagerService.save(localManager);
-
-                    String jwt = jwtService.generateToken(localManager);
-                    return JWTAuthenticationResponseDTO.fromUser(localManager, jwt);
-                });
-    }
-
-    @Override
-    public JWTAuthenticationResponseDTO loginWithGoogle(String idTokenString) {
-        GoogleIdToken.Payload payload = verifyGoogleIdTokenAndGetPayload(idTokenString);
-
-        String email = payload.getEmail();
-        User user = userRepository.findByEmail(email).orElseThrow(() -> new EmailNotFoundException(email));
-
-        if (!user.isEnabled()) {
-            throw new IllegalStateException("Account not enabled.");
-        }
-
-        String jwt = jwtService.generateToken(user);
-
-        userService.updateUserActivity(user.getId());
-
-        return JWTAuthenticationResponseDTO.fromUser(user, jwt);
-    }
-
-    private GoogleIdToken.Payload verifyGoogleIdTokenAndGetPayload(String idTokenString) {
-        if (idTokenString == null || idTokenString.isBlank()) {
-            throw new IllegalArgumentException("idToken is required");
-        }
-
-        GoogleIdToken idToken;
-        try {
-            idToken = googleIdTokenVerifier.verify(idTokenString);
-        } catch (GeneralSecurityException | IOException e) {
-            throw new VerifyException(e);
-        }
-
-        if (idToken == null) {
-            throw new IllegalArgumentException("Invalid Google ID token");
-        }
-
-        GoogleIdToken.Payload payload = idToken.getPayload();
-
-        Boolean emailVerified = (Boolean) payload.get("email_verified");
-        if (emailVerified != null && !emailVerified) {
-            throw new VerifyException("Google account email not verified");
-        }
-
-        return payload;
-    }
-
-    private void validateTokenEmail(String token, String email) {
-        String tokenEmail = jwtService.extractClaim(token, claims -> claims.get("email", String.class));
-        if (!tokenEmail.equals(email)) {
-            throw new IllegalArgumentException("Email must match the token's email");
-        }
-    }
-
-    private String generateVerificationCode() {
-        Random random = new Random();
-        return String.valueOf(random.nextInt(900000) + 100000);
-    }
-}
Index: serveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/service/impl/CustomerServiceImpl.java
===================================================================
--- ReserveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/service/impl/CustomerServiceImpl.java	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,207 +1,0 @@
-package mk.ukim.finki.it.reservengo.service.impl;
-
-import mk.ukim.finki.it.reservengo.dto.customerDTO.RatingDTO;
-import mk.ukim.finki.it.reservengo.dto.eventDTO.DisplayEventDTO;
-import mk.ukim.finki.it.reservengo.dto.localDTO.DisplayLocalDTO;
-import mk.ukim.finki.it.reservengo.dto.reservationDTO.*;
-import mk.ukim.finki.it.reservengo.model.domain.*;
-import mk.ukim.finki.it.reservengo.model.enumerations.ReservationStatus;
-import mk.ukim.finki.it.reservengo.model.exceptions.*;
-import mk.ukim.finki.it.reservengo.repository.CustomerRepository;
-import mk.ukim.finki.it.reservengo.repository.ReservationRepository;
-import mk.ukim.finki.it.reservengo.service.intf.*;
-import org.springframework.stereotype.Service;
-import org.springframework.transaction.annotation.Transactional;
-
-import java.util.List;
-
-@Service
-public class CustomerServiceImpl implements CustomerService {
-    private final CustomerRepository customerRepository;
-    private final LocalService localService;
-    private final UserService userService;
-    private final EventService eventService;
-    private final ReservationRepository reservationRepository;
-
-    public CustomerServiceImpl(CustomerRepository customerRepository, LocalService localService, UserService userService, EventService eventService, ReservationRepository reservationRepository) {
-        this.customerRepository = customerRepository;
-        this.localService = localService;
-        this.userService = userService;
-        this.eventService = eventService;
-        this.reservationRepository = reservationRepository;
-    }
-
-    @Override
-    public List<DisplayLocalDTO> listFavouriteLocals(Long id) {
-        Customer customer = customerRepository.findById(id).orElseThrow(() -> new CustomerIdNotFoundException(id));
-        return DisplayLocalDTO.fromLocals(customer.getFavouriteLocals());
-    }
-
-    @Override
-    public void addFavouriteLocal(Long userId, Long localId) {
-        Customer customer = customerRepository.findById(userId).orElseThrow(() -> new CustomerIdNotFoundException(userId));
-        Local local = localService.findLocalById(localId);
-
-        if (customer.getFavouriteLocals().contains(local)) {
-            throw new LocalAlreadyFavouredException(localId);
-        }
-
-        customer.getFavouriteLocals().add(local);
-        customerRepository.save(customer);
-    }
-
-    @Override
-    public void removeFavouriteLocal(Long userId, Long localId) {
-        Customer customer = customerRepository.findById(userId).orElseThrow(() -> new CustomerIdNotFoundException(userId));
-        Local local = localService.findLocalById(localId);
-
-        if (!customer.getFavouriteLocals().contains(local)) {
-            throw new LocalAlreadyUnfavouredException(localId);
-        }
-
-        customer.getFavouriteLocals().remove(local);
-        customerRepository.save(customer);
-    }
-
-    @Override
-    public void save(Customer customer) {
-        if (userService.emailExists(customer.getEmail())) {
-            throw new UserEmailAlreadyExistsException(customer.getEmail());
-        }
-        customerRepository.save(customer);
-    }
-
-    @Override
-    public List<DisplayEventDTO> listFavouriteEvents(Long id) {
-        Customer customer = customerRepository.findById(id).orElseThrow(() -> new CustomerIdNotFoundException(id));
-        return DisplayEventDTO.fromEvents(customer.getFavouriteEvents());
-    }
-
-    @Override
-    public void addFavouriteEvent(Long userId, Long eventId) {
-        Customer customer = customerRepository.findById(userId).orElseThrow(() -> new CustomerIdNotFoundException(userId));
-        Event event = eventService.findEventById(eventId);
-
-        if (customer.getFavouriteEvents().contains(event)) {
-            throw new EventAlreadyFavouredException(eventId);
-        }
-
-        customer.getFavouriteEvents().add(event);
-        customerRepository.save(customer);
-    }
-
-    @Override
-    public void removeFavouriteEvent(Long userId, Long eventId) {
-        Customer customer = customerRepository.findById(userId).orElseThrow(() -> new CustomerIdNotFoundException(userId));
-        Event event = eventService.findEventById(eventId);
-
-        if (!customer.getFavouriteEvents().contains(event)) {
-            throw new EventAlreadyUnfavouredException(eventId);
-        }
-
-        customer.getFavouriteEvents().remove(event);
-        customerRepository.save(customer);
-    }
-
-    @Override
-    public void rateLocal(Long customerId, Long localId, RatingDTO ratingDTO) {
-        customerRepository.findById(customerId).orElseThrow(() -> new CustomerIdNotFoundException(customerId));
-        localService.addRating(customerId, localId, ratingDTO.rating());
-    }
-
-    @Override
-    public void removeRating(Long customerId, Long localId) {
-        customerRepository.findById(customerId).orElseThrow(() -> new CustomerIdNotFoundException(customerId));
-        localService.removeRating(customerId, localId);
-    }
-
-    @Override
-    public int findLocalRating(Long customerId, Long localId) {
-        customerRepository.findById(customerId).orElseThrow(() -> new CustomerIdNotFoundException(customerId));
-        Local local = localService.findLocalById(localId);
-        if (!local.getRatings().containsKey(customerId) || local.getRatings().get(customerId) == null) {
-            throw new RatingNotFoundException(customerId, localId);
-        }
-        return local.getRatings().get(customerId);
-    }
-
-    @Override
-    public List<DisplayReservationDTO> listAllReservations(Long id) {
-        Customer customer = customerRepository.findById(id).orElseThrow(() -> new CustomerIdNotFoundException(id));
-        return DisplayReservationDTO.from(customer.getReservations());
-    }
-
-    @Override
-    public DisplayReservationDTO getReservationPreview(Long customerId, Long reservationId) {
-        Reservation reservation = reservationRepository.findById(reservationId).orElseThrow(() -> new ReservationIdNotFoundException(reservationId));
-
-        if (!reservation.getCustomer().getId().equals(customerId)) {
-            throw new UnauthorizedReservationAccessException(customerId, reservationId);
-        }
-
-        return DisplayReservationDTO.from(reservation);
-    }
-
-    @Override
-    @Transactional
-    public DisplayReservationDTO editReservation(Long id, Long reservationId, EditReservationDTO editReservationDTO) {
-        Reservation reservation = reservationRepository.findById(reservationId).orElseThrow(() -> new ReservationIdNotFoundException(reservationId));
-
-        if (!reservation.getCustomer().getId().equals(id)) {
-            throw new UnauthorizedReservationAccessException(id, reservationId);
-        }
-
-        reservation.setTimeOfReservation(editReservationDTO.timeOfReservation());
-
-        reservation.getTable().setCapacity(editReservationDTO.capacity());
-        reservation.getTable().setDescription(editReservationDTO.description());
-        reservationRepository.save(reservation);
-
-        return DisplayReservationDTO.from(reservation);
-    }
-
-    @Override
-    public void cancelReservation(Long id, Long reservationId) {
-        Reservation reservation = reservationRepository.findById(reservationId).orElseThrow(() -> new ReservationIdNotFoundException(reservationId));
-
-        if (!reservation.getCustomer().getId().equals(id)) {
-            throw new UnauthorizedReservationAccessException(id, reservationId);
-        }
-
-        reservation.setStatus(ReservationStatus.CANCELED);
-        reservationRepository.save(reservation);
-    }
-
-    @Override
-    @Transactional
-    public void makeReservation(Long id, Long localId, CreateReservationDTO createReservationDTO) {
-        Customer customer = customerRepository.findById(id).orElseThrow(() -> new CustomerIdNotFoundException(id));
-        Local local = localService.findLocalById(localId);
-
-        DiningTable diningTable = new DiningTable(createReservationDTO.capacity(), createReservationDTO.description());
-
-        Reservation reservation = new Reservation();
-        reservation.setCustomer(customer);
-        reservation.setLocal(local);
-        reservation.setTimeOfReservation(createReservationDTO.timeOfReservation());
-        reservation.setTable(diningTable);
-        reservation.setStatus(ReservationStatus.PENDING);
-
-        reservationRepository.save(reservation);
-    }
-
-    @Override
-    public void deleteReservation(Long id, DeleteReservationDTO deleteReservationDTO) {
-        Customer customer = customerRepository.findById(id).orElseThrow(() -> new CustomerIdNotFoundException(id));
-        List<Reservation> reservations = reservationRepository.findAllById(deleteReservationDTO.reservationIds());
-
-        for (Reservation reservation : reservations) {
-            reservation.setStatus(ReservationStatus.CANCELED);
-            reservation.setCustomer(null);
-            customer.getReservations().remove(reservation);
-            reservationRepository.save(reservation);
-        }
-
-        customerRepository.save(customer);
-    }
-}
Index: serveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/service/impl/EmailServiceImpl.java
===================================================================
--- ReserveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/service/impl/EmailServiceImpl.java	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,139 +1,0 @@
-package mk.ukim.finki.it.reservengo.service.impl;
-
-import jakarta.mail.MessagingException;
-import jakarta.mail.internet.MimeMessage;
-import mk.ukim.finki.it.reservengo.model.enumerations.ReservationStatus;
-import mk.ukim.finki.it.reservengo.service.intf.EmailService;
-import org.springframework.beans.factory.annotation.Value;
-import org.springframework.mail.javamail.JavaMailSender;
-import org.springframework.mail.javamail.MimeMessageHelper;
-import org.springframework.stereotype.Service;
-
-@Service
-public class EmailServiceImpl implements EmailService {
-    private final JavaMailSender mailSender;
-    private final String frontEndUrl;
-
-    public EmailServiceImpl(@Value("${frontend.url}") String frontEndUrl, JavaMailSender mailSender) {
-        this.frontEndUrl = frontEndUrl;
-        this.mailSender = mailSender;
-    }
-
-    @Override
-    public void sendManagerInvitationEmail(String email, String token) throws MessagingException {
-        String invitationUrl = frontEndUrl + "/register/manager?token=" + token;
-
-        String html = """
-                <div style="font-family: Arial, sans-serif; font-size: 15px; color: #333;">
-                    <h2>Manager Invitation</h2>
-                    <p>You have been invited to become a manager.</p>
-                    <p>Click the button below to complete your registration:</p>
-                    <a href="%s" style="
-                        background-color: #4CAF50;
-                        color: white;
-                        padding: 10px 20px;
-                        text-decoration: none;
-                        border-radius: 5px;
-                        display: inline-block;
-                    ">Complete Registration</a>
-                    <p style="margin-top: 20px;">This link will expire in 24 hours.</p>
-                </div>
-                """.formatted(invitationUrl);
-
-        sendHtmlEmail(email, "Manager Invitation", html);
-    }
-
-    @Override
-    public void sendWorkerInvitationEmail(String email, String token, String managerEmail, String localName) throws MessagingException {
-        String invitationUrl = frontEndUrl + "/register/worker?token=" + token;
-
-        String html = """
-                <div style="font-family: Arial, sans-serif; font-size: 15px; color: #333;">
-                    <h2>Worker Invitation</h2>
-                    <p>You have been invited to become a worker at <b>%s</b>.</p>
-                    <p>Invited by manager: <b>%s</b></p>
-                    <p>Click the button below to complete your registration:</p>
-                    <a href="%s" style="
-                        background-color: #2196F3;
-                        color: white;
-                        padding: 10px 20px;
-                        text-decoration: none;
-                        border-radius: 5px;
-                        display: inline-block;
-                    ">Complete Registration</a>
-                    <p style="margin-top: 20px;">This link will expire in 24 hours.</p>
-                </div>
-                """.formatted(localName, managerEmail, invitationUrl);
-
-        sendHtmlEmail(email, "Worker Invitation", html);
-    }
-
-    @Override
-    public void sendVerificationEmail(String email, String verificationCode) throws MessagingException {
-        String verificationUrl = frontEndUrl + "/register?code=" + verificationCode;
-
-        String html = """
-                <div style="font-family: Arial, sans-serif; font-size: 15px; color: #333;">
-                    <h2>Email Verification</h2>
-                    <p>Please verify your email address by clicking the button below:</p>
-                    <a href="%s" style="
-                        background-color: #FF9800;
-                        color: white;
-                        padding: 10px 20px;
-                        text-decoration: none;
-                        border-radius: 5px;
-                        display: inline-block;
-                    ">Verify Email</a>
-                    <p style="margin-top: 20px;">
-                        Or use this verification code:
-                        <strong style="font-size: 18px; color: #FF9800;">%s</strong>
-                    </p>
-                    <p style="margin-top: 20px;">If you did not request this, you can ignore this email.</p>
-                </div>
-                """.formatted(verificationUrl, verificationCode);
-
-        sendHtmlEmail(email, "Account verification", html);
-    }
-
-    @Override
-    public void sendReservationFeedbackEmail(String email, ReservationStatus status) throws MessagingException {
-
-        boolean accepted = status == ReservationStatus.ACCEPTED;
-
-        String title = accepted ? "Reservation Confirmed ✅" : "Reservation Declined ❌";
-        String color = accepted ? "#4CAF50" : "#F44336";
-        String message = accepted
-                ? "Your reservation has been <b>successfully accepted</b>."
-                : "Unfortunately, your reservation has been <b>declined</b>.";
-
-        String html = """
-                <div style="font-family: Arial, sans-serif; font-size: 15px; color: #333;">
-                    <h2 style="color: %s;">%s</h2>
-                    <p>%s</p>
-                
-                    <p style="margin-top: 25px; font-size: 13px; color: #777;">
-                        Thank you for using ReserveNGo.
-                    </p>
-                </div>
-                """
-                .formatted(color, title, message);
-
-        sendHtmlEmail(email, "Reservation Status Update", html);
-    }
-
-
-    private void sendHtmlEmail(String to, String subject, String text) throws MessagingException {
-        try {
-            MimeMessage message = mailSender.createMimeMessage();
-            MimeMessageHelper helper = new MimeMessageHelper(message, true, "UTF-8");
-
-            helper.setTo(to);
-            helper.setSubject(subject);
-            helper.setText(text, true);
-
-            mailSender.send(message);
-        } catch (MessagingException e) {
-            throw new MessagingException("Failed to send email", e);
-        }
-    }
-}
Index: serveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/service/impl/EventServiceImpl.java
===================================================================
--- ReserveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/service/impl/EventServiceImpl.java	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,89 +1,0 @@
-package mk.ukim.finki.it.reservengo.service.impl;
-
-import mk.ukim.finki.it.reservengo.dto.eventDTO.DisplayEventDTO;
-import mk.ukim.finki.it.reservengo.model.domain.Event;
-import mk.ukim.finki.it.reservengo.model.domain.Local;
-import mk.ukim.finki.it.reservengo.model.enumerations.EventStatus;
-import mk.ukim.finki.it.reservengo.model.enumerations.EventType;
-import mk.ukim.finki.it.reservengo.model.exceptions.EventIdNotFoundException;
-import mk.ukim.finki.it.reservengo.repository.EventRepository;
-import mk.ukim.finki.it.reservengo.service.intf.EventService;
-import org.springframework.data.domain.*;
-import org.springframework.data.jpa.domain.Specification;
-import org.springframework.stereotype.Service;
-
-import java.util.List;
-
-@Service
-public class EventServiceImpl implements EventService {
-    private final EventRepository eventRepository;
-
-    public EventServiceImpl(EventRepository eventRepository) {
-        this.eventRepository = eventRepository;
-    }
-
-    @Override
-    public Page<DisplayEventDTO> searchEvents(Local local, String name, EventType eventType, EventStatus eventStatus, int page, int size, String sortBy, String direction) {
-        boolean needsManualProcessing;
-        needsManualProcessing = eventStatus != null;
-
-        Specification<Event> spec = Specification.where(null);
-
-        if (local != null) {
-            spec = spec.and((root, query, cb) ->
-                    cb.equal(root.get("local"), local));
-        }
-
-        if (name != null && !name.trim().isEmpty()) {
-            spec = spec.and((root, query, cb) ->
-                    cb.like(cb.lower(root.get("name")), "%" + name.toLowerCase() + "%"));
-        }
-
-        if (eventType != null) {
-            spec = spec.and((root, query, cb) ->
-                    cb.equal(root.get("eventType"), eventType));
-        }
-
-        Pageable pageable = needsManualProcessing
-                ? Pageable.unpaged()
-                : PageRequest.of(page, size, getSort(sortBy, direction));
-
-        Page<Event> eventsPage = eventRepository.findAll(spec, pageable);
-
-        // Manual status filtering
-        if (needsManualProcessing) {
-            List<DisplayEventDTO> filtered = eventsPage.getContent().stream()
-                    .filter(event -> event.getStatus() == eventStatus)
-                    .map(DisplayEventDTO::fromEvent)
-                    .toList();
-
-            int total = filtered.size();
-            int start = Math.min(page * size, total);
-            int end = Math.min(start + size, total);
-            List<DisplayEventDTO> paged = filtered.subList(start, end);
-
-            return new PageImpl<>(paged, PageRequest.of(page, size), total);
-        }
-
-        return eventsPage.map(DisplayEventDTO::fromEvent);
-    }
-
-    @Override
-    public Event findEventById(Long id) {
-        return eventRepository.findById(id).orElseThrow(() -> new EventIdNotFoundException(id));
-    }
-
-    @Override
-    public Event save(Event event) {
-        return eventRepository.save(event);
-    }
-
-    private Sort getSort(String sortBy, String direction) {
-        Sort.Direction sortDirection = "desc".equalsIgnoreCase(direction) ? Sort.Direction.DESC : Sort.Direction.ASC;
-
-        return switch (sortBy) {
-            case "createdAt" -> Sort.by(sortDirection, "createdAt");
-            default -> Sort.by(sortDirection, "name");
-        };
-    }
-}
Index: serveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/service/impl/FileStorageServiceImpl.java
===================================================================
--- ReserveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/service/impl/FileStorageServiceImpl.java	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,124 +1,0 @@
-package mk.ukim.finki.it.reservengo.service.impl;
-
-import mk.ukim.finki.it.reservengo.model.exceptions.InvalidFileException;
-import mk.ukim.finki.it.reservengo.model.exceptions.PhotoDeletionException;
-import mk.ukim.finki.it.reservengo.model.exceptions.PhotoUploadException;
-import mk.ukim.finki.it.reservengo.service.intf.FileStorageService;
-import org.springframework.stereotype.Service;
-import org.springframework.transaction.annotation.Transactional;
-import org.springframework.web.multipart.MultipartFile;
-
-import java.io.IOException;
-import java.nio.file.*;
-import java.util.Objects;
-import java.util.Set;
-import java.util.UUID;
-
-@Service
-@Transactional
-public class FileStorageServiceImpl implements FileStorageService {
-
-    private final Path rootUploadsDir = Paths.get("uploads");
-    private final Path logosDir = rootUploadsDir.resolve("logos");
-    private final Path localsDir = rootUploadsDir.resolve("locals");
-    private final Path profilesDir = rootUploadsDir.resolve("profiles");
-    private static final Set<String> ALLOWED_EXTENSIONS = Set.of("jpg", "jpeg", "png");
-    private static final Set<String> ALLOWED_CONTENT_TYPES = Set.of("image/jpeg", "image/png");
-    private static final long MAX_FILE_SIZE = 5 * 1024 * 1024; // 5MB
-
-    public FileStorageServiceImpl() throws IOException {
-        try {
-            createIfNotExists(rootUploadsDir);
-            createIfNotExists(logosDir);
-            createIfNotExists(localsDir);
-            createIfNotExists(profilesDir);
-        } catch (IOException e) {
-            throw new FileSystemException("Could not initialize storage directories");
-        }
-    }
-
-    private void createIfNotExists(Path dir) throws IOException {
-        if (!Files.exists(dir)) {
-            Files.createDirectories(dir);
-        }
-    }
-
-    @Override
-    public String saveLogoFile(MultipartFile file) {
-        return savePhotoFile(file, logosDir, "/uploads/logos/");
-    }
-
-    @Override
-    public String saveProfilePhotoFile(MultipartFile file) {
-        return savePhotoFile(file, profilesDir, "/uploads/profiles/");
-    }
-
-    @Override
-    public String savePhotoFile(MultipartFile file) {
-        return savePhotoFile(file, localsDir, "/uploads/locals/");
-    }
-
-    @Override
-    public void deletePhotoFile(String filePath) {
-        if (filePath == null || filePath.trim().isEmpty()) {
-            return;
-        }
-        try {
-            String normalizedPath = filePath.replaceFirst("^/uploads/?", "");
-            Path fullPath = rootUploadsDir.resolve(normalizedPath).normalize();
-            Files.deleteIfExists(fullPath);
-        } catch (IOException e) {
-            throw new PhotoDeletionException("Failed to delete photo.");
-        }
-    }
-
-    @Override
-    public void validateFile(MultipartFile file) {
-        if (file == null || file.isEmpty()) {
-            throw new InvalidFileException("Photo file cannot be empty");
-        }
-
-        if (file.getSize() > MAX_FILE_SIZE) {
-            throw new InvalidFileException("Photo file size exceeds maximum allowed size of 5MB");
-        }
-
-        String contentType = file.getContentType();
-        if (contentType == null || !ALLOWED_CONTENT_TYPES.contains(contentType.toLowerCase())) {
-            throw new InvalidFileException("Invalid file type. Only:" + ALLOWED_CONTENT_TYPES + " are allowed.");
-        }
-
-        String originalFilename = file.getOriginalFilename();
-        if (originalFilename == null || originalFilename.trim().isEmpty()) {
-            throw new InvalidFileException("Invalid filename");
-        }
-
-        String fileExtension = getFileExtension(originalFilename).toLowerCase();
-        if (!ALLOWED_EXTENSIONS.contains(fileExtension)) {
-            throw new InvalidFileException("File extension not allowed: " + fileExtension);
-        }
-    }
-
-    private String generateUniqueFileName(String extension) {
-        return UUID.randomUUID() + "." + extension;
-    }
-
-    private String getFileExtension(String filename) {
-        int lastDotIndex = filename.lastIndexOf('.');
-        return lastDotIndex > 0 ? filename.substring(lastDotIndex + 1) : "";
-    }
-
-    private String savePhotoFile(MultipartFile file, Path targetDir, String webPathPrefix) {
-        validateFile(file);
-        String originalFilename = file.getOriginalFilename();
-        String fileExtension = getFileExtension(Objects.requireNonNull(originalFilename)).toLowerCase();
-
-        try {
-            String fileName = generateUniqueFileName(fileExtension);
-            Path targetPath = targetDir.resolve(fileName);
-            Files.copy(file.getInputStream(), targetPath, StandardCopyOption.REPLACE_EXISTING);
-            return webPathPrefix + fileName;
-        } catch (IOException e) {
-            throw new PhotoUploadException("Failed to upload photo.");
-        }
-    }
-}
Index: serveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/service/impl/JWTServiceImpl.java
===================================================================
--- ReserveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/service/impl/JWTServiceImpl.java	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,86 +1,0 @@
-package mk.ukim.finki.it.reservengo.service.impl;
-
-import io.jsonwebtoken.Claims;
-import io.jsonwebtoken.Jwts;
-import io.jsonwebtoken.SignatureAlgorithm;
-import io.jsonwebtoken.io.Decoders;
-import io.jsonwebtoken.security.Keys;
-import mk.ukim.finki.it.reservengo.constants.JWTConstants;
-import mk.ukim.finki.it.reservengo.model.domain.User;
-import mk.ukim.finki.it.reservengo.model.enumerations.Role;
-import mk.ukim.finki.it.reservengo.service.intf.JWTService;
-import org.springframework.security.core.userdetails.UserDetails;
-import org.springframework.stereotype.Service;
-
-import java.security.Key;
-import java.util.Date;
-import java.util.function.Function;
-
-@Service
-public class JWTServiceImpl implements JWTService {
-    @Override
-    public String extractUsername(String token) {
-        return extractClaim(token, Claims::getSubject);
-    }
-
-    @Override
-    public Claims extractAllClaims(String token) {
-        return Jwts
-                .parserBuilder()
-                .setSigningKey(getSignInKey())
-                .build()
-                .parseClaimsJws(token)
-                .getBody();
-    }
-
-    @Override
-    public Key getSignInKey() {
-        byte[] keyBytes = Decoders.BASE64.decode(JWTConstants.SECRET_KEY);
-        return Keys.hmacShaKeyFor(keyBytes);
-    }
-
-    @Override
-    public <T> T extractClaim(String token, Function<Claims, T> claimsResolver) {
-        final Claims claims = extractAllClaims(token);
-        return claimsResolver.apply(claims);
-    }
-
-    @Override
-    public String generateToken(User user) {
-        return Jwts.builder()
-                .setSubject(user.getUsername())
-                .claim("role", user.getUserRole())
-                .claim("id", user.getId())
-                .setIssuedAt(new Date())
-                .setExpiration(new Date(System.currentTimeMillis() + JWTConstants.EXPIRATION_TIME))
-                .signWith(getSignInKey(), SignatureAlgorithm.HS256)
-                .compact();
-    }
-
-    @Override
-    public boolean isTokenValid(String token, UserDetails userDetails) {
-        final String username = extractUsername(token);
-        return (username.equals(userDetails.getUsername())) && !isTokenExpired(token);
-    }
-
-    @Override
-    public boolean isTokenExpired(String token) {
-        return extractExpiration(token).before(new Date());
-    }
-
-    @Override
-    public Date extractExpiration(String token) {
-        return extractClaim(token, Claims::getExpiration);
-    }
-
-    @Override
-    public String generateInviteToken(String email, Role role) {
-        return Jwts.builder()
-                .claim("email", email)
-                .claim("role", role)
-                .setIssuedAt(new Date())
-                .setExpiration(new Date(System.currentTimeMillis() + JWTConstants.EXPIRATION_TIME))
-                .signWith(getSignInKey(), SignatureAlgorithm.HS256)
-                .compact();
-    }
-}
Index: serveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/service/impl/LocalManagerServiceImpl.java
===================================================================
--- ReserveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/service/impl/LocalManagerServiceImpl.java	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,213 +1,0 @@
-package mk.ukim.finki.it.reservengo.service.impl;
-
-import jakarta.mail.MessagingException;
-import mk.ukim.finki.it.reservengo.dto.eventDTO.CreateEventDTO;
-import mk.ukim.finki.it.reservengo.dto.localDTO.CreateLocalDetailsDTO;
-import mk.ukim.finki.it.reservengo.dto.localDTO.DeleteLocalPhotosDTO;
-import mk.ukim.finki.it.reservengo.dto.localDTO.DeleteLocalPhotosResultDTO;
-import mk.ukim.finki.it.reservengo.dto.userDTO.EditUserEmailDTO;
-import mk.ukim.finki.it.reservengo.dto.workerDTO.PositionDTO;
-import mk.ukim.finki.it.reservengo.model.domain.Event;
-import mk.ukim.finki.it.reservengo.model.domain.Local;
-import mk.ukim.finki.it.reservengo.model.domain.LocalManager;
-import mk.ukim.finki.it.reservengo.model.domain.LocalWorker;
-import mk.ukim.finki.it.reservengo.model.enumerations.Position;
-import mk.ukim.finki.it.reservengo.model.enumerations.Role;
-import mk.ukim.finki.it.reservengo.model.exceptions.*;
-import mk.ukim.finki.it.reservengo.repository.LocalManagerRepository;
-import mk.ukim.finki.it.reservengo.service.intf.*;
-import org.springframework.security.access.AccessDeniedException;
-import org.springframework.stereotype.Service;
-import org.springframework.web.multipart.MultipartFile;
-
-import java.util.List;
-import java.util.stream.Collectors;
-
-@Service
-public class LocalManagerServiceImpl implements LocalManagerService {
-
-    private final LocalService localService;
-    private final LocalManagerRepository localManagerRepository;
-    private final UserService userService;
-    private final EventService eventService;
-    private final LocalWorkerService workerService;
-    private final JWTService jwtService;
-    private final EmailService emailService;
-
-    public LocalManagerServiceImpl(LocalService localService, LocalManagerRepository localManagerRepository, UserService userService, EventService eventService, LocalWorkerService workerService, JWTService jwtService, EmailService emailService) {
-        this.localService = localService;
-        this.localManagerRepository = localManagerRepository;
-        this.userService = userService;
-        this.eventService = eventService;
-        this.workerService = workerService;
-        this.jwtService = jwtService;
-        this.emailService = emailService;
-    }
-
-    @Override
-    public void save(LocalManager localManager) {
-        if (userService.emailExists(localManager.getEmail())) {
-            throw new UserEmailAlreadyExistsException(localManager.getEmail());
-        }
-        localManagerRepository.save(localManager);
-    }
-
-    public List<LocalManager> findAllByLocalId(Long localId) {
-        return localManagerRepository.findByLocal_Id(localId);
-    }
-
-    @Override
-    public LocalManager findManagerById(Long id) {
-        return localManagerRepository.findById(id).orElseThrow(() -> new LocalManagerIdNotFoundException(id));
-    }
-
-    @Override
-    public List<LocalManager> findAllUnassigned() {
-        return localManagerRepository.findAll().stream()
-                .filter(manager -> manager.getLocal() == null)
-                .filter(manager -> manager.getPosition() == null)
-                .collect(Collectors.toList());
-    }
-
-    @Override
-    public void updateLocalAssignment(LocalManager manager, Local local, Position position) {
-        manager.setLocal(local);
-        manager.setPosition(position);
-
-        localManagerRepository.save(manager);
-    }
-
-    @Override
-    public Local findLocalByManagerId(Long id) {
-        LocalManager localManager = localManagerRepository.findById(id).orElseThrow(() -> new LocalManagerIdNotFoundException(id));
-        if (localManager.getLocal() == null) {
-            throw new ManagerNotAssignedException(id);
-        }
-        return localManager.getLocal();
-    }
-
-    @Override
-    public Local editLocal(Long managerId, CreateLocalDetailsDTO createLocalDetailsDTO) {
-        LocalManager manager = localManagerRepository.findById(managerId).orElseThrow(() -> new LocalManagerIdNotFoundException(managerId));
-        if (manager.getLocal() == null) {
-            throw new ManagerNotAssignedException(manager.getId());
-        }
-        return localService.edit(manager.getLocal().getId(), createLocalDetailsDTO);
-    }
-
-    @Override
-    public String uploadLocalLogo(Long managerId, MultipartFile logoFile) {
-        Local local = findLocalByManagerId(managerId);
-
-        return localService.addLogo(local.getId(), logoFile);
-    }
-
-    @Override
-    public void deleteLocalLogo(Long managerId) {
-        Local local = findLocalByManagerId(managerId);
-
-        localService.deleteLogo(local.getId());
-    }
-
-    @Override
-    public String uploadLocalPhoto(Long managerId, MultipartFile photoFile) {
-        Local local = findLocalByManagerId(managerId);
-
-        return localService.addPhoto(local.getId(), photoFile);
-    }
-
-    @Override
-    public DeleteLocalPhotosResultDTO deleteLocalPhoto(Long managerId, DeleteLocalPhotosDTO deleteLocalPhotosDTO) {
-        Local local = findLocalByManagerId(managerId);
-
-        return localService.deletePhotos(local.getId(), deleteLocalPhotosDTO.localPhotosUrls());
-    }
-
-    @Override
-    public void addEvent(Long managerId, CreateEventDTO createEventDTO) {
-        Local local = findLocalByManagerId(managerId);
-        Event event = createEventDTO.toEvent(local);
-
-        localService.addEvent(local, event);
-    }
-
-    @Override
-    public void deleteEvent(Long managerId, Long eventId) {
-        Local local = findLocalByManagerId(managerId);
-        Event event = eventService.findEventById(eventId);
-
-        if (!event.getLocal().getId().equals(local.getId())) {
-            throw new EventNotInLocalException(eventId);
-        }
-
-        localService.deleteEvent(local, event);
-    }
-
-    @Override
-    public Event editEvent(Long managerId, Long eventId, CreateEventDTO createEventDTO) {
-        Local local = findLocalByManagerId(managerId);
-        Event event = eventService.findEventById(eventId);
-
-        if (!event.getLocal().getId().equals(local.getId())) {
-            throw new EventNotInLocalException(eventId);
-        }
-
-        return localService.editEvent(local, event, createEventDTO);
-    }
-
-    @Override
-    public List<LocalWorker> findWorkersByLocal(Local local) {
-        return workerService.findAllByLocalId(local.getId());
-    }
-
-    @Override
-    public List<LocalWorker> findUnassignedWorkers() {
-        return workerService.findAllUnassigned();
-    }
-
-    @Override
-    public void assignWorkerToLocal(Local local, Long workerId) {
-        LocalWorker worker = workerService.findWorkerById(workerId);
-        if (worker.getLocal() != null) {
-            throw new WorkerAlreadyAssignedException(worker.getId(), worker.getLocal().getId());
-        }
-        workerService.updateLocalAssignment(worker, local);
-    }
-
-    @Override
-    public void removeWorkerFromLocal(Long managerId, Long workerId) {
-        LocalWorker worker = workerService.findWorkerById(workerId);
-        if (worker.getLocal() == null) {
-            throw new WorkerNotAssignedException(workerId);
-        }
-        LocalManager manager = findManagerById(managerId);
-        if (!worker.getLocal().getId().equals(manager.getLocal().getId())) {
-            throw new AccessDeniedException("You are not allowed to remove a worker that is not assigned to your local!");
-        }
-        workerService.updateLocalAssignment(worker, null);
-    }
-
-    @Override
-    public void changePosition(Long managerId, Long workerId, PositionDTO positionDTO) {
-        LocalWorker worker = workerService.findWorkerById(workerId);
-        if (worker.getLocal() == null) {
-            throw new WorkerNotAssignedException(workerId);
-        }
-        LocalManager manager = findManagerById(managerId);
-        if (!worker.getLocal().getId().equals(manager.getLocal().getId())) {
-            throw new AccessDeniedException("You are not allowed to change the position of a worker that is not assigned to your local!");
-        }
-        workerService.changePosition(worker, positionDTO.position());
-    }
-
-    @Override
-    public void inviteWorker(Long managerId, EditUserEmailDTO emailDTO) throws MessagingException {
-        LocalManager manager = localManagerRepository.findById(managerId).orElseThrow(() -> new LocalManagerIdNotFoundException(managerId));
-        if (manager.getLocal() == null) {
-            throw new ManagerNotAssignedException(managerId);
-        }
-
-        String token = jwtService.generateInviteToken(emailDTO.newEmail(), Role.ROLE_LOCAL_WORKER);
-        emailService.sendWorkerInvitationEmail(emailDTO.newEmail(), token, manager.getEmail(), manager.getLocal().getName());
-    }
-}
Index: serveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/service/impl/LocalServiceImpl.java
===================================================================
--- ReserveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/service/impl/LocalServiceImpl.java	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,282 +1,0 @@
-package mk.ukim.finki.it.reservengo.service.impl;
-
-import mk.ukim.finki.it.reservengo.dto.eventDTO.CreateEventDTO;
-import mk.ukim.finki.it.reservengo.dto.localDTO.CreateLocalDetailsDTO;
-import mk.ukim.finki.it.reservengo.dto.localDTO.DeleteLocalPhotosResultDTO;
-import mk.ukim.finki.it.reservengo.dto.localDTO.DisplayLocalDTO;
-import mk.ukim.finki.it.reservengo.dto.localDTO.WorkingHourDTO;
-import mk.ukim.finki.it.reservengo.model.domain.Event;
-import mk.ukim.finki.it.reservengo.model.domain.Local;
-import mk.ukim.finki.it.reservengo.model.enumerations.LocalType;
-import mk.ukim.finki.it.reservengo.model.enumerations.ProvidedService;
-import mk.ukim.finki.it.reservengo.model.exceptions.*;
-import mk.ukim.finki.it.reservengo.repository.LocalRepository;
-import mk.ukim.finki.it.reservengo.service.intf.EventService;
-import mk.ukim.finki.it.reservengo.service.intf.FileStorageService;
-import mk.ukim.finki.it.reservengo.service.intf.LocalService;
-import org.springframework.data.domain.*;
-import org.springframework.data.jpa.domain.Specification;
-import org.springframework.stereotype.Service;
-import org.springframework.transaction.annotation.Transactional;
-import org.springframework.web.multipart.MultipartFile;
-
-import java.util.ArrayList;
-import java.util.Comparator;
-import java.util.List;
-import java.util.Objects;
-import java.util.stream.Collectors;
-import java.util.stream.Stream;
-
-@Service
-public class LocalServiceImpl implements LocalService {
-
-    private final LocalRepository localRepository;
-    private final FileStorageService fileStorageService;
-    private final EventService eventService;
-
-    public LocalServiceImpl(LocalRepository localRepository, FileStorageService fileStorageService, EventService eventService) {
-        this.localRepository = localRepository;
-        this.fileStorageService = fileStorageService;
-        this.eventService = eventService;
-    }
-
-    @Override
-    public List<Local> listAll() {
-        return localRepository.findAll();
-    }
-
-    @Override
-    public Local findLocalById(Long id) {
-        return localRepository.findById(id).orElseThrow(() -> new LocalIdNotFoundException(id));
-    }
-
-    @Override
-    public void save(String name) {
-        Local local = new Local(name);
-        localRepository.save(local);
-    }
-
-    @Override
-    @Transactional
-    public Local edit(Long localId, CreateLocalDetailsDTO createLocalDetailsDTO) {
-        Local local = localRepository.findById(localId).orElseThrow(() -> new LocalIdNotFoundException(localId));
-
-        local.setName(createLocalDetailsDTO.name());
-        local.setDescription(createLocalDetailsDTO.description());
-        local.setAddress(createLocalDetailsDTO.address());
-        local.setWorkingHours(new ArrayList<>(WorkingHourDTO.to(createLocalDetailsDTO.workingHours())));
-        local.setAvailableServices(new ArrayList<>(createLocalDetailsDTO.services()));
-        local.setLocalType(createLocalDetailsDTO.localType());
-        local.setMenuLink(createLocalDetailsDTO.menuLink());
-        local.setContact(createLocalDetailsDTO.contact().toContact());
-
-        return localRepository.save(local);
-    }
-
-    @Override
-    public void delete(Long id) {
-        Local local = localRepository.findById(id).orElseThrow(() -> new LocalIdNotFoundException(id));
-        localRepository.delete(local);
-    }
-
-    @Transactional
-    @Override
-    public String addLogo(Long localId, MultipartFile multipartFile) {
-        fileStorageService.validateFile(multipartFile);
-        Local local = localRepository.findById(localId).orElseThrow(() -> new LocalIdNotFoundException(localId));
-
-        if (local.getLogoUrl() != null && !local.getLogoUrl().isEmpty()) {
-            fileStorageService.deletePhotoFile(local.getLogoUrl());
-        }
-
-        String logoPath = fileStorageService.saveLogoFile(multipartFile);
-        local.setLogoUrl(logoPath);
-        localRepository.save(local);
-
-        return logoPath;
-    }
-
-    @Transactional
-    @Override
-    public void deleteLogo(Long localId) {
-        Local local = localRepository.findById(localId).orElseThrow(() -> new LocalIdNotFoundException(localId));
-        String logoUrl = local.getLogoUrl();
-
-        if (logoUrl != null && !logoUrl.isEmpty()) {
-            fileStorageService.deletePhotoFile(logoUrl);
-            local.setLogoUrl(null);
-            localRepository.save(local);
-        } else {
-            throw new PhotoDeletionException("No logo found for local with id: " + localId);
-        }
-    }
-
-    @Override
-    public String addPhoto(Long localId, MultipartFile photoFile) {
-        fileStorageService.validateFile(photoFile);
-        Local local = localRepository.findById(localId).orElseThrow(() -> new LocalIdNotFoundException(localId));
-
-        List<String> photoPaths = local.getPhotos();
-
-        if (photoPaths == null) {
-            photoPaths = new ArrayList<>();
-        }
-
-        String photoPath = fileStorageService.savePhotoFile(photoFile);
-        photoPaths.add(photoPath);
-        localRepository.save(local);
-
-        return photoPath;
-    }
-
-    @Transactional
-    @Override
-    public DeleteLocalPhotosResultDTO deletePhotos(Long localId, List<String> photoPaths) {
-        Local local = localRepository.findById(localId).orElseThrow(() -> new LocalIdNotFoundException(localId));
-        List<String> currentPhotoUrls = local.getPhotos();
-
-        if (currentPhotoUrls == null || currentPhotoUrls.isEmpty()) {
-            throw new PhotoDeletionException("No photos found for local with id: " + localId);
-        }
-
-        List<String> deletedPhotos = new ArrayList<>();
-        List<String> notFoundPhotos = new ArrayList<>();
-
-        for (String photoUrl : photoPaths) {
-            if (currentPhotoUrls.contains(photoUrl)) {
-                fileStorageService.deletePhotoFile(photoUrl);
-                currentPhotoUrls.remove(photoUrl);
-                deletedPhotos.add(photoUrl);
-            } else {
-                notFoundPhotos.add(photoUrl);
-            }
-        }
-        local.setPhotos(currentPhotoUrls);
-        localRepository.save(local);
-
-        return new DeleteLocalPhotosResultDTO(deletedPhotos, notFoundPhotos);
-    }
-
-    @Override
-    public Page<DisplayLocalDTO> searchLocals(String name, List<ProvidedService> services, LocalType localType, Boolean isOpen, int page, int size, String sortBy, String direction
-    ) {
-        if (isOpen == null) {
-            isOpen = false;
-        }
-        boolean sortByRating = "rating".equalsIgnoreCase(sortBy);
-        boolean needsManualProcessing = isOpen || sortByRating;
-
-        Specification<Local> spec = Specification.where(null);
-
-        if (name != null && !name.trim().isEmpty()) {
-            spec = spec.and((root, query, cb) ->
-                    cb.like(cb.lower(root.get("name")), "%" + name.toLowerCase() + "%"));
-        }
-
-        if (services != null && !services.isEmpty()) {
-            spec = spec.and((root, query, cb) -> {
-                Objects.requireNonNull(query).distinct(true);
-                return root.join("availableServices").in(services);
-            });
-        }
-
-        if (localType != null) {
-            spec = spec.and((root, query, cb) -> cb.equal(root.get("localType"), localType));
-        }
-
-        // If we need manual processing, get all results; otherwise use normal pagination
-        Pageable pageable = needsManualProcessing ? Pageable.unpaged() : PageRequest.of(page, size, getSort(sortBy, direction));
-        Page<Local> localsPage = localRepository.findAll(spec, pageable);
-
-        if (needsManualProcessing) {
-            Stream<Local> localStream = localsPage.getContent().stream();
-
-            // Filters only open restaurants if requested
-            if (isOpen) {
-                localStream = localStream.filter(Local::isOpenNow);
-            }
-
-            List<DisplayLocalDTO> dtoList = localStream
-                    .map(DisplayLocalDTO::fromLocal)
-                    .collect(Collectors.toList());
-
-            // Sort by rating (highest to lowest) if requested
-            if (sortByRating) {
-                dtoList = dtoList.stream()
-                        .sorted(Comparator.comparingDouble(DisplayLocalDTO::averageRating).reversed())
-                        .collect(Collectors.toList());
-            }
-
-            // Manual pagination
-            int totalElements = dtoList.size();
-            int start = Math.min(page * size, totalElements);
-            int end = Math.min(start + size, totalElements);
-            List<DisplayLocalDTO> pagedResults = dtoList.subList(start, end);
-
-            return new PageImpl<>(pagedResults, PageRequest.of(page, size), totalElements);
-        }
-
-        // Normal database-level pagination and sorting
-        return localsPage.map(DisplayLocalDTO::fromLocal);
-    }
-
-    @Override
-    public void addEvent(Local local, Event event) {
-        local.getEvents().add(event);
-        localRepository.save(local);
-    }
-
-    @Override
-    public void deleteEvent(Local local, Event event) {
-        if (!local.getEvents().contains(event)) {
-            throw new EventNotInLocalException(event.getId());
-        }
-        local.getEvents().remove(event);
-        
-        localRepository.save(local);
-    }
-
-    @Override
-    public Event editEvent(Local local, Event event, CreateEventDTO createEventDTO) {
-        if (!local.getEvents().contains(event)) {
-            throw new EventNotInLocalException(event.getId());
-        }
-
-        event.setName(createEventDTO.name());
-        event.setDescription(createEventDTO.description());
-        event.setEventStart(createEventDTO.eventStart());
-        event.setEventEnd(createEventDTO.eventEnd());
-        event.setEventType(createEventDTO.eventType());
-
-        return eventService.save(event);
-    }
-
-    @Override
-    @Transactional
-    public void addRating(Long customerId, Long localId, int rating) {
-        Local local = localRepository.findById(localId).orElseThrow(() -> new LocalIdNotFoundException(localId));
-        local.getRatings().put(customerId, rating);
-        localRepository.save(local);
-    }
-
-    @Override
-    @Transactional
-    public void removeRating(Long customerId, Long localId) {
-        Local local = localRepository.findById(localId).orElseThrow(() -> new LocalIdNotFoundException(localId));
-        if (!local.getRatings().containsKey(customerId) || local.getRatings().get(customerId) == null) {
-            throw new RatingNotFoundException(customerId, localId);
-        }
-        local.getRatings().remove(customerId);
-        localRepository.save(local);
-    }
-
-    private Sort getSort(String sortBy, String direction) {
-        Sort.Direction sortDirection = "desc".equalsIgnoreCase(direction) ? Sort.Direction.DESC : Sort.Direction.ASC;
-
-        return switch (sortBy) {
-            case "createdAt" -> Sort.by(sortDirection, "createdAt");
-            case "rating" -> Sort.unsorted(); // handled manually
-            default -> Sort.by(sortDirection, "name");
-        };
-    }
-}
Index: serveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/service/impl/LocalWorkerServiceImpl.java
===================================================================
--- ReserveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/service/impl/LocalWorkerServiceImpl.java	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,177 +1,0 @@
-package mk.ukim.finki.it.reservengo.service.impl;
-
-import jakarta.mail.MessagingException;
-import mk.ukim.finki.it.reservengo.dto.reservationDTO.DeleteReservationDTO;
-import mk.ukim.finki.it.reservengo.dto.workerDTO.DisplayLocalReservationDTO;
-import mk.ukim.finki.it.reservengo.model.domain.Local;
-import mk.ukim.finki.it.reservengo.model.domain.LocalWorker;
-import mk.ukim.finki.it.reservengo.model.domain.Reservation;
-import mk.ukim.finki.it.reservengo.model.enumerations.Position;
-import mk.ukim.finki.it.reservengo.model.enumerations.ReservationStatus;
-import mk.ukim.finki.it.reservengo.model.enumerations.Role;
-import mk.ukim.finki.it.reservengo.model.exceptions.*;
-import mk.ukim.finki.it.reservengo.repository.LocalRepository;
-import mk.ukim.finki.it.reservengo.repository.LocalWorkerRepository;
-import mk.ukim.finki.it.reservengo.repository.ReservationRepository;
-import mk.ukim.finki.it.reservengo.service.intf.EmailService;
-import mk.ukim.finki.it.reservengo.service.intf.LocalWorkerService;
-import mk.ukim.finki.it.reservengo.service.intf.UserService;
-import org.springframework.stereotype.Service;
-
-import java.util.List;
-import java.util.stream.Collectors;
-
-@Service
-public class LocalWorkerServiceImpl implements LocalWorkerService {
-    private final LocalWorkerRepository localWorkerRepository;
-    private final UserService userService;
-    private final ReservationRepository reservationRepository;
-    private final EmailService emailService;
-    private final LocalRepository localRepository;
-
-
-    public LocalWorkerServiceImpl(LocalWorkerRepository localWorkerRepository, UserService userService, ReservationRepository reservationRepository, EmailService emailService, LocalRepository localRepository) {
-        this.localWorkerRepository = localWorkerRepository;
-        this.userService = userService;
-        this.reservationRepository = reservationRepository;
-        this.emailService = emailService;
-        this.localRepository = localRepository;
-    }
-
-    @Override
-    public void save(LocalWorker localWorker) {
-        if (userService.emailExists(localWorker.getEmail())) {
-            throw new UserEmailAlreadyExistsException(localWorker.getEmail());
-        }
-        localWorkerRepository.save(localWorker);
-    }
-
-    @Override
-    public LocalWorker findWorkerById(Long id) {
-        return localWorkerRepository.findById(id).orElseThrow(() -> new WorkerIdNotFoundException(id));
-    }
-
-    @Override
-    public void changePosition(LocalWorker worker, Position position) {
-        worker.setPosition(position);
-        localWorkerRepository.save(worker);
-    }
-
-    @Override
-    public List<LocalWorker> findAllByLocalId(Long id) {
-        return localWorkerRepository.findByLocal_Id(id);
-    }
-
-    @Override
-    public List<LocalWorker> findAllUnassigned() {
-        return localWorkerRepository.findAll().stream()
-                .filter(worker -> worker.getLocal() == null)
-                .filter(worker -> worker.getPosition() == null)
-                .collect(Collectors.toList());
-    }
-
-    @Override
-    public void updateLocalAssignment(LocalWorker worker, Local local) {
-        worker.setLocal(local);
-        if (local == null) {
-            worker.setPosition(null);
-        }
-        localWorkerRepository.save(worker);
-    }
-
-    @Override
-    public List<DisplayLocalReservationDTO> viewWorkerLocalReservations(Long workerUserId, ReservationStatus status) {
-        LocalWorker localWorker = validateWorker(workerUserId);
-        Local local = localWorker.getLocal();
-
-        List<Reservation> reservations =
-                (status != null)
-                        ? reservationRepository.findByLocalIdAndStatus(local.getId(), status)
-                        : reservationRepository.findByLocalId(local.getId());
-
-        return DisplayLocalReservationDTO.from(reservations);
-    }
-
-    @Override
-    public void acceptReservation(Long workerUserId, Long reservationId) throws MessagingException {
-        LocalWorker worker = validateWorker(workerUserId);
-        Reservation reservation = getAuthorizedReservation(worker, reservationId);
-
-        reservation.setStatus(ReservationStatus.ACCEPTED);
-        reservationRepository.save(reservation);
-
-        emailService.sendReservationFeedbackEmail(reservation.getCustomer().getEmail(), ReservationStatus.ACCEPTED);
-    }
-
-    @Override
-    public void denyReservation(Long workerUserId, Long reservationId) throws MessagingException {
-        LocalWorker worker = validateWorker(workerUserId);
-        Reservation reservation = getAuthorizedReservation(worker, reservationId);
-
-        reservation.setStatus(ReservationStatus.CANCELED);
-        reservationRepository.save(reservation);
-
-        emailService.sendReservationFeedbackEmail(reservation.getCustomer().getEmail(), ReservationStatus.CANCELED);
-    }
-
-    @Override
-    public void finishReservation(Long id, Long reservationId) {
-        LocalWorker worker = validateWorker(id);
-        Reservation reservation = getAuthorizedReservation(worker, reservationId);
-
-        reservation.setStatus(ReservationStatus.FINISHED);
-        reservationRepository.save(reservation);
-    }
-
-    @Override
-    public void deleteReservation(Long id, DeleteReservationDTO deleteReservationDTO) {
-        LocalWorker worker = localWorkerRepository.findById(id).orElseThrow(() -> new WorkerIdNotFoundException(id));
-        List<Reservation> reservations = getAuthorizedReservations(worker, deleteReservationDTO.reservationIds());
-        Local local = worker.getLocal();
-        for (Reservation reservation : reservations) {
-            reservation.setStatus(ReservationStatus.CANCELED);
-            reservation.setLocal(null);
-            local.getReservations().remove(reservation);
-            reservationRepository.save(reservation);
-        }
-
-        localRepository.save(local);
-    }
-
-    private Reservation getAuthorizedReservation(LocalWorker worker, Long reservationId) {
-        Reservation reservation = reservationRepository.findById(reservationId).orElseThrow(() -> new ReservationIdNotFoundException(reservationId));
-
-        if (!reservation.getLocal().getId().equals(worker.getLocal().getId())) {
-            throw new UnauthorizedException(worker.getId());
-        }
-
-        return reservation;
-    }
-
-    private List<Reservation> getAuthorizedReservations(LocalWorker worker, List<Long> reservationIds) {
-        List<Reservation> reservations = reservationRepository.findAllById(reservationIds);
-
-        for (Reservation reservation : reservations) {
-            if (!reservation.getLocal().getId().equals(worker.getLocal().getId())) {
-                throw new UnauthorizedException(worker.getId());
-            }
-        }
-
-        return reservations;
-    }
-
-    private LocalWorker validateWorker(Long workerUserId) {
-        LocalWorker worker = localWorkerRepository.findById(workerUserId)
-                .orElseThrow(() -> new WorkerIdNotFoundException(workerUserId));
-
-        if (worker.getUserRole() != Role.ROLE_LOCAL_WORKER) {
-            throw new UnauthorizedException(workerUserId);
-        }
-
-        if (worker.getLocal() == null) {
-            throw new WorkerNotAssignedException(workerUserId);
-        }
-
-        return worker;
-    }
-}
Index: serveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/service/impl/UserServiceImpl.java
===================================================================
--- ReserveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/service/impl/UserServiceImpl.java	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,144 +1,0 @@
-package mk.ukim.finki.it.reservengo.service.impl;
-
-import mk.ukim.finki.it.reservengo.dto.userDTO.*;
-import mk.ukim.finki.it.reservengo.model.domain.User;
-import mk.ukim.finki.it.reservengo.model.exceptions.EmailNotFoundException;
-import mk.ukim.finki.it.reservengo.model.exceptions.PhotoDeletionException;
-import mk.ukim.finki.it.reservengo.model.exceptions.UserEmailAlreadyExistsException;
-import mk.ukim.finki.it.reservengo.model.exceptions.UserIdNotFoundException;
-import mk.ukim.finki.it.reservengo.repository.UserRepository;
-import mk.ukim.finki.it.reservengo.service.intf.FileStorageService;
-import mk.ukim.finki.it.reservengo.service.intf.JWTService;
-import mk.ukim.finki.it.reservengo.service.intf.UserService;
-import org.springframework.security.crypto.password.PasswordEncoder;
-import org.springframework.stereotype.Service;
-import org.springframework.transaction.annotation.Transactional;
-import org.springframework.web.multipart.MultipartFile;
-
-import java.time.LocalDateTime;
-
-@Service
-@Transactional
-public class UserServiceImpl implements UserService {
-
-    private final UserRepository userRepository;
-    private final JWTService jwtService;
-    private final PasswordEncoder passwordEncoder;
-    private final FileStorageService fileStorageService;
-
-    public UserServiceImpl(UserRepository userRepository, PasswordEncoder passwordEncoder, JWTService jwtService, FileStorageService fileStorageService) {
-        this.userRepository = userRepository;
-        this.jwtService = jwtService;
-        this.passwordEncoder = passwordEncoder;
-        this.fileStorageService = fileStorageService;
-    }
-
-    @Override
-    public User findUserById(Long userId) {
-        return userRepository.findById(userId).orElseThrow(() -> new UserIdNotFoundException(userId));
-    }
-
-    @Override
-    public User findUserByEmail(String email) {
-        return userRepository.findByEmail(email).orElseThrow(() -> new EmailNotFoundException(email));
-    }
-
-    @Override
-    public boolean emailExists(String email) {
-        return userRepository.findByEmail(email).isPresent();
-    }
-
-    @Override
-    public DisplayUserEmailDTO changeEmail(Long userId, EditUserEmailDTO editUserEmailDTO) {
-        User user = userRepository.findById(userId).orElseThrow(() -> new UserIdNotFoundException(userId));
-
-        if (editUserEmailDTO.newEmail().equals(user.getEmail())) {
-            throw new IllegalArgumentException("New email must be different from the current email.");
-        }
-        if (emailExists(editUserEmailDTO.newEmail())) {
-            throw new UserEmailAlreadyExistsException(editUserEmailDTO.newEmail());
-        }
-        user.setEmail(editUserEmailDTO.newEmail());
-
-        userRepository.save(user);
-        String jwt = jwtService.generateToken(user);
-
-        return DisplayUserEmailDTO.fromUser(user, jwt);
-    }
-
-    @Override
-    public void changePassword(Long userId, EditUserPasswordDTO editUserPasswordDTO) {
-        User user = userRepository.findById(userId).orElseThrow(() -> new UserIdNotFoundException(userId));
-
-        if (!passwordEncoder.matches(editUserPasswordDTO.currentPassword(), user.getPassword())) {
-            throw new IllegalArgumentException("Current password is incorrect");
-        }
-
-        user.setPassword(passwordEncoder.encode(editUserPasswordDTO.newPassword()));
-        userRepository.save(user);
-    }
-
-    @Override
-    public String uploadProfilePhoto(Long userId, MultipartFile photoFile) {
-        fileStorageService.validateFile(photoFile);
-        User user = userRepository.findById(userId).orElseThrow(() -> new UserIdNotFoundException(userId));
-
-        if (user.getProfilePhotoUrl() != null && !user.getProfilePhotoUrl().isEmpty()) {
-            fileStorageService.deletePhotoFile(user.getProfilePhotoUrl());
-        }
-
-        String photoPath = fileStorageService.saveProfilePhotoFile(photoFile);
-        user.setProfilePhotoUrl(photoPath);
-        userRepository.save(user);
-
-        return photoPath;
-    }
-
-    @Override
-    public void deleteProfilePhoto(Long userId) {
-        User user = userRepository.findById(userId).orElseThrow(() -> new UserIdNotFoundException(userId));
-        String photoUrl = user.getProfilePhotoUrl();
-
-        if (photoUrl != null && !photoUrl.isEmpty()) {
-            fileStorageService.deletePhotoFile(photoUrl);
-            user.setProfilePhotoUrl(null);
-            userRepository.save(user);
-        } else {
-            throw new PhotoDeletionException("No profile photo found for user with id: " + userId);
-        }
-    }
-
-    @Override
-    public void disableProfile(Long id) {
-        User user = userRepository.findById(id).orElseThrow(() -> new UserIdNotFoundException(id));
-        user.setEnabled(false);
-        userRepository.save(user);
-    }
-
-    @Override
-    public void enableProfile(Long id) {
-        User user = userRepository.findById(id).orElseThrow(() -> new UserIdNotFoundException(id));
-        user.setEnabled(true);
-        user.setLastActivityDate(LocalDateTime.now());
-        userRepository.save(user);
-    }
-
-    @Override
-    public void updateUserActivity(Long id) {
-        User user = userRepository.findById(id).orElseThrow(() -> new UserIdNotFoundException(id));
-        user.setLastActivityDate(LocalDateTime.now());
-        userRepository.save(user);
-    }
-
-    @Override
-    public User editUser(Long userId, EditUserProfileDTO editUserProfileDTO) {
-        User user = userRepository.findById(userId).orElseThrow(() -> new UserIdNotFoundException(userId));
-
-        user.setFirstName(editUserProfileDTO.firstName());
-        user.setLastName(editUserProfileDTO.lastName());
-        user.setPhoneNumber(editUserProfileDTO.phoneNumber());
-        userRepository.save(user);
-
-        return user;
-    }
-}
Index: serveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/service/intf/AdminService.java
===================================================================
--- ReserveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/service/intf/AdminService.java	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,27 +1,0 @@
-package mk.ukim.finki.it.reservengo.service.intf;
-
-import jakarta.mail.MessagingException;
-import mk.ukim.finki.it.reservengo.dto.adminDTO.DisplayAdminLocalsDTO;
-import mk.ukim.finki.it.reservengo.dto.localDTO.CreateLocalDTO;
-import mk.ukim.finki.it.reservengo.dto.userDTO.DisplayUserDTO;
-import mk.ukim.finki.it.reservengo.dto.userDTO.EditUserEmailDTO;
-
-import java.util.List;
-
-public interface AdminService {
-    void addLocal(CreateLocalDTO localDTO);
-
-    void deleteLocal(Long id);
-
-    List<DisplayAdminLocalsDTO> getLocals();
-
-    List<DisplayUserDTO> findManagersByLocalId(Long localId);
-
-    List<DisplayUserDTO> findUnassignedManagers();
-
-    void assignManagerToLocal(Long localId, Long managerId);
-
-    void removeManagerFromLocal(Long managerId);
-
-    void inviteManager(EditUserEmailDTO emailDTO) throws MessagingException;
-}
Index: serveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/service/intf/AuthService.java
===================================================================
--- ReserveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/service/intf/AuthService.java	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,30 +1,0 @@
-package mk.ukim.finki.it.reservengo.service.intf;
-
-import jakarta.mail.MessagingException;
-import mk.ukim.finki.it.reservengo.dto.jwtDTO.JWTAuthenticationRequestDTO;
-import mk.ukim.finki.it.reservengo.dto.jwtDTO.JWTAuthenticationResponseDTO;
-import mk.ukim.finki.it.reservengo.dto.jwtDTO.JWTLoginDTO;
-
-public interface AuthService {
-    JWTAuthenticationResponseDTO registerCustomer(JWTAuthenticationRequestDTO jwtAuthenticationRequestDTO) throws MessagingException;
-
-    JWTAuthenticationResponseDTO registerLocalWorker(JWTAuthenticationRequestDTO jwtAuthenticationRequestDTO, String token);
-
-    JWTAuthenticationResponseDTO registerLocalManager(JWTAuthenticationRequestDTO jwtAuthenticationRequestDTO, String token);
-
-    JWTAuthenticationResponseDTO login(JWTLoginDTO jwtLoginDTO) throws MessagingException;
-
-    void reactivateProfile(JWTLoginDTO jwtLoginDTO);
-
-    void verifyCustomer(String email, String verificationCode) throws MessagingException;
-
-    void resendVerificationCode(String email) throws MessagingException;
-
-    JWTAuthenticationResponseDTO registerGoogleCustomer(String idToken);
-
-    JWTAuthenticationResponseDTO registerGoogleLocalWorker(String idToken, String inviteToken);
-
-    JWTAuthenticationResponseDTO registerGoogleLocalManager(String idToken, String inviteToken);
-
-    JWTAuthenticationResponseDTO loginWithGoogle(String idToken);
-}
Index: serveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/service/intf/CustomerService.java
===================================================================
--- ReserveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/service/intf/CustomerService.java	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,44 +1,0 @@
-package mk.ukim.finki.it.reservengo.service.intf;
-
-import mk.ukim.finki.it.reservengo.dto.customerDTO.RatingDTO;
-import mk.ukim.finki.it.reservengo.dto.eventDTO.DisplayEventDTO;
-import mk.ukim.finki.it.reservengo.dto.localDTO.DisplayLocalDTO;
-import mk.ukim.finki.it.reservengo.dto.reservationDTO.*;
-import mk.ukim.finki.it.reservengo.model.domain.Customer;
-
-import java.util.List;
-
-public interface CustomerService {
-
-    List<DisplayLocalDTO> listFavouriteLocals(Long id);
-
-    void addFavouriteLocal(Long userId, Long localId);
-
-    void removeFavouriteLocal(Long userId, Long localId);
-
-    void save(Customer customer);
-
-    List<DisplayEventDTO> listFavouriteEvents(Long id);
-
-    void addFavouriteEvent(Long userId, Long eventId);
-
-    void removeFavouriteEvent(Long userId, Long eventId);
-
-    void rateLocal(Long customerId, Long localId, RatingDTO ratingDTO);
-
-    void removeRating(Long customerId, Long localId);
-
-    int findLocalRating(Long customerId, Long localId);
-
-    List<DisplayReservationDTO> listAllReservations(Long id);
-
-    DisplayReservationDTO getReservationPreview(Long customerId, Long reservationId);
-
-    DisplayReservationDTO editReservation(Long id, Long reservationId, EditReservationDTO editReservationDTO);
-
-    void cancelReservation(Long id, Long reservationId);
-
-    void makeReservation(Long id, Long localId,CreateReservationDTO createReservationDTO);
-
-    void deleteReservation(Long id, DeleteReservationDTO deleteReservationDTO);
-}
Index: serveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/service/intf/EmailService.java
===================================================================
--- ReserveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/service/intf/EmailService.java	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,14 +1,0 @@
-package mk.ukim.finki.it.reservengo.service.intf;
-
-import jakarta.mail.MessagingException;
-import mk.ukim.finki.it.reservengo.model.enumerations.ReservationStatus;
-
-public interface EmailService {
-    void sendManagerInvitationEmail(String email, String token) throws MessagingException;
-
-    void sendWorkerInvitationEmail(String email, String token, String managerEmail, String localName) throws MessagingException;
-
-    void sendVerificationEmail(String email, String verificationCode) throws MessagingException;
-
-    void sendReservationFeedbackEmail(String email, ReservationStatus status) throws MessagingException;
-}
Index: serveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/service/intf/EventService.java
===================================================================
--- ReserveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/service/intf/EventService.java	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,16 +1,0 @@
-package mk.ukim.finki.it.reservengo.service.intf;
-
-import mk.ukim.finki.it.reservengo.dto.eventDTO.DisplayEventDTO;
-import mk.ukim.finki.it.reservengo.model.domain.Event;
-import mk.ukim.finki.it.reservengo.model.domain.Local;
-import mk.ukim.finki.it.reservengo.model.enumerations.EventStatus;
-import mk.ukim.finki.it.reservengo.model.enumerations.EventType;
-import org.springframework.data.domain.Page;
-
-public interface EventService {
-    Page<DisplayEventDTO> searchEvents(Local local, String name, EventType eventType, EventStatus eventStatus, int page, int size, String sortBy, String direction);
-
-    Event findEventById(Long id);
-
-    Event save(Event event);
-}
Index: serveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/service/intf/FileStorageService.java
===================================================================
--- ReserveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/service/intf/FileStorageService.java	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,15 +1,0 @@
-package mk.ukim.finki.it.reservengo.service.intf;
-
-import org.springframework.web.multipart.MultipartFile;
-
-public interface FileStorageService {
-    String saveLogoFile(MultipartFile file);
-
-    String saveProfilePhotoFile(MultipartFile file);
-
-    String savePhotoFile(MultipartFile file);
-
-    void deletePhotoFile(String filePath);
-
-    void validateFile(MultipartFile file);
-}
Index: serveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/service/intf/JWTService.java
===================================================================
--- ReserveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/service/intf/JWTService.java	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,30 +1,0 @@
-package mk.ukim.finki.it.reservengo.service.intf;
-
-import io.jsonwebtoken.Claims;
-import mk.ukim.finki.it.reservengo.model.domain.User;
-import mk.ukim.finki.it.reservengo.model.enumerations.Role;
-import org.springframework.security.core.userdetails.UserDetails;
-
-import java.security.Key;
-import java.util.Date;
-import java.util.function.Function;
-
-public interface JWTService {
-    String generateToken(User user);
-
-    String extractUsername(String token);
-
-    Claims extractAllClaims(String token);
-
-    Key getSignInKey();
-
-    <T> T extractClaim(String token, Function<Claims, T> claimsResolver);
-
-    boolean isTokenValid(String token, UserDetails userDetails);
-
-    boolean isTokenExpired(String token);
-
-    Date extractExpiration(String token);
-
-    String generateInviteToken(String email, Role role);
-}
Index: serveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/service/intf/LocalManagerService.java
===================================================================
--- ReserveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/service/intf/LocalManagerService.java	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,59 +1,0 @@
-package mk.ukim.finki.it.reservengo.service.intf;
-
-import jakarta.mail.MessagingException;
-import mk.ukim.finki.it.reservengo.dto.eventDTO.CreateEventDTO;
-import mk.ukim.finki.it.reservengo.dto.localDTO.CreateLocalDetailsDTO;
-import mk.ukim.finki.it.reservengo.dto.localDTO.DeleteLocalPhotosDTO;
-import mk.ukim.finki.it.reservengo.dto.localDTO.DeleteLocalPhotosResultDTO;
-import mk.ukim.finki.it.reservengo.dto.userDTO.EditUserEmailDTO;
-import mk.ukim.finki.it.reservengo.dto.workerDTO.PositionDTO;
-import mk.ukim.finki.it.reservengo.model.domain.Event;
-import mk.ukim.finki.it.reservengo.model.domain.Local;
-import mk.ukim.finki.it.reservengo.model.domain.LocalManager;
-import mk.ukim.finki.it.reservengo.model.domain.LocalWorker;
-import mk.ukim.finki.it.reservengo.model.enumerations.Position;
-import org.springframework.web.multipart.MultipartFile;
-
-import java.util.List;
-
-public interface LocalManagerService {
-    void save(LocalManager localManager);
-
-    List<LocalManager> findAllByLocalId(Long localId);
-
-    LocalManager findManagerById(Long id);
-
-    List<LocalManager> findAllUnassigned();
-
-    void updateLocalAssignment(LocalManager manager, Local local, Position position);
-
-    Local findLocalByManagerId(Long id);
-
-    Local editLocal(Long managerId, CreateLocalDetailsDTO createLocalDetailsDTO);
-
-    String uploadLocalLogo(Long managerId, MultipartFile logoFile);
-
-    void deleteLocalLogo(Long managerId);
-
-    String uploadLocalPhoto(Long managerId, MultipartFile photoFile);
-
-    DeleteLocalPhotosResultDTO deleteLocalPhoto(Long managerId, DeleteLocalPhotosDTO deleteLocalPhotosDTO);
-
-    void addEvent(Long managerId, CreateEventDTO createEventDTO);
-
-    void deleteEvent(Long managerId, Long eventId);
-
-    Event editEvent(Long managerId, Long eventId, CreateEventDTO createEventDTO);
-
-    List<LocalWorker> findWorkersByLocal(Local local);
-
-    List<LocalWorker> findUnassignedWorkers();
-
-    void assignWorkerToLocal(Local local, Long workerId);
-
-    void removeWorkerFromLocal(Long managerId, Long workerId);
-
-    void changePosition(Long managerId, Long workerId, PositionDTO positionDTO);
-
-    void inviteWorker(Long managerId, EditUserEmailDTO emailDTO) throws MessagingException;
-}
Index: serveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/service/intf/LocalService.java
===================================================================
--- ReserveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/service/intf/LocalService.java	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,46 +1,0 @@
-package mk.ukim.finki.it.reservengo.service.intf;
-
-import mk.ukim.finki.it.reservengo.dto.eventDTO.CreateEventDTO;
-import mk.ukim.finki.it.reservengo.dto.localDTO.CreateLocalDetailsDTO;
-import mk.ukim.finki.it.reservengo.dto.localDTO.DeleteLocalPhotosResultDTO;
-import mk.ukim.finki.it.reservengo.dto.localDTO.DisplayLocalDTO;
-import mk.ukim.finki.it.reservengo.model.domain.Event;
-import mk.ukim.finki.it.reservengo.model.domain.Local;
-import mk.ukim.finki.it.reservengo.model.enumerations.LocalType;
-import mk.ukim.finki.it.reservengo.model.enumerations.ProvidedService;
-import org.springframework.data.domain.Page;
-import org.springframework.web.multipart.MultipartFile;
-
-import java.util.List;
-
-public interface LocalService {
-    List<Local> listAll();
-
-    Local findLocalById(Long id);
-
-    void save(String name);
-
-    Local edit(Long localId, CreateLocalDetailsDTO createLocalDetailsDTO);
-
-    void delete(Long id);
-
-    String addLogo(Long localId, MultipartFile multipartFile);
-
-    void deleteLogo(Long localId);
-
-    String addPhoto(Long localId, MultipartFile photoFile);
-
-    DeleteLocalPhotosResultDTO deletePhotos(Long localId, List<String> photoUrls);
-
-    Page<DisplayLocalDTO> searchLocals(String name, List<ProvidedService> services, LocalType localType, Boolean isOpen, int page, int size, String sortBy, String direction);
-
-    void addEvent(Local local, Event event);
-
-    void deleteEvent(Local local, Event event);
-
-    Event editEvent(Local local, Event event, CreateEventDTO createEventDTO);
-
-    void addRating(Long customerId, Long localId, int rating);
-
-    void removeRating(Long customerId, Long localId);
-}
Index: serveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/service/intf/LocalWorkerService.java
===================================================================
--- ReserveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/service/intf/LocalWorkerService.java	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,35 +1,0 @@
-package mk.ukim.finki.it.reservengo.service.intf;
-
-import jakarta.mail.MessagingException;
-import mk.ukim.finki.it.reservengo.dto.reservationDTO.DeleteReservationDTO;
-import mk.ukim.finki.it.reservengo.dto.workerDTO.DisplayLocalReservationDTO;
-import mk.ukim.finki.it.reservengo.model.domain.Local;
-import mk.ukim.finki.it.reservengo.model.domain.LocalWorker;
-import mk.ukim.finki.it.reservengo.model.enumerations.Position;
-import mk.ukim.finki.it.reservengo.model.enumerations.ReservationStatus;
-
-import java.util.List;
-
-public interface LocalWorkerService {
-    void save(LocalWorker localWorker);
-
-    LocalWorker findWorkerById(Long id);
-
-    void changePosition(LocalWorker worker, Position position);
-
-    List<LocalWorker> findAllByLocalId(Long id);
-
-    List<LocalWorker> findAllUnassigned();
-
-    void updateLocalAssignment(LocalWorker worker, Local local);
-
-    List<DisplayLocalReservationDTO> viewWorkerLocalReservations(Long id, ReservationStatus status);
-
-    void acceptReservation(Long id,Long reservationId) throws MessagingException;
-
-    void denyReservation(Long id,Long reservationId) throws MessagingException;
-
-    void finishReservation(Long id, Long reservationId);
-
-    void deleteReservation(Long id, DeleteReservationDTO deleteReservationDTO);
-}
Index: serveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/service/intf/UserService.java
===================================================================
--- ReserveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/service/intf/UserService.java	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,29 +1,0 @@
-package mk.ukim.finki.it.reservengo.service.intf;
-
-import mk.ukim.finki.it.reservengo.dto.userDTO.*;
-import mk.ukim.finki.it.reservengo.model.domain.User;
-import org.springframework.web.multipart.MultipartFile;
-
-public interface UserService {
-    User findUserById(Long userId);
-
-    User editUser(Long userId, EditUserProfileDTO editUserProfileDTO);
-
-    User findUserByEmail(String email);
-
-    boolean emailExists(String email);
-
-    DisplayUserEmailDTO changeEmail(Long userId, EditUserEmailDTO editUserEmailDTO);
-
-    void changePassword(Long userId, EditUserPasswordDTO editUserPasswordDTO);
-
-    String uploadProfilePhoto(Long userId, MultipartFile photoFile);
-
-    void deleteProfilePhoto(Long userId);
-
-    void disableProfile(Long id);
-
-    void enableProfile(Long id);
-
-    void updateUserActivity(Long id);
-}
Index: serveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/service/jobs/ScheduledTasks.java
===================================================================
--- ReserveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/service/jobs/ScheduledTasks.java	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,54 +1,0 @@
-package mk.ukim.finki.it.reservengo.service.jobs;
-
-import mk.ukim.finki.it.reservengo.model.domain.User;
-import mk.ukim.finki.it.reservengo.model.enumerations.Role;
-import mk.ukim.finki.it.reservengo.repository.ReservationRepository;
-import mk.ukim.finki.it.reservengo.repository.UserRepository;
-import org.springframework.scheduling.annotation.Scheduled;
-import org.springframework.stereotype.Component;
-import org.springframework.transaction.annotation.Transactional;
-
-import java.time.LocalDateTime;
-import java.util.List;
-
-@Component
-public class ScheduledTasks {
-
-    private final UserRepository userRepository;
-    private final ReservationRepository reservationRepository;
-
-    public ScheduledTasks(UserRepository userRepository, ReservationRepository reservationRepository) {
-        this.userRepository = userRepository;
-        this.reservationRepository = reservationRepository;
-    }
-
-    @Transactional
-    @Scheduled(cron = "0 0 3 * * ?")
-    public void deleteInactiveDisabledUsers() {
-        LocalDateTime threshold = LocalDateTime.now().minusDays(30);
-        List<User> usersToDelete = userRepository.findAllByEnabledFalseAndLastActivityDateBefore(threshold);
-        userRepository.deleteAll(usersToDelete);
-    }
-
-    @Transactional
-    @Scheduled(cron = "0 0 4 * * ?")
-    public void disableInactiveWorkersAndManagers() {
-        LocalDateTime threshold = LocalDateTime.now().minusDays(30);
-        List<User> usersToDisable = userRepository.findAllByEnabledTrueAndLastActivityDateBefore(threshold)
-                .stream()
-                .filter(user -> user.getUserRole() == Role.ROLE_LOCAL_MANAGER || user.getUserRole() == Role.ROLE_LOCAL_WORKER)
-                .toList();
-
-        usersToDisable.forEach(user -> {
-            user.setEnabled(false);
-            user.setLastActivityDate(LocalDateTime.now());
-        });
-        userRepository.saveAll(usersToDisable);
-    }
-
-    @Transactional
-    @Scheduled(cron = "0 0 0/1 * * ?")
-    public void expireOldReservations() {
-        reservationRepository.expireOldReservations(LocalDateTime.now());
-    }
-}
Index: serveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/web/advice/GlobalExceptionHandler.java
===================================================================
--- ReserveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/web/advice/GlobalExceptionHandler.java	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,169 +1,0 @@
-package mk.ukim.finki.it.reservengo.web.advice;
-
-import com.google.common.base.VerifyException;
-import jakarta.mail.MessagingException;
-import mk.ukim.finki.it.reservengo.model.exceptions.*;
-import org.springframework.http.HttpStatus;
-import org.springframework.http.ResponseEntity;
-import org.springframework.security.access.AccessDeniedException;
-import org.springframework.security.authentication.BadCredentialsException;
-import org.springframework.security.core.AuthenticationException;
-import org.springframework.web.bind.annotation.ExceptionHandler;
-import org.springframework.web.bind.annotation.RestControllerAdvice;
-
-import java.nio.file.FileSystemException;
-
-@RestControllerAdvice
-public class GlobalExceptionHandler {
-
-    @ExceptionHandler(BadCredentialsException.class)
-    public ResponseEntity<String> handleBadCredentials(BadCredentialsException ex) {
-        return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body(ex.getMessage());
-    }
-
-    @ExceptionHandler(EmailNotFoundException.class)
-    public ResponseEntity<String> handleEmailNotFound(EmailNotFoundException ex) {
-        return ResponseEntity.status(HttpStatus.NOT_FOUND).body(ex.getMessage());
-    }
-
-    @ExceptionHandler(AuthenticationException.class)
-    public ResponseEntity<String> handleAuthenticationError(AuthenticationException ex) {
-        return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(ex.getMessage());
-    }
-
-    @ExceptionHandler(IllegalArgumentException.class)
-    public ResponseEntity<String> handleIllegalArgumentException(IllegalArgumentException ex) {
-        return ResponseEntity.status(HttpStatus.NOT_ACCEPTABLE).body(ex.getMessage());
-    }
-
-    @ExceptionHandler(IllegalStateException.class)
-    public ResponseEntity<String> handleIllegalStateException(IllegalStateException ex) {
-        return ResponseEntity.status(HttpStatus.FORBIDDEN).body(ex.getMessage());
-    }
-
-    @ExceptionHandler(UserIdNotFoundException.class)
-    public ResponseEntity<String> handleUserIdNotFound(UserIdNotFoundException ex) {
-        return ResponseEntity.status(HttpStatus.NOT_FOUND).body(ex.getMessage());
-    }
-
-    @ExceptionHandler(LocalManagerIdNotFoundException.class)
-    public ResponseEntity<String> handleLocalManagerIdNotFound(LocalManagerIdNotFoundException ex) {
-        return ResponseEntity.status(HttpStatus.NOT_FOUND).body(ex.getMessage());
-    }
-
-    @ExceptionHandler(LocalIdNotFoundException.class)
-    public ResponseEntity<String> handleLocalIdNotFound(LocalIdNotFoundException ex) {
-        return ResponseEntity.status(HttpStatus.NOT_FOUND).body(ex.getMessage());
-    }
-
-    @ExceptionHandler(CustomerIdNotFoundException.class)
-    public ResponseEntity<String> handleCustomerIdNotFound(CustomerIdNotFoundException ex) {
-        return ResponseEntity.status(HttpStatus.NOT_FOUND).body(ex.getMessage());
-    }
-
-    @ExceptionHandler(ReservationIdNotFoundException.class)
-    public ResponseEntity<String> handleReservationIdNotFound(ReservationIdNotFoundException ex) {
-        return ResponseEntity.status(HttpStatus.NOT_FOUND).body(ex.getMessage());
-    }
-
-    @ExceptionHandler(UserEmailAlreadyExistsException.class)
-    public ResponseEntity<String> handleUserEmailAlreadyExists(UserEmailAlreadyExistsException ex) {
-        return ResponseEntity.status(HttpStatus.CONFLICT).body(ex.getMessage());
-    }
-
-    @ExceptionHandler(LocalAlreadyFavouredException.class)
-    public ResponseEntity<String> handleLocalAlreadyFavoured(LocalAlreadyFavouredException ex) {
-        return ResponseEntity.status(HttpStatus.CONFLICT).body(ex.getMessage());
-    }
-
-    @ExceptionHandler(LocalAlreadyUnfavouredException.class)
-    public ResponseEntity<String> handleLocalAlreadyUnfavoured(LocalAlreadyUnfavouredException ex) {
-        return ResponseEntity.status(HttpStatus.CONFLICT).body(ex.getMessage());
-    }
-
-    @ExceptionHandler(ManagerAlreadyAssignedException.class)
-    public ResponseEntity<String> handleManagerAlreadyAssigned(ManagerAlreadyAssignedException ex) {
-        return ResponseEntity.status(HttpStatus.CONFLICT).body(ex.getMessage());
-    }
-
-    @ExceptionHandler(ManagerNotAssignedException.class)
-    public ResponseEntity<String> handleManagerNotAssigned(ManagerNotAssignedException ex) {
-        return ResponseEntity.status(HttpStatus.CONFLICT).body(ex.getMessage());
-    }
-
-    @ExceptionHandler(InvalidFileException.class)
-    public ResponseEntity<String> handleInvalidFile(InvalidFileException ex) {
-        return ResponseEntity.status(HttpStatus.CONFLICT).body(ex.getMessage());
-    }
-
-    @ExceptionHandler(PhotoUploadException.class)
-    public ResponseEntity<String> handleFailedPhotoUpload(PhotoUploadException ex) {
-        return ResponseEntity.status(HttpStatus.CONFLICT).body(ex.getMessage());
-    }
-
-    @ExceptionHandler(PhotoDeletionException.class)
-    public ResponseEntity<String> handleFailedPhotoDelete(PhotoDeletionException ex) {
-        return ResponseEntity.status(HttpStatus.CONFLICT).body(ex.getMessage());
-    }
-
-    @ExceptionHandler(FileSystemException.class)
-    public ResponseEntity<String> handleFileSystemFail(FileSystemException ex) {
-        return ResponseEntity.status(HttpStatus.CONFLICT).body(ex.getMessage());
-    }
-
-    @ExceptionHandler(EventIdNotFoundException.class)
-    public ResponseEntity<String> handleEventIdNotFound(EventIdNotFoundException ex) {
-        return ResponseEntity.status(HttpStatus.NOT_FOUND).body(ex.getMessage());
-    }
-
-    @ExceptionHandler(EventNotInLocalException.class)
-    public ResponseEntity<String> handleEventNotInLocal(EventNotInLocalException ex) {
-        return ResponseEntity.status(HttpStatus.FORBIDDEN).body(ex.getMessage());
-    }
-
-    @ExceptionHandler(EventAlreadyFavouredException.class)
-    public ResponseEntity<String> handleEventAlreadyFavoured(EventAlreadyFavouredException ex) {
-        return ResponseEntity.status(HttpStatus.CONFLICT).body(ex.getMessage());
-    }
-
-    @ExceptionHandler(EventAlreadyUnfavouredException.class)
-    public ResponseEntity<String> handleEventAlreadyUnfavoured(EventAlreadyUnfavouredException ex) {
-        return ResponseEntity.status(HttpStatus.CONFLICT).body(ex.getMessage());
-    }
-
-    @ExceptionHandler(WorkerIdNotFoundException.class)
-    public ResponseEntity<String> handleWorkerIdNotFound(WorkerIdNotFoundException ex) {
-        return ResponseEntity.status(HttpStatus.NOT_FOUND).body(ex.getMessage());
-    }
-
-    @ExceptionHandler(WorkerNotAssignedException.class)
-    public ResponseEntity<String> handleWorkerNotAssigned(WorkerNotAssignedException ex) {
-        return ResponseEntity.status(HttpStatus.CONFLICT).body(ex.getMessage());
-    }
-
-    @ExceptionHandler(AccessDeniedException.class)
-    public ResponseEntity<String> handleAccessDenied(AccessDeniedException ex) {
-        return ResponseEntity.status(HttpStatus.FORBIDDEN).body(ex.getMessage());
-    }
-
-    @ExceptionHandler(WorkerAlreadyAssignedException.class)
-    public ResponseEntity<String> handleWorkerAlreadyAssigned(WorkerAlreadyAssignedException ex) {
-        return ResponseEntity.status(HttpStatus.CONFLICT).body(ex.getMessage());
-    }
-
-    @ExceptionHandler(RatingNotFoundException.class)
-    public ResponseEntity<String> handleRatingNotFound(RatingNotFoundException ex) {
-        return ResponseEntity.status(HttpStatus.NOT_FOUND).body(ex.getMessage());
-    }
-
-    @ExceptionHandler(MessagingException.class)
-    public ResponseEntity<String> handleMessagingException(MessagingException ex) {
-        return ResponseEntity.status(HttpStatus.CONFLICT).body(ex.getMessage());
-    }
-
-    @ExceptionHandler(VerifyException.class)
-    public ResponseEntity<String> handleVerifyException(VerifyException ex) {
-        return ResponseEntity.status(HttpStatus.CONFLICT).body(ex.getMessage());
-    }
-}
-
Index: serveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/web/controller/AdminController.java
===================================================================
--- ReserveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/web/controller/AdminController.java	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,74 +1,0 @@
-package mk.ukim.finki.it.reservengo.web.controller;
-
-import jakarta.mail.MessagingException;
-import mk.ukim.finki.it.reservengo.dto.adminDTO.DisplayAdminLocalsDTO;
-import mk.ukim.finki.it.reservengo.dto.localDTO.CreateLocalDTO;
-import mk.ukim.finki.it.reservengo.dto.userDTO.DisplayUserDTO;
-import mk.ukim.finki.it.reservengo.dto.userDTO.EditUserEmailDTO;
-import mk.ukim.finki.it.reservengo.service.intf.AdminService;
-import org.springframework.http.HttpStatus;
-import org.springframework.http.ResponseEntity;
-import org.springframework.security.access.prepost.PreAuthorize;
-import org.springframework.web.bind.annotation.*;
-
-import java.util.List;
-
-@RestController
-@RequestMapping("/api/admin")
-@PreAuthorize("hasRole('ADMIN')")
-public class AdminController {
-
-    private final AdminService adminService;
-
-    public AdminController(AdminService adminService) {
-        this.adminService = adminService;
-    }
-
-    @PostMapping("/add-local")
-    public ResponseEntity<Void> addLocal(@RequestBody CreateLocalDTO localDTO) {
-        adminService.addLocal(localDTO);
-        return new ResponseEntity<>(HttpStatus.CREATED);
-    }
-
-    @DeleteMapping("/delete-local/{id}")
-    public ResponseEntity<Void> deleteLocal(@PathVariable Long id) {
-        adminService.deleteLocal(id);
-        return new ResponseEntity<>(HttpStatus.OK);
-    }
-
-    @GetMapping("/locals")
-    public ResponseEntity<List<DisplayAdminLocalsDTO>> getLocals() {
-        List<DisplayAdminLocalsDTO> locals = adminService.getLocals();
-        return new ResponseEntity<>(locals, HttpStatus.OK);
-    }
-
-    @GetMapping("/local-managers/{id}")
-    public ResponseEntity<List<DisplayUserDTO>> getManagersForLocal(@PathVariable Long id) {
-        List<DisplayUserDTO> managers = adminService.findManagersByLocalId(id);
-        return new ResponseEntity<>(managers, HttpStatus.OK);
-    }
-
-    @GetMapping("/local-managers")
-    public ResponseEntity<List<DisplayUserDTO>> getManagers() {
-        List<DisplayUserDTO> managers = adminService.findUnassignedManagers();
-        return new ResponseEntity<>(managers, HttpStatus.OK);
-    }
-
-    @PostMapping("/assign/{localId}/{managerId}")
-    public ResponseEntity<Void> assignManagerToLocal(@PathVariable Long localId, @PathVariable Long managerId) {
-        adminService.assignManagerToLocal(localId, managerId);
-        return new ResponseEntity<>(HttpStatus.OK);
-    }
-
-    @DeleteMapping("/remove/{managerId}")
-    public ResponseEntity<Void> removeManagerFromLocal(@PathVariable Long managerId) {
-        adminService.removeManagerFromLocal(managerId);
-        return new ResponseEntity<>(HttpStatus.OK);
-    }
-
-    @PostMapping("/invite-manager")
-    public ResponseEntity<Void> inviteManager(@RequestBody EditUserEmailDTO emailDTO) throws MessagingException {
-        adminService.inviteManager(emailDTO);
-        return new ResponseEntity<>(HttpStatus.OK);
-    }
-}
Index: serveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/web/controller/AuthController.java
===================================================================
--- ReserveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/web/controller/AuthController.java	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,88 +1,0 @@
-package mk.ukim.finki.it.reservengo.web.controller;
-
-import jakarta.mail.MessagingException;
-import mk.ukim.finki.it.reservengo.dto.jwtDTO.JWTAuthenticationRequestDTO;
-import mk.ukim.finki.it.reservengo.dto.jwtDTO.JWTAuthenticationResponseDTO;
-import mk.ukim.finki.it.reservengo.dto.jwtDTO.JWTLoginDTO;
-import mk.ukim.finki.it.reservengo.dto.jwtDTO.VerificationDTO;
-import mk.ukim.finki.it.reservengo.service.intf.AuthService;
-import org.springframework.http.HttpStatus;
-import org.springframework.http.ResponseEntity;
-import org.springframework.web.bind.annotation.*;
-
-@RestController
-@RequestMapping("/api/auth")
-public class AuthController {
-    private final AuthService authenticationService;
-
-    public AuthController(AuthService authenticationService) {
-        this.authenticationService = authenticationService;
-    }
-
-    @PostMapping(value = "/register/customer")
-    public ResponseEntity<JWTAuthenticationResponseDTO> registerCustomer(@RequestBody JWTAuthenticationRequestDTO jwtAuthenticationRequestDTO) throws MessagingException {
-        return new ResponseEntity<>(authenticationService.registerCustomer(jwtAuthenticationRequestDTO), HttpStatus.CREATED);
-    }
-
-    @PostMapping("/register/local-worker")
-    public ResponseEntity<JWTAuthenticationResponseDTO> registerLocalWorker(@RequestBody JWTAuthenticationRequestDTO jwtAuthenticationRequestDTO,
-                                                                            @RequestHeader(value = "Invite-Token") String token) {
-        return new ResponseEntity<>(authenticationService.registerLocalWorker(jwtAuthenticationRequestDTO, token), HttpStatus.CREATED);
-    }
-
-    @PostMapping("/register/local-manager")
-    public ResponseEntity<JWTAuthenticationResponseDTO> registerLocalManager(@RequestBody JWTAuthenticationRequestDTO jwtAuthenticationRequestDTO,
-                                                                             @RequestHeader(value = "Invite-Token") String token) {
-        return new ResponseEntity<>(authenticationService.registerLocalManager(jwtAuthenticationRequestDTO, token), HttpStatus.CREATED);
-    }
-
-    @PostMapping("/login")
-    public ResponseEntity<JWTAuthenticationResponseDTO> login(@RequestBody JWTLoginDTO jwtLoginDTO) throws MessagingException {
-        return new ResponseEntity<>(authenticationService.login(jwtLoginDTO), HttpStatus.OK);
-    }
-
-    @PostMapping("/oauth/google/customer")
-    public ResponseEntity<JWTAuthenticationResponseDTO> registerGoogleCustomer(@RequestHeader(value = "X-Google-Token") String idToken) {
-        return new ResponseEntity<>(authenticationService.registerGoogleCustomer(idToken), HttpStatus.CREATED);
-    }
-
-    @PostMapping("/oauth/google/local-worker")
-    public ResponseEntity<JWTAuthenticationResponseDTO> registerGoogleLocalWorker(@RequestHeader(value = "X-Google-Token") String idToken,
-                                                                                  @RequestHeader(value = "Invite-Token") String inviteToken) {
-        return new ResponseEntity<>(authenticationService.registerGoogleLocalWorker(idToken, inviteToken), HttpStatus.CREATED);
-    }
-
-    @PostMapping("/oauth/google/local-manager")
-    public ResponseEntity<JWTAuthenticationResponseDTO> registerGoogleLocalManager(@RequestHeader(value = "X-Google-Token") String idToken,
-                                                                                   @RequestHeader(value = "Invite-Token") String inviteToken) {
-        return new ResponseEntity<>(authenticationService.registerGoogleLocalManager(idToken, inviteToken), HttpStatus.CREATED);
-    }
-
-    @PostMapping("/oauth/google/login")
-    public ResponseEntity<JWTAuthenticationResponseDTO> loginWithGoogle(@RequestHeader(value = "X-Google-Token") String idToken) {
-        return new ResponseEntity<>((authenticationService.loginWithGoogle(idToken)), HttpStatus.OK);
-    }
-
-    @PatchMapping("/enable")
-    public ResponseEntity<Void> reactivateAccount(@RequestBody JWTLoginDTO jwtLoginDTO) {
-        authenticationService.reactivateProfile(jwtLoginDTO);
-        return new ResponseEntity<>(HttpStatus.OK);
-    }
-
-    @GetMapping("/register/invite/check")
-    public ResponseEntity<Void> checkInvite() {
-        return new ResponseEntity<>(HttpStatus.OK);
-    }
-
-    @PatchMapping("/verify")
-    public ResponseEntity<Void> verifyAccount(@RequestBody VerificationDTO verificationDTO) throws MessagingException {
-        authenticationService.verifyCustomer(verificationDTO.email(), verificationDTO.verificationCode());
-        return new ResponseEntity<>(HttpStatus.OK);
-    }
-
-    @PostMapping("/resend-verification")
-    public ResponseEntity<Void> resendVerificationCode(@RequestBody VerificationDTO verificationDTO) throws MessagingException {
-        authenticationService.resendVerificationCode(verificationDTO.email());
-        return new ResponseEntity<>(HttpStatus.OK);
-    }
-}
Index: serveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/web/controller/CustomerController.java
===================================================================
--- ReserveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/web/controller/CustomerController.java	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,117 +1,0 @@
-package mk.ukim.finki.it.reservengo.web.controller;
-
-import mk.ukim.finki.it.reservengo.dto.customerDTO.RatingDTO;
-import mk.ukim.finki.it.reservengo.dto.eventDTO.DisplayEventDTO;
-import mk.ukim.finki.it.reservengo.dto.localDTO.DisplayLocalDTO;
-import mk.ukim.finki.it.reservengo.dto.reservationDTO.*;
-import mk.ukim.finki.it.reservengo.model.domain.User;
-import mk.ukim.finki.it.reservengo.service.intf.CustomerService;
-import org.springframework.http.HttpStatus;
-import org.springframework.http.ResponseEntity;
-import org.springframework.security.access.prepost.PreAuthorize;
-import org.springframework.security.core.annotation.AuthenticationPrincipal;
-import org.springframework.web.bind.annotation.*;
-
-import java.util.List;
-
-@RestController
-@RequestMapping("/api/customer")
-@PreAuthorize("hasRole('CUSTOMER')")
-public class CustomerController {
-
-    private final CustomerService customerService;
-
-    public CustomerController(CustomerService customerService) {
-        this.customerService = customerService;
-    }
-
-    @GetMapping("/favourite-locals")
-    public ResponseEntity<List<DisplayLocalDTO>> listFavouriteLocals(@AuthenticationPrincipal User user) {
-        List<DisplayLocalDTO> list = customerService.listFavouriteLocals(user.getId());
-        return new ResponseEntity<>(list, HttpStatus.OK);
-    }
-
-    @PostMapping("/favourite-locals/add/{id}")
-    public ResponseEntity<Void> addFavouriteLocal(@AuthenticationPrincipal User user, @PathVariable Long id) {
-        customerService.addFavouriteLocal(user.getId(), id);
-        return new ResponseEntity<>(HttpStatus.OK);
-    }
-
-    @PostMapping("/favourite-locals/remove/{id}")
-    public ResponseEntity<Void> removeFavouriteLocal(@AuthenticationPrincipal User user, @PathVariable Long id) {
-        customerService.removeFavouriteLocal(user.getId(), id);
-        return new ResponseEntity<>(HttpStatus.OK);
-    }
-
-    @GetMapping("/favourite-events")
-    public ResponseEntity<List<DisplayEventDTO>> listFavouriteEvents(@AuthenticationPrincipal User user) {
-        List<DisplayEventDTO> list = customerService.listFavouriteEvents(user.getId());
-        return new ResponseEntity<>(list, HttpStatus.OK);
-    }
-
-    @PostMapping("/favourite-events/add/{id}")
-    public ResponseEntity<Void> addFavouriteEvent(@AuthenticationPrincipal User user, @PathVariable Long id) {
-        customerService.addFavouriteEvent(user.getId(), id);
-        return new ResponseEntity<>(HttpStatus.OK);
-    }
-
-    @PostMapping("/favourite-events/remove/{id}")
-    public ResponseEntity<Void> removeFavouriteEvent(@AuthenticationPrincipal User user, @PathVariable Long id) {
-        customerService.removeFavouriteEvent(user.getId(), id);
-        return new ResponseEntity<>(HttpStatus.OK);
-    }
-
-    @PutMapping("/local/{id}/rate")
-    public ResponseEntity<Void> rateLocal(@AuthenticationPrincipal User user, @PathVariable Long id, @RequestBody RatingDTO ratingDTO) {
-        customerService.rateLocal(user.getId(), id, ratingDTO);
-        return new ResponseEntity<>(HttpStatus.OK);
-    }
-
-    @DeleteMapping("/local/{id}/remove-rating")
-    public ResponseEntity<Void> deleteRating(@AuthenticationPrincipal User user, @PathVariable Long id) {
-        customerService.removeRating(user.getId(), id);
-        return new ResponseEntity<>(HttpStatus.OK);
-    }
-
-    @GetMapping("/local/{id}/rating")
-    public ResponseEntity<RatingDTO> getRatingForLocal(@AuthenticationPrincipal User user, @PathVariable Long id) {
-        RatingDTO ratingDTO = RatingDTO.from(customerService.findLocalRating(user.getId(), id));
-        return new ResponseEntity<>(ratingDTO, HttpStatus.OK);
-    }
-
-    @GetMapping("/reservations")
-    public ResponseEntity<List<DisplayReservationDTO>> listCustomerReservations(@AuthenticationPrincipal User user) {
-        List<DisplayReservationDTO> allReservation = customerService.listAllReservations(user.getId());
-        return new ResponseEntity<>(allReservation, HttpStatus.OK);
-    }
-
-    @GetMapping("/reservations/{reservationId}")
-    public ResponseEntity<DisplayReservationDTO> getReservationDetails(@AuthenticationPrincipal User user, @PathVariable Long reservationId) {
-        DisplayReservationDTO reservationDTO = customerService.getReservationPreview(user.getId(), reservationId);
-        return new ResponseEntity<>(reservationDTO, HttpStatus.OK);
-    }
-
-    @PutMapping("/reservations/{reservationId}/cancel")
-    public ResponseEntity<Void> cancelReservation(@AuthenticationPrincipal User user, @PathVariable Long reservationId) {
-        customerService.cancelReservation(user.getId(), reservationId);
-        return new ResponseEntity<>(HttpStatus.OK);
-    }
-
-    @PutMapping("/reservations/{reservationId}/edit")
-    public ResponseEntity<DisplayReservationDTO> editReservation(@AuthenticationPrincipal User user, @PathVariable Long reservationId, @RequestBody EditReservationDTO editReservationDTO) {
-        DisplayReservationDTO editedReservationDTO = customerService.editReservation(user.getId(), reservationId, editReservationDTO);
-        return new ResponseEntity<>(editedReservationDTO, HttpStatus.OK);
-    }
-
-    @PostMapping("/reservations/{localId}/create")
-    public ResponseEntity<Void> makeReservation(@AuthenticationPrincipal User user, @PathVariable Long localId, @RequestBody CreateReservationDTO createReservationDTO) {
-        customerService.makeReservation(user.getId(), localId, createReservationDTO);
-        return new ResponseEntity<>(HttpStatus.CREATED);
-    }
-
-    @DeleteMapping("/reservations/delete")
-    public ResponseEntity<Void> deleteReservation(@AuthenticationPrincipal User user, @RequestBody DeleteReservationDTO deleteReservationDTO) {
-        customerService.deleteReservation(user.getId(), deleteReservationDTO);
-        return new ResponseEntity<>(HttpStatus.OK);
-    }
-}
Index: serveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/web/controller/EventController.java
===================================================================
--- ReserveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/web/controller/EventController.java	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,45 +1,0 @@
-package mk.ukim.finki.it.reservengo.web.controller;
-
-import mk.ukim.finki.it.reservengo.dto.eventDTO.DisplayEventDTO;
-import mk.ukim.finki.it.reservengo.dto.eventDTO.PagedEventDTO;
-import mk.ukim.finki.it.reservengo.model.domain.Local;
-import mk.ukim.finki.it.reservengo.model.enumerations.EventStatus;
-import mk.ukim.finki.it.reservengo.model.enumerations.EventType;
-import mk.ukim.finki.it.reservengo.service.intf.EventService;
-import mk.ukim.finki.it.reservengo.service.intf.LocalService;
-import org.springframework.data.domain.Page;
-import org.springframework.http.HttpStatus;
-import org.springframework.http.ResponseEntity;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RequestParam;
-import org.springframework.web.bind.annotation.RestController;
-
-@RestController
-@RequestMapping("/api/events")
-public class EventController {
-    private final EventService eventService;
-    private final LocalService localService;
-
-    public EventController(EventService eventService, LocalService localService) {
-        this.eventService = eventService;
-        this.localService = localService;
-    }
-
-    @GetMapping
-    public ResponseEntity<PagedEventDTO> getEvents(
-            @RequestParam(required = false) Long localId,
-            @RequestParam(required = false) String name,
-            @RequestParam(required = false) EventType eventType,
-            @RequestParam(required = false) EventStatus eventStatus, // active, upcoming
-            @RequestParam(required = false, defaultValue = "name") String sortBy, // created at, name
-            @RequestParam(required = false, defaultValue = "asc") String direction,
-            @RequestParam(defaultValue = "0") int page,
-            @RequestParam(defaultValue = "10") int size
-    ) {
-        Local local = localId == null ? null : localService.findLocalById(localId);
-        Page<DisplayEventDTO> dtoPage = eventService.searchEvents(local, name, eventType, eventStatus, page, size, sortBy, direction);
-        PagedEventDTO pagedEventDTO = PagedEventDTO.from(dtoPage);
-        return new ResponseEntity<>(pagedEventDTO, HttpStatus.OK);
-    }
-}
Index: serveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/web/controller/LocalController.java
===================================================================
--- ReserveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/web/controller/LocalController.java	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,47 +1,0 @@
-package mk.ukim.finki.it.reservengo.web.controller;
-
-import mk.ukim.finki.it.reservengo.dto.localDTO.DisplayLocalDTO;
-import mk.ukim.finki.it.reservengo.dto.localDTO.DisplayLocalDetailsDTO;
-import mk.ukim.finki.it.reservengo.dto.localDTO.PagedLocalDTO;
-import mk.ukim.finki.it.reservengo.model.enumerations.LocalType;
-import mk.ukim.finki.it.reservengo.model.enumerations.ProvidedService;
-import mk.ukim.finki.it.reservengo.service.intf.LocalService;
-import org.springframework.data.domain.Page;
-import org.springframework.http.HttpStatus;
-import org.springframework.http.ResponseEntity;
-import org.springframework.web.bind.annotation.*;
-
-import java.util.List;
-
-@RestController
-@RequestMapping("/api/locals")
-public class LocalController {
-
-    private final LocalService localService;
-
-    public LocalController(LocalService localService) {
-        this.localService = localService;
-    }
-
-    @GetMapping
-    public ResponseEntity<PagedLocalDTO> getLocals(
-            @RequestParam(required = false) String name,
-            @RequestParam(required = false) List<ProvidedService> services,
-            @RequestParam(required = false) LocalType localType,
-            @RequestParam(required = false) Boolean isOpen,
-            @RequestParam(required = false, defaultValue = "name") String sortBy, // created at, rating, name
-            @RequestParam(required = false, defaultValue = "asc") String direction,
-            @RequestParam(defaultValue = "0") int page,
-            @RequestParam(defaultValue = "10") int size
-    ) {
-        Page<DisplayLocalDTO> dtoPage = localService.searchLocals(name, services, localType, isOpen, page, size, sortBy, direction);
-        PagedLocalDTO pagedLocalDTO = PagedLocalDTO.from(dtoPage);
-        return new ResponseEntity<>(pagedLocalDTO, HttpStatus.OK);
-    }
-
-    @GetMapping("/{id}")
-    public ResponseEntity<DisplayLocalDetailsDTO> getLocalDetails(@PathVariable Long id) {
-        DisplayLocalDetailsDTO local = DisplayLocalDetailsDTO.from(localService.findLocalById(id));
-        return new ResponseEntity<>(local, HttpStatus.OK);
-    }
-}
Index: serveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/web/controller/LocalManagerController.java
===================================================================
--- ReserveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/web/controller/LocalManagerController.java	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,127 +1,0 @@
-package mk.ukim.finki.it.reservengo.web.controller;
-
-import jakarta.mail.MessagingException;
-import mk.ukim.finki.it.reservengo.dto.eventDTO.CreateEventDTO;
-import mk.ukim.finki.it.reservengo.dto.eventDTO.DisplayEventDTO;
-import mk.ukim.finki.it.reservengo.dto.localDTO.CreateLocalDetailsDTO;
-import mk.ukim.finki.it.reservengo.dto.localDTO.DeleteLocalPhotosDTO;
-import mk.ukim.finki.it.reservengo.dto.localDTO.DeleteLocalPhotosResultDTO;
-import mk.ukim.finki.it.reservengo.dto.localDTO.DisplayLocalDetailsDTO;
-import mk.ukim.finki.it.reservengo.dto.userDTO.EditUserEmailDTO;
-import mk.ukim.finki.it.reservengo.dto.workerDTO.DisplayWorkerDTO;
-import mk.ukim.finki.it.reservengo.dto.workerDTO.PositionDTO;
-import mk.ukim.finki.it.reservengo.model.domain.Local;
-import mk.ukim.finki.it.reservengo.model.domain.User;
-import mk.ukim.finki.it.reservengo.service.intf.LocalManagerService;
-import org.springframework.http.HttpStatus;
-import org.springframework.http.ResponseEntity;
-import org.springframework.security.access.prepost.PreAuthorize;
-import org.springframework.security.core.annotation.AuthenticationPrincipal;
-import org.springframework.web.bind.annotation.*;
-import org.springframework.web.multipart.MultipartFile;
-
-import java.util.List;
-
-@RestController
-@RequestMapping("/api/local-manager")
-@PreAuthorize("hasRole('LOCAL_MANAGER')")
-public class LocalManagerController {
-
-    private final LocalManagerService localManagerService;
-
-    public LocalManagerController(LocalManagerService localManagerService) {
-        this.localManagerService = localManagerService;
-    }
-
-    @GetMapping("/my-local")
-    public ResponseEntity<DisplayLocalDetailsDTO> getLocalForManager(@AuthenticationPrincipal User user) {
-        DisplayLocalDetailsDTO displayLocalDetailsDTO = DisplayLocalDetailsDTO.from(localManagerService.findLocalByManagerId(user.getId()));
-        return new ResponseEntity<>(displayLocalDetailsDTO, HttpStatus.OK);
-    }
-
-    @PutMapping("/my-local/edit")
-    public ResponseEntity<DisplayLocalDetailsDTO> editLocal(@AuthenticationPrincipal User user, @RequestBody CreateLocalDetailsDTO createLocalDetailsDTO) {
-        DisplayLocalDetailsDTO displayLocalDetailsDTO = DisplayLocalDetailsDTO.from(localManagerService.editLocal(user.getId(), createLocalDetailsDTO));
-        return new ResponseEntity<>(displayLocalDetailsDTO, HttpStatus.OK);
-    }
-
-    @PostMapping("/upload-logo")
-    public ResponseEntity<String> uploadLogo(@AuthenticationPrincipal User user, @RequestParam("logo") MultipartFile logoFile) {
-        String logoUrl = localManagerService.uploadLocalLogo(user.getId(), logoFile);
-        return new ResponseEntity<>(logoUrl, HttpStatus.OK);
-    }
-
-    @DeleteMapping("/delete-logo")
-    public ResponseEntity<Void> deleteLocalLogo(@AuthenticationPrincipal User user) {
-        localManagerService.deleteLocalLogo(user.getId());
-        return new ResponseEntity<>(HttpStatus.OK);
-    }
-
-    @PostMapping("/upload-photo")
-    public ResponseEntity<String> uploadLocalPhotos(@AuthenticationPrincipal User user, @RequestParam("photo") MultipartFile photoFile) {
-        String photoUrl = localManagerService.uploadLocalPhoto(user.getId(), photoFile);
-        return new ResponseEntity<>(photoUrl, HttpStatus.OK);
-    }
-
-    @DeleteMapping("/delete-photos")
-    public ResponseEntity<DeleteLocalPhotosResultDTO> deleteLocalPhotos(@AuthenticationPrincipal User user, @RequestBody DeleteLocalPhotosDTO deleteLocalPhotosDTO) {
-        DeleteLocalPhotosResultDTO resultDTO = localManagerService.deleteLocalPhoto(user.getId(), deleteLocalPhotosDTO);
-        return new ResponseEntity<>(resultDTO, HttpStatus.MULTI_STATUS);
-    }
-
-    @PostMapping("/add-event")
-    public ResponseEntity<Void> addEvent(@AuthenticationPrincipal User user, @RequestBody CreateEventDTO createEventDTO) {
-        localManagerService.addEvent(user.getId(), createEventDTO);
-        return new ResponseEntity<>(HttpStatus.CREATED);
-    }
-
-    @DeleteMapping("/delete-event/{id}")
-    public ResponseEntity<Void> deleteEvent(@AuthenticationPrincipal User user, @PathVariable Long id) {
-        localManagerService.deleteEvent(user.getId(), id);
-        return new ResponseEntity<>(HttpStatus.OK);
-    }
-
-    @PutMapping("/events/edit/{id}")
-    public ResponseEntity<DisplayEventDTO> editEvent(@AuthenticationPrincipal User user, @PathVariable Long id, @RequestBody CreateEventDTO createEventDTO) {
-        DisplayEventDTO dto = DisplayEventDTO.fromEvent(localManagerService.editEvent(user.getId(), id, createEventDTO));
-        return new ResponseEntity<>(dto, HttpStatus.OK);
-    }
-
-    @GetMapping("/local-workers")
-    public ResponseEntity<List<DisplayWorkerDTO>> getWorkersForLocal(@AuthenticationPrincipal User user) {
-        Local local = localManagerService.findLocalByManagerId(user.getId());
-        List<DisplayWorkerDTO> workers = DisplayWorkerDTO.fromWorkers(localManagerService.findWorkersByLocal(local));
-        return new ResponseEntity<>(workers, HttpStatus.OK);
-    }
-
-    @GetMapping("/workers")
-    public ResponseEntity<List<DisplayWorkerDTO>> getWorkers() {
-        List<DisplayWorkerDTO> workers = DisplayWorkerDTO.fromWorkers(localManagerService.findUnassignedWorkers());
-        return new ResponseEntity<>(workers, HttpStatus.OK);
-    }
-
-    @PostMapping("/assign/{workerId}")
-    public ResponseEntity<Void> assignWorkerToLocal(@AuthenticationPrincipal User user, @PathVariable Long workerId) {
-        Local local = localManagerService.findLocalByManagerId(user.getId());
-        localManagerService.assignWorkerToLocal(local, workerId);
-        return new ResponseEntity<>(HttpStatus.OK);
-    }
-
-    @DeleteMapping("/remove/{workerId}")
-    public ResponseEntity<Void> removeWorkerFromLocal(@AuthenticationPrincipal User user, @PathVariable Long workerId) {
-        localManagerService.removeWorkerFromLocal(user.getId(), workerId);
-        return new ResponseEntity<>(HttpStatus.OK);
-    }
-
-    @PutMapping("/change-position/{workerId}")
-    public ResponseEntity<Void> changeWorkerPosition(@AuthenticationPrincipal User user, @PathVariable Long workerId, @RequestBody PositionDTO positionDTO) {
-        localManagerService.changePosition(user.getId(), workerId, positionDTO);
-        return new ResponseEntity<>(HttpStatus.OK);
-    }
-
-    @PostMapping("/invite-worker")
-    public ResponseEntity<Void> inviteWorker(@AuthenticationPrincipal User user, @RequestBody EditUserEmailDTO emailDTO) throws MessagingException {
-        localManagerService.inviteWorker(user.getId(), emailDTO);
-        return new ResponseEntity<>(HttpStatus.OK);
-    }
-}
Index: serveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/web/controller/LocalWorkerController.java
===================================================================
--- ReserveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/web/controller/LocalWorkerController.java	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,58 +1,0 @@
-package mk.ukim.finki.it.reservengo.web.controller;
-
-import jakarta.mail.MessagingException;
-import mk.ukim.finki.it.reservengo.dto.reservationDTO.DeleteReservationDTO;
-import mk.ukim.finki.it.reservengo.dto.workerDTO.DisplayLocalReservationDTO;
-import mk.ukim.finki.it.reservengo.model.domain.User;
-import mk.ukim.finki.it.reservengo.model.enumerations.ReservationStatus;
-import mk.ukim.finki.it.reservengo.service.intf.LocalWorkerService;
-import org.springframework.http.HttpStatus;
-import org.springframework.http.ResponseEntity;
-import org.springframework.security.core.annotation.AuthenticationPrincipal;
-import org.springframework.web.bind.annotation.*;
-
-import java.util.List;
-
-@RestController
-@RequestMapping("/api/local-worker")
-public class LocalWorkerController {
-    private final LocalWorkerService localWorkerService;
-
-    public LocalWorkerController(LocalWorkerService localWorkerService) {
-        this.localWorkerService = localWorkerService;
-    }
-
-    @GetMapping("/reservations")
-    public ResponseEntity<List<DisplayLocalReservationDTO>> viewLocalReservations(@RequestParam(required = false) ReservationStatus status, @AuthenticationPrincipal User user) {
-        List<DisplayLocalReservationDTO> reservations = localWorkerService.viewWorkerLocalReservations(user.getId(), status);
-        return new ResponseEntity<>(reservations, HttpStatus.OK);
-    }
-
-    @PutMapping("/reservations/{reservationId}/accept")
-    public ResponseEntity<Void> acceptReservation(@PathVariable Long reservationId, @AuthenticationPrincipal User user) throws MessagingException {
-        localWorkerService.acceptReservation(user.getId(), reservationId);
-        return new ResponseEntity<>(HttpStatus.OK);
-    }
-
-    @PutMapping("/reservations/{reservationId}/deny")
-    public ResponseEntity<Void> denyReservation(@PathVariable Long reservationId, @AuthenticationPrincipal User user) throws MessagingException {
-        localWorkerService.denyReservation(user.getId(), reservationId);
-        return new ResponseEntity<>(HttpStatus.OK);
-    }
-
-    @PutMapping("/reservations/{reservationId}/finish")
-    public ResponseEntity<Void> finishReservation(
-            @PathVariable Long reservationId,
-            @AuthenticationPrincipal User user) {
-        localWorkerService.finishReservation(user.getId(), reservationId);
-        return new ResponseEntity<>(HttpStatus.OK);
-    }
-
-    @DeleteMapping("/reservations/delete")
-    public ResponseEntity<Void> deleteReservation(@AuthenticationPrincipal User user, @RequestBody DeleteReservationDTO deleteReservationDTO) {
-        localWorkerService.deleteReservation(user.getId(), deleteReservationDTO);
-        return new ResponseEntity<>(HttpStatus.OK);
-    }
-}
-
-
Index: serveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/web/controller/UserController.java
===================================================================
--- ReserveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/web/controller/UserController.java	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,65 +1,0 @@
-package mk.ukim.finki.it.reservengo.web.controller;
-
-import mk.ukim.finki.it.reservengo.dto.userDTO.*;
-import mk.ukim.finki.it.reservengo.model.domain.User;
-import mk.ukim.finki.it.reservengo.service.intf.UserService;
-import org.springframework.http.HttpStatus;
-import org.springframework.http.ResponseEntity;
-import org.springframework.security.core.annotation.AuthenticationPrincipal;
-import org.springframework.web.bind.annotation.*;
-import org.springframework.web.multipart.MultipartFile;
-
-
-@RestController
-@RequestMapping("/api/user")
-public class UserController {
-
-    private final UserService userService;
-
-    public UserController(UserService userService) {
-        this.userService = userService;
-    }
-
-    @GetMapping("/profile")
-    public ResponseEntity<DisplayUserDTO> getProfile(@AuthenticationPrincipal User user) {
-        DisplayUserDTO displayUserDTO = DisplayUserDTO.fromUser(userService.findUserById(user.getId()));
-        return new ResponseEntity<>(displayUserDTO, HttpStatus.OK);
-    }
-
-    @PutMapping("/edit")
-    public ResponseEntity<DisplayUserDTO> editProfile(@AuthenticationPrincipal User user, @RequestBody EditUserProfileDTO editUserProfileDTO) {
-        DisplayUserDTO displayUserDTO = DisplayUserDTO.fromUser(userService.editUser(user.getId(), editUserProfileDTO));
-        return new ResponseEntity<>(displayUserDTO, HttpStatus.OK);
-    }
-
-    @PatchMapping("/change-email")
-    public ResponseEntity<DisplayUserEmailDTO> changeEmail(@AuthenticationPrincipal User user, @RequestBody EditUserEmailDTO editUserEmailDTO) {
-        DisplayUserEmailDTO displayUserEmailDTO = userService.changeEmail(user.getId(), editUserEmailDTO);
-        return new ResponseEntity<>(displayUserEmailDTO, HttpStatus.OK);
-    }
-
-    @PatchMapping("/change-password")
-    public ResponseEntity<Void> changePassword(@AuthenticationPrincipal User user, @RequestBody EditUserPasswordDTO editUserPasswordDTO) {
-        userService.changePassword(user.getId(), editUserPasswordDTO);
-        return new ResponseEntity<>(HttpStatus.OK);
-    }
-
-    @PostMapping("/upload-avatar")
-    public ResponseEntity<String> uploadLogo(@AuthenticationPrincipal User user,
-                                             @RequestParam("avatar") MultipartFile logoFile) {
-        String logoUrl = userService.uploadProfilePhoto(user.getId(), logoFile);
-        return new ResponseEntity<>(logoUrl, HttpStatus.OK);
-    }
-
-    @DeleteMapping("/delete-avatar")
-    public ResponseEntity<Void> deleteLocalLogo(@AuthenticationPrincipal User user) {
-        userService.deleteProfilePhoto(user.getId());
-        return new ResponseEntity<>(HttpStatus.OK);
-    }
-
-    @PatchMapping("/disable")
-    public ResponseEntity<Void> disableUser(@AuthenticationPrincipal User user) {
-        userService.disableProfile(user.getId());
-        return new ResponseEntity<>(HttpStatus.OK);
-    }
-}
Index: serveNGo-backend/src/main/resources/application-dev.properties
===================================================================
--- ReserveNGo-backend/src/main/resources/application-dev.properties	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,20 +1,0 @@
-spring.datasource.url=jdbc:h2:mem:testdb
-
-spring.datasource.username=${H2_DB_USER}
-spring.datasource.password=${H2_DB_PASSWORD}
-
-spring.jpa.hibernate.ddl-auto=create-drop
-spring.h2.console.enabled=true
-spring.h2.console.path=/h2
-
-spring.mail.host=${MAIL_HOST}
-spring.mail.port=${MAIL_PORT}
-spring.mail.username=${MAIL_USERNAME}
-spring.mail.password=${MAIL_PASSWORD}
-spring.mail.properties.mail.transport.protocol=smtp
-spring.mail.properties.mail.smtp.auth=true
-spring.mail.properties.mail.smtp.starttls.enable=true
-spring.mail.properties.mail.debug=true
-
-spring.security.oauth2.client.registration.google.client-id=${CLIENT_ID}
-spring.security.oauth2.client.registration.google.client-secret=${CLIENT_SECRET}
Index: serveNGo-backend/src/main/resources/application-prod.properties
===================================================================
--- ReserveNGo-backend/src/main/resources/application-prod.properties	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,19 +1,0 @@
-spring.datasource.url=jdbc:postgresql://${PG_DB_HOST}:${PG_DB_PORT}/resngo
-
-spring.datasource.username=${PG_DB_USER}
-spring.datasource.password=${PG_DB_PASSWORD}
-
-spring.jpa.hibernate.ddl-auto=update
-spring.jpa.show-sql=true
-
-spring.mail.host=${MAIL_HOST}
-spring.mail.port=${MAIL_PORT}
-spring.mail.username=${MAIL_USERNAME}
-spring.mail.password=${MAIL_PASSWORD}
-spring.mail.properties.mail.transport.protocol=smtp
-spring.mail.properties.mail.smtp.auth=true
-spring.mail.properties.mail.smtp.starttls.enable=true
-
-
-spring.security.oauth2.client.registration.google.client-id=${CLIENT_ID}
-spring.security.oauth2.client.registration.google.client-secret=${CLIENT_SECRET}
Index: serveNGo-backend/src/main/resources/application.properties
===================================================================
--- ReserveNGo-backend/src/main/resources/application.properties	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,10 +1,0 @@
-spring.application.name=ReserveNGo
-server.port=8080
-spring.profiles.active=dev
-
-spring.servlet.multipart.max-file-size=10MB
-spring.servlet.multipart.max-request-size=20MB
-
-frontend.url=http://localhost:5173
-
-spring.security.oauth2.client.registration.google.scope=openid,profile,email
Index: serveNGo-backend/src/test/java/mk/ukim/finki/it/reservengo/ReserveNGoApplicationTests.java
===================================================================
--- ReserveNGo-backend/src/test/java/mk/ukim/finki/it/reservengo/ReserveNGoApplicationTests.java	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,8 +1,0 @@
-package mk.ukim.finki.it.reservengo;
-
-import org.springframework.boot.test.context.SpringBootTest;
-
-@SpringBootTest
-class ReserveNGoApplicationTests {
-
-}
Index: serveNGo-frontend/.editorconfig
===================================================================
--- ReserveNGo-frontend/.editorconfig	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,9 +1,0 @@
-[*.{js,jsx,mjs,cjs,ts,tsx,mts,cts,vue}]
-charset = utf-8
-indent_size = 2
-indent_style = space
-insert_final_newline = true
-trim_trailing_whitespace = true
-
-end_of_line = lf
-max_line_length = 100
Index: serveNGo-frontend/.env.example
===================================================================
--- ReserveNGo-frontend/.env.example	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,2 +1,0 @@
-VITE_API_BASE_URL=your_vite_api_base_url
-VITE_GOOGLE_CLIENT_ID=your_vite_google_client_id
Index: serveNGo-frontend/.gitattributes
===================================================================
--- ReserveNGo-frontend/.gitattributes	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,1 +1,0 @@
-* text=auto eol=lf
Index: serveNGo-frontend/.gitignore
===================================================================
--- ReserveNGo-frontend/.gitignore	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,30 +1,0 @@
-# Logs
-logs
-*.log
-npm-debug.log*
-yarn-debug.log*
-yarn-error.log*
-pnpm-debug.log*
-lerna-debug.log*
-
-node_modules
-.DS_Store
-dist
-dist-ssr
-coverage
-*.local
-
-/cypress/videos/
-/cypress/screenshots/
-
-# Editor directories and files
-.vscode/*
-!.vscode/extensions.json
-.idea/*
-*.suo
-*.ntvs*
-*.njsproj
-*.sln
-*.sw?
-
-*.tsbuildinfo
Index: serveNGo-frontend/.prettierrc.json
===================================================================
--- ReserveNGo-frontend/.prettierrc.json	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,7 +1,0 @@
-
-{
-  "$schema": "https://json.schemastore.org/prettierrc",
-  "semi": false,
-  "singleQuote": true,
-  "printWidth": 100
-}
Index: serveNGo-frontend/.vscode/extensions.json
===================================================================
--- ReserveNGo-frontend/.vscode/extensions.json	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,9 +1,0 @@
-{
-  "recommendations": [
-    "Vue.volar",
-    "vitest.explorer",
-    "dbaeumer.vscode-eslint",
-    "EditorConfig.EditorConfig",
-    "esbenp.prettier-vscode"
-  ]
-}
Index: serveNGo-frontend/Dockerfile
===================================================================
--- ReserveNGo-frontend/Dockerfile	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,28 +1,0 @@
-# ---------- Build stage ----------
-FROM node:20-alpine AS build
-
-WORKDIR /app
-
-ARG VITE_API_BASE_URL
-ARG VITE_GOOGLE_CLIENT_ID
-
-COPY package*.json ./
-RUN npm ci
-
-COPY . .
-
-RUN npm run build
-
-
-# ---------- Runtime stage ----------
-FROM nginx:alpine
-
-RUN rm /etc/nginx/conf.d/default.conf
-
-COPY nginx.conf /etc/nginx/conf.d/default.conf
-
-COPY --from=build /app/dist /usr/share/nginx/html
-
-EXPOSE 80
-
-CMD ["nginx", "-g", "daemon off;"]
Index: serveNGo-frontend/README.md
===================================================================
--- ReserveNGo-frontend/README.md	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,41 +1,0 @@
-# vue-project
-
-This template should help get you started developing with Vue 3 in Vite.
-
-## Recommended IDE Setup
-
-[VSCode](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (and disable Vetur).
-
-## Customize configuration
-
-See [Vite Configuration Reference](https://vite.dev/config/).
-
-## Project Setup
-
-```sh
-npm install
-```
-
-### Compile and Hot-Reload for Development
-
-```sh
-npm run dev
-```
-
-### Compile and Minify for Production
-
-```sh
-npm run build
-```
-
-### Run Unit Tests with [Vitest](https://vitest.dev/)
-
-```sh
-npm run test:unit
-```
-
-### Lint with [ESLint](https://eslint.org/)
-
-```sh
-npm run lint
-```
Index: serveNGo-frontend/eslint.config.js
===================================================================
--- ReserveNGo-frontend/eslint.config.js	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,25 +1,0 @@
-import js from '@eslint/js'
-import pluginVue from 'eslint-plugin-vue'
-import pluginVitest from '@vitest/eslint-plugin'
-import skipFormatting from '@vue/eslint-config-prettier/skip-formatting'
-
-export default [
-  {
-    name: 'app/files-to-lint',
-    files: ['**/*.{js,mjs,jsx,vue}'],
-  },
-
-  {
-    name: 'app/files-to-ignore',
-    ignores: ['**/dist/**', '**/dist-ssr/**', '**/coverage/**'],
-  },
-
-  js.configs.recommended,
-  ...pluginVue.configs['flat/essential'],
-
-  {
-    ...pluginVitest.configs.recommended,
-    files: ['src/**/__tests__/*'],
-  },
-  skipFormatting,
-]
Index: serveNGo-frontend/index.html
===================================================================
--- ReserveNGo-frontend/index.html	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,13 +1,0 @@
-<!DOCTYPE html>
-<html lang="">
-<head>
-  <meta charset="UTF-8">
-  <meta name="viewport" content="width=device-width, initial-scale=1.0">
-  <title>ReserveNGo</title>
-  <meta name="theme-color" content="#9B177E">
-</head>
-<body>
-<div id="app"></div>
-<script type="module" src="/src/main.js"></script>
-</body>
-</html>
Index: serveNGo-frontend/jsconfig.json
===================================================================
--- ReserveNGo-frontend/jsconfig.json	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,8 +1,0 @@
-{
-  "compilerOptions": {
-    "paths": {
-      "@/*": ["./src/*"]
-    }
-  },
-  "exclude": ["node_modules", "dist"]
-}
Index: serveNGo-frontend/nginx.conf
===================================================================
--- ReserveNGo-frontend/nginx.conf	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,17 +1,0 @@
-server {
-    listen 80;
-    server_name localhost;
-
-    root /usr/share/nginx/html;
-    index index.html;
-
-    # SPA routing
-    location / {
-        try_files $uri $uri/ /index.html;
-    }
-
-    location ~* \.(js|css|png|jpg|jpeg|gif|svg|ico|woff2?)$ {
-        expires 1y;
-        add_header Cache-Control "public, immutable";
-    }
-}
Index: serveNGo-frontend/package-lock.json
===================================================================
--- ReserveNGo-frontend/package-lock.json	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,7284 +1,0 @@
-{
-  "name": "vue-project",
-  "version": "0.0.0",
-  "lockfileVersion": 3,
-  "requires": true,
-  "packages": {
-    "": {
-      "name": "vue-project",
-      "version": "0.0.0",
-      "dependencies": {
-        "@fortawesome/fontawesome-free": "^6.7.2",
-        "@mdi/font": "^7.4.47",
-        "bootstrap": "^5.3.8",
-        "pinia": "^2.3.1",
-        "sass": "^1.89.0",
-        "sass-loader": "^13.3.3",
-        "vue": "^3.5.13",
-        "vue-router": "^4.5.0",
-        "vue3-google-login": "^2.0.34",
-        "vue3-google-signin": "^2.1.1",
-        "vue3-otp-input": "^0.5.40",
-        "vuetify": "^3.8.0-beta.0"
-      },
-      "devDependencies": {
-        "@eslint/js": "^9.18.0",
-        "@typescript-eslint/eslint-plugin": "^8.54.0",
-        "@typescript-eslint/parser": "^8.54.0",
-        "@vitejs/plugin-vue": "^5.2.1",
-        "@vitest/eslint-plugin": "1.1.25",
-        "@vue/eslint-config-prettier": "^10.1.0",
-        "@vue/test-utils": "^2.4.6",
-        "eslint": "^9.18.0",
-        "eslint-plugin-vue": "^9.32.0",
-        "jsdom": "^26.0.0",
-        "prettier": "^3.4.2",
-        "vite": "^6.0.11",
-        "vite-plugin-vue-devtools": "^7.7.0",
-        "vitest": "^3.0.2"
-      }
-    },
-    "node_modules/@ampproject/remapping": {
-      "version": "2.3.0",
-      "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz",
-      "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==",
-      "dev": true,
-      "license": "Apache-2.0",
-      "dependencies": {
-        "@jridgewell/gen-mapping": "^0.3.5",
-        "@jridgewell/trace-mapping": "^0.3.24"
-      },
-      "engines": {
-        "node": ">=6.0.0"
-      }
-    },
-    "node_modules/@antfu/utils": {
-      "version": "0.7.10",
-      "resolved": "https://registry.npmjs.org/@antfu/utils/-/utils-0.7.10.tgz",
-      "integrity": "sha512-+562v9k4aI80m1+VuMHehNJWLOFjBnXn3tdOitzD0il5b7smkSBal4+a3oKiQTbrwMmN/TBUMDvbdoWDehgOww==",
-      "dev": true,
-      "license": "MIT",
-      "funding": {
-        "url": "https://github.com/sponsors/antfu"
-      }
-    },
-    "node_modules/@asamuzakjp/css-color": {
-      "version": "2.8.3",
-      "resolved": "https://registry.npmjs.org/@asamuzakjp/css-color/-/css-color-2.8.3.tgz",
-      "integrity": "sha512-GIc76d9UI1hCvOATjZPyHFmE5qhRccp3/zGfMPapK3jBi+yocEzp6BBB0UnfRYP9NP4FANqUZYb0hnfs3TM3hw==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "@csstools/css-calc": "^2.1.1",
-        "@csstools/css-color-parser": "^3.0.7",
-        "@csstools/css-parser-algorithms": "^3.0.4",
-        "@csstools/css-tokenizer": "^3.0.3",
-        "lru-cache": "^10.4.3"
-      }
-    },
-    "node_modules/@babel/code-frame": {
-      "version": "7.26.2",
-      "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.26.2.tgz",
-      "integrity": "sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "@babel/helper-validator-identifier": "^7.25.9",
-        "js-tokens": "^4.0.0",
-        "picocolors": "^1.0.0"
-      },
-      "engines": {
-        "node": ">=6.9.0"
-      }
-    },
-    "node_modules/@babel/compat-data": {
-      "version": "7.26.5",
-      "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.26.5.tgz",
-      "integrity": "sha512-XvcZi1KWf88RVbF9wn8MN6tYFloU5qX8KjuF3E1PVBmJ9eypXfs4GRiJwLuTZL0iSnJUKn1BFPa5BPZZJyFzPg==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">=6.9.0"
-      }
-    },
-    "node_modules/@babel/core": {
-      "version": "7.26.0",
-      "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.26.0.tgz",
-      "integrity": "sha512-i1SLeK+DzNnQ3LL/CswPCa/E5u4lh1k6IAEphON8F+cXt0t9euTshDru0q7/IqMa1PMPz5RnHuHscF8/ZJsStg==",
-      "dev": true,
-      "license": "MIT",
-      "peer": true,
-      "dependencies": {
-        "@ampproject/remapping": "^2.2.0",
-        "@babel/code-frame": "^7.26.0",
-        "@babel/generator": "^7.26.0",
-        "@babel/helper-compilation-targets": "^7.25.9",
-        "@babel/helper-module-transforms": "^7.26.0",
-        "@babel/helpers": "^7.26.0",
-        "@babel/parser": "^7.26.0",
-        "@babel/template": "^7.25.9",
-        "@babel/traverse": "^7.25.9",
-        "@babel/types": "^7.26.0",
-        "convert-source-map": "^2.0.0",
-        "debug": "^4.1.0",
-        "gensync": "^1.0.0-beta.2",
-        "json5": "^2.2.3",
-        "semver": "^6.3.1"
-      },
-      "engines": {
-        "node": ">=6.9.0"
-      },
-      "funding": {
-        "type": "opencollective",
-        "url": "https://opencollective.com/babel"
-      }
-    },
-    "node_modules/@babel/core/node_modules/semver": {
-      "version": "6.3.1",
-      "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
-      "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
-      "dev": true,
-      "license": "ISC",
-      "bin": {
-        "semver": "bin/semver.js"
-      }
-    },
-    "node_modules/@babel/generator": {
-      "version": "7.26.5",
-      "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.26.5.tgz",
-      "integrity": "sha512-2caSP6fN9I7HOe6nqhtft7V4g7/V/gfDsC3Ag4W7kEzzvRGKqiv0pu0HogPiZ3KaVSoNDhUws6IJjDjpfmYIXw==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "@babel/parser": "^7.26.5",
-        "@babel/types": "^7.26.5",
-        "@jridgewell/gen-mapping": "^0.3.5",
-        "@jridgewell/trace-mapping": "^0.3.25",
-        "jsesc": "^3.0.2"
-      },
-      "engines": {
-        "node": ">=6.9.0"
-      }
-    },
-    "node_modules/@babel/helper-annotate-as-pure": {
-      "version": "7.25.9",
-      "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.25.9.tgz",
-      "integrity": "sha512-gv7320KBUFJz1RnylIg5WWYPRXKZ884AGkYpgpWW02TH66Dl+HaC1t1CKd0z3R4b6hdYEcmrNZHUmfCP+1u3/g==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "@babel/types": "^7.25.9"
-      },
-      "engines": {
-        "node": ">=6.9.0"
-      }
-    },
-    "node_modules/@babel/helper-compilation-targets": {
-      "version": "7.26.5",
-      "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.26.5.tgz",
-      "integrity": "sha512-IXuyn5EkouFJscIDuFF5EsiSolseme1s0CZB+QxVugqJLYmKdxI1VfIBOst0SUu4rnk2Z7kqTwmoO1lp3HIfnA==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "@babel/compat-data": "^7.26.5",
-        "@babel/helper-validator-option": "^7.25.9",
-        "browserslist": "^4.24.0",
-        "lru-cache": "^5.1.1",
-        "semver": "^6.3.1"
-      },
-      "engines": {
-        "node": ">=6.9.0"
-      }
-    },
-    "node_modules/@babel/helper-compilation-targets/node_modules/lru-cache": {
-      "version": "5.1.1",
-      "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
-      "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==",
-      "dev": true,
-      "license": "ISC",
-      "dependencies": {
-        "yallist": "^3.0.2"
-      }
-    },
-    "node_modules/@babel/helper-compilation-targets/node_modules/semver": {
-      "version": "6.3.1",
-      "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
-      "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
-      "dev": true,
-      "license": "ISC",
-      "bin": {
-        "semver": "bin/semver.js"
-      }
-    },
-    "node_modules/@babel/helper-create-class-features-plugin": {
-      "version": "7.25.9",
-      "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.25.9.tgz",
-      "integrity": "sha512-UTZQMvt0d/rSz6KI+qdu7GQze5TIajwTS++GUozlw8VBJDEOAqSXwm1WvmYEZwqdqSGQshRocPDqrt4HBZB3fQ==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "@babel/helper-annotate-as-pure": "^7.25.9",
-        "@babel/helper-member-expression-to-functions": "^7.25.9",
-        "@babel/helper-optimise-call-expression": "^7.25.9",
-        "@babel/helper-replace-supers": "^7.25.9",
-        "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9",
-        "@babel/traverse": "^7.25.9",
-        "semver": "^6.3.1"
-      },
-      "engines": {
-        "node": ">=6.9.0"
-      },
-      "peerDependencies": {
-        "@babel/core": "^7.0.0"
-      }
-    },
-    "node_modules/@babel/helper-create-class-features-plugin/node_modules/semver": {
-      "version": "6.3.1",
-      "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
-      "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
-      "dev": true,
-      "license": "ISC",
-      "bin": {
-        "semver": "bin/semver.js"
-      }
-    },
-    "node_modules/@babel/helper-member-expression-to-functions": {
-      "version": "7.25.9",
-      "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.25.9.tgz",
-      "integrity": "sha512-wbfdZ9w5vk0C0oyHqAJbc62+vet5prjj01jjJ8sKn3j9h3MQQlflEdXYvuqRWjHnM12coDEqiC1IRCi0U/EKwQ==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "@babel/traverse": "^7.25.9",
-        "@babel/types": "^7.25.9"
-      },
-      "engines": {
-        "node": ">=6.9.0"
-      }
-    },
-    "node_modules/@babel/helper-module-imports": {
-      "version": "7.25.9",
-      "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.25.9.tgz",
-      "integrity": "sha512-tnUA4RsrmflIM6W6RFTLFSXITtl0wKjgpnLgXyowocVPrbYrLUXSBXDgTs8BlbmIzIdlBySRQjINYs2BAkiLtw==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "@babel/traverse": "^7.25.9",
-        "@babel/types": "^7.25.9"
-      },
-      "engines": {
-        "node": ">=6.9.0"
-      }
-    },
-    "node_modules/@babel/helper-module-transforms": {
-      "version": "7.26.0",
-      "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.26.0.tgz",
-      "integrity": "sha512-xO+xu6B5K2czEnQye6BHA7DolFFmS3LB7stHZFaOLb1pAwO1HWLS8fXA+eh0A2yIvltPVmx3eNNDBJA2SLHXFw==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "@babel/helper-module-imports": "^7.25.9",
-        "@babel/helper-validator-identifier": "^7.25.9",
-        "@babel/traverse": "^7.25.9"
-      },
-      "engines": {
-        "node": ">=6.9.0"
-      },
-      "peerDependencies": {
-        "@babel/core": "^7.0.0"
-      }
-    },
-    "node_modules/@babel/helper-optimise-call-expression": {
-      "version": "7.25.9",
-      "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.25.9.tgz",
-      "integrity": "sha512-FIpuNaz5ow8VyrYcnXQTDRGvV6tTjkNtCK/RYNDXGSLlUD6cBuQTSw43CShGxjvfBTfcUA/r6UhUCbtYqkhcuQ==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "@babel/types": "^7.25.9"
-      },
-      "engines": {
-        "node": ">=6.9.0"
-      }
-    },
-    "node_modules/@babel/helper-plugin-utils": {
-      "version": "7.26.5",
-      "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.26.5.tgz",
-      "integrity": "sha512-RS+jZcRdZdRFzMyr+wcsaqOmld1/EqTghfaBGQQd/WnRdzdlvSZ//kF7U8VQTxf1ynZ4cjUcYgjVGx13ewNPMg==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">=6.9.0"
-      }
-    },
-    "node_modules/@babel/helper-replace-supers": {
-      "version": "7.26.5",
-      "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.26.5.tgz",
-      "integrity": "sha512-bJ6iIVdYX1YooY2X7w1q6VITt+LnUILtNk7zT78ykuwStx8BauCzxvFqFaHjOpW1bVnSUM1PN1f0p5P21wHxvg==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "@babel/helper-member-expression-to-functions": "^7.25.9",
-        "@babel/helper-optimise-call-expression": "^7.25.9",
-        "@babel/traverse": "^7.26.5"
-      },
-      "engines": {
-        "node": ">=6.9.0"
-      },
-      "peerDependencies": {
-        "@babel/core": "^7.0.0"
-      }
-    },
-    "node_modules/@babel/helper-skip-transparent-expression-wrappers": {
-      "version": "7.25.9",
-      "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.25.9.tgz",
-      "integrity": "sha512-K4Du3BFa3gvyhzgPcntrkDgZzQaq6uozzcpGbOO1OEJaI+EJdqWIMTLgFgQf6lrfiDFo5FU+BxKepI9RmZqahA==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "@babel/traverse": "^7.25.9",
-        "@babel/types": "^7.25.9"
-      },
-      "engines": {
-        "node": ">=6.9.0"
-      }
-    },
-    "node_modules/@babel/helper-string-parser": {
-      "version": "7.25.9",
-      "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.25.9.tgz",
-      "integrity": "sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==",
-      "license": "MIT",
-      "engines": {
-        "node": ">=6.9.0"
-      }
-    },
-    "node_modules/@babel/helper-validator-identifier": {
-      "version": "7.25.9",
-      "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz",
-      "integrity": "sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==",
-      "license": "MIT",
-      "engines": {
-        "node": ">=6.9.0"
-      }
-    },
-    "node_modules/@babel/helper-validator-option": {
-      "version": "7.25.9",
-      "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.25.9.tgz",
-      "integrity": "sha512-e/zv1co8pp55dNdEcCynfj9X7nyUKUXoUEwfXqaZt0omVOmDe9oOTdKStH4GmAw6zxMFs50ZayuMfHDKlO7Tfw==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">=6.9.0"
-      }
-    },
-    "node_modules/@babel/helpers": {
-      "version": "7.26.0",
-      "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.26.0.tgz",
-      "integrity": "sha512-tbhNuIxNcVb21pInl3ZSjksLCvgdZy9KwJ8brv993QtIVKJBBkYXz4q4ZbAv31GdnC+R90np23L5FbEBlthAEw==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "@babel/template": "^7.25.9",
-        "@babel/types": "^7.26.0"
-      },
-      "engines": {
-        "node": ">=6.9.0"
-      }
-    },
-    "node_modules/@babel/parser": {
-      "version": "7.26.5",
-      "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.5.tgz",
-      "integrity": "sha512-SRJ4jYmXRqV1/Xc+TIVG84WjHBXKlxO9sHQnA2Pf12QQEAp1LOh6kDzNHXcUnbH1QI0FDoPPVOt+vyUDucxpaw==",
-      "license": "MIT",
-      "dependencies": {
-        "@babel/types": "^7.26.5"
-      },
-      "bin": {
-        "parser": "bin/babel-parser.js"
-      },
-      "engines": {
-        "node": ">=6.0.0"
-      }
-    },
-    "node_modules/@babel/plugin-proposal-decorators": {
-      "version": "7.25.9",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.25.9.tgz",
-      "integrity": "sha512-smkNLL/O1ezy9Nhy4CNosc4Va+1wo5w4gzSZeLe6y6dM4mmHfYOCPolXQPHQxonZCF+ZyebxN9vqOolkYrSn5g==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "@babel/helper-create-class-features-plugin": "^7.25.9",
-        "@babel/helper-plugin-utils": "^7.25.9",
-        "@babel/plugin-syntax-decorators": "^7.25.9"
-      },
-      "engines": {
-        "node": ">=6.9.0"
-      },
-      "peerDependencies": {
-        "@babel/core": "^7.0.0-0"
-      }
-    },
-    "node_modules/@babel/plugin-syntax-decorators": {
-      "version": "7.25.9",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.25.9.tgz",
-      "integrity": "sha512-ryzI0McXUPJnRCvMo4lumIKZUzhYUO/ScI+Mz4YVaTLt04DHNSjEUjKVvbzQjZFLuod/cYEc07mJWhzl6v4DPg==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "@babel/helper-plugin-utils": "^7.25.9"
-      },
-      "engines": {
-        "node": ">=6.9.0"
-      },
-      "peerDependencies": {
-        "@babel/core": "^7.0.0-0"
-      }
-    },
-    "node_modules/@babel/plugin-syntax-import-attributes": {
-      "version": "7.26.0",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.26.0.tgz",
-      "integrity": "sha512-e2dttdsJ1ZTpi3B9UYGLw41hifAubg19AtCu/2I/F1QNVclOBr1dYpTdmdyZ84Xiz43BS/tCUkMAZNLv12Pi+A==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "@babel/helper-plugin-utils": "^7.25.9"
-      },
-      "engines": {
-        "node": ">=6.9.0"
-      },
-      "peerDependencies": {
-        "@babel/core": "^7.0.0-0"
-      }
-    },
-    "node_modules/@babel/plugin-syntax-import-meta": {
-      "version": "7.10.4",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz",
-      "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "@babel/helper-plugin-utils": "^7.10.4"
-      },
-      "peerDependencies": {
-        "@babel/core": "^7.0.0-0"
-      }
-    },
-    "node_modules/@babel/plugin-syntax-jsx": {
-      "version": "7.25.9",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.25.9.tgz",
-      "integrity": "sha512-ld6oezHQMZsZfp6pWtbjaNDF2tiiCYYDqQszHt5VV437lewP9aSi2Of99CK0D0XB21k7FLgnLcmQKyKzynfeAA==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "@babel/helper-plugin-utils": "^7.25.9"
-      },
-      "engines": {
-        "node": ">=6.9.0"
-      },
-      "peerDependencies": {
-        "@babel/core": "^7.0.0-0"
-      }
-    },
-    "node_modules/@babel/plugin-syntax-typescript": {
-      "version": "7.25.9",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.25.9.tgz",
-      "integrity": "sha512-hjMgRy5hb8uJJjUcdWunWVcoi9bGpJp8p5Ol1229PoN6aytsLwNMgmdftO23wnCLMfVmTwZDWMPNq/D1SY60JQ==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "@babel/helper-plugin-utils": "^7.25.9"
-      },
-      "engines": {
-        "node": ">=6.9.0"
-      },
-      "peerDependencies": {
-        "@babel/core": "^7.0.0-0"
-      }
-    },
-    "node_modules/@babel/plugin-transform-typescript": {
-      "version": "7.26.5",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.26.5.tgz",
-      "integrity": "sha512-GJhPO0y8SD5EYVCy2Zr+9dSZcEgaSmq5BLR0Oc25TOEhC+ba49vUAGZFjy8v79z9E1mdldq4x9d1xgh4L1d5dQ==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "@babel/helper-annotate-as-pure": "^7.25.9",
-        "@babel/helper-create-class-features-plugin": "^7.25.9",
-        "@babel/helper-plugin-utils": "^7.26.5",
-        "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9",
-        "@babel/plugin-syntax-typescript": "^7.25.9"
-      },
-      "engines": {
-        "node": ">=6.9.0"
-      },
-      "peerDependencies": {
-        "@babel/core": "^7.0.0-0"
-      }
-    },
-    "node_modules/@babel/template": {
-      "version": "7.25.9",
-      "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.25.9.tgz",
-      "integrity": "sha512-9DGttpmPvIxBb/2uwpVo3dqJ+O6RooAFOS+lB+xDqoE2PVCE8nfoHMdZLpfCQRLwvohzXISPZcgxt80xLfsuwg==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "@babel/code-frame": "^7.25.9",
-        "@babel/parser": "^7.25.9",
-        "@babel/types": "^7.25.9"
-      },
-      "engines": {
-        "node": ">=6.9.0"
-      }
-    },
-    "node_modules/@babel/traverse": {
-      "version": "7.26.5",
-      "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.26.5.tgz",
-      "integrity": "sha512-rkOSPOw+AXbgtwUga3U4u8RpoK9FEFWBNAlTpcnkLFjL5CT+oyHNuUUC/xx6XefEJ16r38r8Bc/lfp6rYuHeJQ==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "@babel/code-frame": "^7.26.2",
-        "@babel/generator": "^7.26.5",
-        "@babel/parser": "^7.26.5",
-        "@babel/template": "^7.25.9",
-        "@babel/types": "^7.26.5",
-        "debug": "^4.3.1",
-        "globals": "^11.1.0"
-      },
-      "engines": {
-        "node": ">=6.9.0"
-      }
-    },
-    "node_modules/@babel/traverse/node_modules/globals": {
-      "version": "11.12.0",
-      "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz",
-      "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">=4"
-      }
-    },
-    "node_modules/@babel/types": {
-      "version": "7.26.5",
-      "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.5.tgz",
-      "integrity": "sha512-L6mZmwFDK6Cjh1nRCLXpa6no13ZIioJDz7mdkzHv399pThrTa/k0nUlNaenOeh2kWu/iaOQYElEpKPUswUa9Vg==",
-      "license": "MIT",
-      "dependencies": {
-        "@babel/helper-string-parser": "^7.25.9",
-        "@babel/helper-validator-identifier": "^7.25.9"
-      },
-      "engines": {
-        "node": ">=6.9.0"
-      }
-    },
-    "node_modules/@csstools/color-helpers": {
-      "version": "5.0.1",
-      "resolved": "https://registry.npmjs.org/@csstools/color-helpers/-/color-helpers-5.0.1.tgz",
-      "integrity": "sha512-MKtmkA0BX87PKaO1NFRTFH+UnkgnmySQOvNxJubsadusqPEC2aJ9MOQiMceZJJ6oitUl/i0L6u0M1IrmAOmgBA==",
-      "dev": true,
-      "funding": [
-        {
-          "type": "github",
-          "url": "https://github.com/sponsors/csstools"
-        },
-        {
-          "type": "opencollective",
-          "url": "https://opencollective.com/csstools"
-        }
-      ],
-      "license": "MIT-0",
-      "engines": {
-        "node": ">=18"
-      }
-    },
-    "node_modules/@csstools/css-calc": {
-      "version": "2.1.1",
-      "resolved": "https://registry.npmjs.org/@csstools/css-calc/-/css-calc-2.1.1.tgz",
-      "integrity": "sha512-rL7kaUnTkL9K+Cvo2pnCieqNpTKgQzy5f+N+5Iuko9HAoasP+xgprVh7KN/MaJVvVL1l0EzQq2MoqBHKSrDrag==",
-      "dev": true,
-      "funding": [
-        {
-          "type": "github",
-          "url": "https://github.com/sponsors/csstools"
-        },
-        {
-          "type": "opencollective",
-          "url": "https://opencollective.com/csstools"
-        }
-      ],
-      "license": "MIT",
-      "engines": {
-        "node": ">=18"
-      },
-      "peerDependencies": {
-        "@csstools/css-parser-algorithms": "^3.0.4",
-        "@csstools/css-tokenizer": "^3.0.3"
-      }
-    },
-    "node_modules/@csstools/css-color-parser": {
-      "version": "3.0.7",
-      "resolved": "https://registry.npmjs.org/@csstools/css-color-parser/-/css-color-parser-3.0.7.tgz",
-      "integrity": "sha512-nkMp2mTICw32uE5NN+EsJ4f5N+IGFeCFu4bGpiKgb2Pq/7J/MpyLBeQ5ry4KKtRFZaYs6sTmcMYrSRIyj5DFKA==",
-      "dev": true,
-      "funding": [
-        {
-          "type": "github",
-          "url": "https://github.com/sponsors/csstools"
-        },
-        {
-          "type": "opencollective",
-          "url": "https://opencollective.com/csstools"
-        }
-      ],
-      "license": "MIT",
-      "dependencies": {
-        "@csstools/color-helpers": "^5.0.1",
-        "@csstools/css-calc": "^2.1.1"
-      },
-      "engines": {
-        "node": ">=18"
-      },
-      "peerDependencies": {
-        "@csstools/css-parser-algorithms": "^3.0.4",
-        "@csstools/css-tokenizer": "^3.0.3"
-      }
-    },
-    "node_modules/@csstools/css-parser-algorithms": {
-      "version": "3.0.4",
-      "resolved": "https://registry.npmjs.org/@csstools/css-parser-algorithms/-/css-parser-algorithms-3.0.4.tgz",
-      "integrity": "sha512-Up7rBoV77rv29d3uKHUIVubz1BTcgyUK72IvCQAbfbMv584xHcGKCKbWh7i8hPrRJ7qU4Y8IO3IY9m+iTB7P3A==",
-      "dev": true,
-      "funding": [
-        {
-          "type": "github",
-          "url": "https://github.com/sponsors/csstools"
-        },
-        {
-          "type": "opencollective",
-          "url": "https://opencollective.com/csstools"
-        }
-      ],
-      "license": "MIT",
-      "peer": true,
-      "engines": {
-        "node": ">=18"
-      },
-      "peerDependencies": {
-        "@csstools/css-tokenizer": "^3.0.3"
-      }
-    },
-    "node_modules/@csstools/css-tokenizer": {
-      "version": "3.0.3",
-      "resolved": "https://registry.npmjs.org/@csstools/css-tokenizer/-/css-tokenizer-3.0.3.tgz",
-      "integrity": "sha512-UJnjoFsmxfKUdNYdWgOB0mWUypuLvAfQPH1+pyvRJs6euowbFkFC6P13w1l8mJyi3vxYMxc9kld5jZEGRQs6bw==",
-      "dev": true,
-      "funding": [
-        {
-          "type": "github",
-          "url": "https://github.com/sponsors/csstools"
-        },
-        {
-          "type": "opencollective",
-          "url": "https://opencollective.com/csstools"
-        }
-      ],
-      "license": "MIT",
-      "peer": true,
-      "engines": {
-        "node": ">=18"
-      }
-    },
-    "node_modules/@esbuild/aix-ppc64": {
-      "version": "0.24.2",
-      "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.24.2.tgz",
-      "integrity": "sha512-thpVCb/rhxE/BnMLQ7GReQLLN8q9qbHmI55F4489/ByVg2aQaQ6kbcLb6FHkocZzQhxc4gx0sCk0tJkKBFzDhA==",
-      "cpu": [
-        "ppc64"
-      ],
-      "dev": true,
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "aix"
-      ],
-      "engines": {
-        "node": ">=18"
-      }
-    },
-    "node_modules/@esbuild/android-arm": {
-      "version": "0.24.2",
-      "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.24.2.tgz",
-      "integrity": "sha512-tmwl4hJkCfNHwFB3nBa8z1Uy3ypZpxqxfTQOcHX+xRByyYgunVbZ9MzUUfb0RxaHIMnbHagwAxuTL+tnNM+1/Q==",
-      "cpu": [
-        "arm"
-      ],
-      "dev": true,
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "android"
-      ],
-      "engines": {
-        "node": ">=18"
-      }
-    },
-    "node_modules/@esbuild/android-arm64": {
-      "version": "0.24.2",
-      "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.24.2.tgz",
-      "integrity": "sha512-cNLgeqCqV8WxfcTIOeL4OAtSmL8JjcN6m09XIgro1Wi7cF4t/THaWEa7eL5CMoMBdjoHOTh/vwTO/o2TRXIyzg==",
-      "cpu": [
-        "arm64"
-      ],
-      "dev": true,
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "android"
-      ],
-      "engines": {
-        "node": ">=18"
-      }
-    },
-    "node_modules/@esbuild/android-x64": {
-      "version": "0.24.2",
-      "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.24.2.tgz",
-      "integrity": "sha512-B6Q0YQDqMx9D7rvIcsXfmJfvUYLoP722bgfBlO5cGvNVb5V/+Y7nhBE3mHV9OpxBf4eAS2S68KZztiPaWq4XYw==",
-      "cpu": [
-        "x64"
-      ],
-      "dev": true,
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "android"
-      ],
-      "engines": {
-        "node": ">=18"
-      }
-    },
-    "node_modules/@esbuild/darwin-arm64": {
-      "version": "0.24.2",
-      "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.24.2.tgz",
-      "integrity": "sha512-kj3AnYWc+CekmZnS5IPu9D+HWtUI49hbnyqk0FLEJDbzCIQt7hg7ucF1SQAilhtYpIujfaHr6O0UHlzzSPdOeA==",
-      "cpu": [
-        "arm64"
-      ],
-      "dev": true,
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "darwin"
-      ],
-      "engines": {
-        "node": ">=18"
-      }
-    },
-    "node_modules/@esbuild/darwin-x64": {
-      "version": "0.24.2",
-      "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.24.2.tgz",
-      "integrity": "sha512-WeSrmwwHaPkNR5H3yYfowhZcbriGqooyu3zI/3GGpF8AyUdsrrP0X6KumITGA9WOyiJavnGZUwPGvxvwfWPHIA==",
-      "cpu": [
-        "x64"
-      ],
-      "dev": true,
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "darwin"
-      ],
-      "engines": {
-        "node": ">=18"
-      }
-    },
-    "node_modules/@esbuild/freebsd-arm64": {
-      "version": "0.24.2",
-      "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.24.2.tgz",
-      "integrity": "sha512-UN8HXjtJ0k/Mj6a9+5u6+2eZ2ERD7Edt1Q9IZiB5UZAIdPnVKDoG7mdTVGhHJIeEml60JteamR3qhsr1r8gXvg==",
-      "cpu": [
-        "arm64"
-      ],
-      "dev": true,
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "freebsd"
-      ],
-      "engines": {
-        "node": ">=18"
-      }
-    },
-    "node_modules/@esbuild/freebsd-x64": {
-      "version": "0.24.2",
-      "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.24.2.tgz",
-      "integrity": "sha512-TvW7wE/89PYW+IevEJXZ5sF6gJRDY/14hyIGFXdIucxCsbRmLUcjseQu1SyTko+2idmCw94TgyaEZi9HUSOe3Q==",
-      "cpu": [
-        "x64"
-      ],
-      "dev": true,
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "freebsd"
-      ],
-      "engines": {
-        "node": ">=18"
-      }
-    },
-    "node_modules/@esbuild/linux-arm": {
-      "version": "0.24.2",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.24.2.tgz",
-      "integrity": "sha512-n0WRM/gWIdU29J57hJyUdIsk0WarGd6To0s+Y+LwvlC55wt+GT/OgkwoXCXvIue1i1sSNWblHEig00GBWiJgfA==",
-      "cpu": [
-        "arm"
-      ],
-      "dev": true,
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">=18"
-      }
-    },
-    "node_modules/@esbuild/linux-arm64": {
-      "version": "0.24.2",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.24.2.tgz",
-      "integrity": "sha512-7HnAD6074BW43YvvUmE/35Id9/NB7BeX5EoNkK9obndmZBUk8xmJJeU7DwmUeN7tkysslb2eSl6CTrYz6oEMQg==",
-      "cpu": [
-        "arm64"
-      ],
-      "dev": true,
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">=18"
-      }
-    },
-    "node_modules/@esbuild/linux-ia32": {
-      "version": "0.24.2",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.24.2.tgz",
-      "integrity": "sha512-sfv0tGPQhcZOgTKO3oBE9xpHuUqguHvSo4jl+wjnKwFpapx+vUDcawbwPNuBIAYdRAvIDBfZVvXprIj3HA+Ugw==",
-      "cpu": [
-        "ia32"
-      ],
-      "dev": true,
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">=18"
-      }
-    },
-    "node_modules/@esbuild/linux-loong64": {
-      "version": "0.24.2",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.24.2.tgz",
-      "integrity": "sha512-CN9AZr8kEndGooS35ntToZLTQLHEjtVB5n7dl8ZcTZMonJ7CCfStrYhrzF97eAecqVbVJ7APOEe18RPI4KLhwQ==",
-      "cpu": [
-        "loong64"
-      ],
-      "dev": true,
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">=18"
-      }
-    },
-    "node_modules/@esbuild/linux-mips64el": {
-      "version": "0.24.2",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.24.2.tgz",
-      "integrity": "sha512-iMkk7qr/wl3exJATwkISxI7kTcmHKE+BlymIAbHO8xanq/TjHaaVThFF6ipWzPHryoFsesNQJPE/3wFJw4+huw==",
-      "cpu": [
-        "mips64el"
-      ],
-      "dev": true,
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">=18"
-      }
-    },
-    "node_modules/@esbuild/linux-ppc64": {
-      "version": "0.24.2",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.24.2.tgz",
-      "integrity": "sha512-shsVrgCZ57Vr2L8mm39kO5PPIb+843FStGt7sGGoqiiWYconSxwTiuswC1VJZLCjNiMLAMh34jg4VSEQb+iEbw==",
-      "cpu": [
-        "ppc64"
-      ],
-      "dev": true,
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">=18"
-      }
-    },
-    "node_modules/@esbuild/linux-riscv64": {
-      "version": "0.24.2",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.24.2.tgz",
-      "integrity": "sha512-4eSFWnU9Hhd68fW16GD0TINewo1L6dRrB+oLNNbYyMUAeOD2yCK5KXGK1GH4qD/kT+bTEXjsyTCiJGHPZ3eM9Q==",
-      "cpu": [
-        "riscv64"
-      ],
-      "dev": true,
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">=18"
-      }
-    },
-    "node_modules/@esbuild/linux-s390x": {
-      "version": "0.24.2",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.24.2.tgz",
-      "integrity": "sha512-S0Bh0A53b0YHL2XEXC20bHLuGMOhFDO6GN4b3YjRLK//Ep3ql3erpNcPlEFed93hsQAjAQDNsvcK+hV90FubSw==",
-      "cpu": [
-        "s390x"
-      ],
-      "dev": true,
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">=18"
-      }
-    },
-    "node_modules/@esbuild/linux-x64": {
-      "version": "0.24.2",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.24.2.tgz",
-      "integrity": "sha512-8Qi4nQcCTbLnK9WoMjdC9NiTG6/E38RNICU6sUNqK0QFxCYgoARqVqxdFmWkdonVsvGqWhmm7MO0jyTqLqwj0Q==",
-      "cpu": [
-        "x64"
-      ],
-      "dev": true,
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">=18"
-      }
-    },
-    "node_modules/@esbuild/netbsd-arm64": {
-      "version": "0.24.2",
-      "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.24.2.tgz",
-      "integrity": "sha512-wuLK/VztRRpMt9zyHSazyCVdCXlpHkKm34WUyinD2lzK07FAHTq0KQvZZlXikNWkDGoT6x3TD51jKQ7gMVpopw==",
-      "cpu": [
-        "arm64"
-      ],
-      "dev": true,
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "netbsd"
-      ],
-      "engines": {
-        "node": ">=18"
-      }
-    },
-    "node_modules/@esbuild/netbsd-x64": {
-      "version": "0.24.2",
-      "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.24.2.tgz",
-      "integrity": "sha512-VefFaQUc4FMmJuAxmIHgUmfNiLXY438XrL4GDNV1Y1H/RW3qow68xTwjZKfj/+Plp9NANmzbH5R40Meudu8mmw==",
-      "cpu": [
-        "x64"
-      ],
-      "dev": true,
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "netbsd"
-      ],
-      "engines": {
-        "node": ">=18"
-      }
-    },
-    "node_modules/@esbuild/openbsd-arm64": {
-      "version": "0.24.2",
-      "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.24.2.tgz",
-      "integrity": "sha512-YQbi46SBct6iKnszhSvdluqDmxCJA+Pu280Av9WICNwQmMxV7nLRHZfjQzwbPs3jeWnuAhE9Jy0NrnJ12Oz+0A==",
-      "cpu": [
-        "arm64"
-      ],
-      "dev": true,
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "openbsd"
-      ],
-      "engines": {
-        "node": ">=18"
-      }
-    },
-    "node_modules/@esbuild/openbsd-x64": {
-      "version": "0.24.2",
-      "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.24.2.tgz",
-      "integrity": "sha512-+iDS6zpNM6EnJyWv0bMGLWSWeXGN/HTaF/LXHXHwejGsVi+ooqDfMCCTerNFxEkM3wYVcExkeGXNqshc9iMaOA==",
-      "cpu": [
-        "x64"
-      ],
-      "dev": true,
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "openbsd"
-      ],
-      "engines": {
-        "node": ">=18"
-      }
-    },
-    "node_modules/@esbuild/sunos-x64": {
-      "version": "0.24.2",
-      "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.24.2.tgz",
-      "integrity": "sha512-hTdsW27jcktEvpwNHJU4ZwWFGkz2zRJUz8pvddmXPtXDzVKTTINmlmga3ZzwcuMpUvLw7JkLy9QLKyGpD2Yxig==",
-      "cpu": [
-        "x64"
-      ],
-      "dev": true,
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "sunos"
-      ],
-      "engines": {
-        "node": ">=18"
-      }
-    },
-    "node_modules/@esbuild/win32-arm64": {
-      "version": "0.24.2",
-      "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.24.2.tgz",
-      "integrity": "sha512-LihEQ2BBKVFLOC9ZItT9iFprsE9tqjDjnbulhHoFxYQtQfai7qfluVODIYxt1PgdoyQkz23+01rzwNwYfutxUQ==",
-      "cpu": [
-        "arm64"
-      ],
-      "dev": true,
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "win32"
-      ],
-      "engines": {
-        "node": ">=18"
-      }
-    },
-    "node_modules/@esbuild/win32-ia32": {
-      "version": "0.24.2",
-      "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.24.2.tgz",
-      "integrity": "sha512-q+iGUwfs8tncmFC9pcnD5IvRHAzmbwQ3GPS5/ceCyHdjXubwQWI12MKWSNSMYLJMq23/IUCvJMS76PDqXe1fxA==",
-      "cpu": [
-        "ia32"
-      ],
-      "dev": true,
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "win32"
-      ],
-      "engines": {
-        "node": ">=18"
-      }
-    },
-    "node_modules/@esbuild/win32-x64": {
-      "version": "0.24.2",
-      "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.24.2.tgz",
-      "integrity": "sha512-7VTgWzgMGvup6aSqDPLiW5zHaxYJGTO4OokMjIlrCtf+VpEL+cXKtCvg723iguPYI5oaUNdS+/V7OU2gvXVWEg==",
-      "cpu": [
-        "x64"
-      ],
-      "dev": true,
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "win32"
-      ],
-      "engines": {
-        "node": ">=18"
-      }
-    },
-    "node_modules/@eslint-community/eslint-utils": {
-      "version": "4.9.1",
-      "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.1.tgz",
-      "integrity": "sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "eslint-visitor-keys": "^3.4.3"
-      },
-      "engines": {
-        "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
-      },
-      "funding": {
-        "url": "https://opencollective.com/eslint"
-      },
-      "peerDependencies": {
-        "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0"
-      }
-    },
-    "node_modules/@eslint-community/regexpp": {
-      "version": "4.12.2",
-      "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.2.tgz",
-      "integrity": "sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": "^12.0.0 || ^14.0.0 || >=16.0.0"
-      }
-    },
-    "node_modules/@eslint/config-array": {
-      "version": "0.19.1",
-      "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.19.1.tgz",
-      "integrity": "sha512-fo6Mtm5mWyKjA/Chy1BYTdn5mGJoDNjC7C64ug20ADsRDGrA85bN3uK3MaKbeRkRuuIEAR5N33Jr1pbm411/PA==",
-      "dev": true,
-      "license": "Apache-2.0",
-      "dependencies": {
-        "@eslint/object-schema": "^2.1.5",
-        "debug": "^4.3.1",
-        "minimatch": "^3.1.2"
-      },
-      "engines": {
-        "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
-      }
-    },
-    "node_modules/@eslint/config-array/node_modules/brace-expansion": {
-      "version": "1.1.11",
-      "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
-      "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "balanced-match": "^1.0.0",
-        "concat-map": "0.0.1"
-      }
-    },
-    "node_modules/@eslint/config-array/node_modules/minimatch": {
-      "version": "3.1.2",
-      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
-      "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
-      "dev": true,
-      "license": "ISC",
-      "dependencies": {
-        "brace-expansion": "^1.1.7"
-      },
-      "engines": {
-        "node": "*"
-      }
-    },
-    "node_modules/@eslint/core": {
-      "version": "0.10.0",
-      "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.10.0.tgz",
-      "integrity": "sha512-gFHJ+xBOo4G3WRlR1e/3G8A6/KZAH6zcE/hkLRCZTi/B9avAG365QhFA8uOGzTMqgTghpn7/fSnscW++dpMSAw==",
-      "dev": true,
-      "license": "Apache-2.0",
-      "dependencies": {
-        "@types/json-schema": "^7.0.15"
-      },
-      "engines": {
-        "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
-      }
-    },
-    "node_modules/@eslint/eslintrc": {
-      "version": "3.2.0",
-      "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.2.0.tgz",
-      "integrity": "sha512-grOjVNN8P3hjJn/eIETF1wwd12DdnwFDoyceUJLYYdkpbwq3nLi+4fqrTAONx7XDALqlL220wC/RHSC/QTI/0w==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "ajv": "^6.12.4",
-        "debug": "^4.3.2",
-        "espree": "^10.0.1",
-        "globals": "^14.0.0",
-        "ignore": "^5.2.0",
-        "import-fresh": "^3.2.1",
-        "js-yaml": "^4.1.0",
-        "minimatch": "^3.1.2",
-        "strip-json-comments": "^3.1.1"
-      },
-      "engines": {
-        "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
-      },
-      "funding": {
-        "url": "https://opencollective.com/eslint"
-      }
-    },
-    "node_modules/@eslint/eslintrc/node_modules/brace-expansion": {
-      "version": "1.1.11",
-      "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
-      "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "balanced-match": "^1.0.0",
-        "concat-map": "0.0.1"
-      }
-    },
-    "node_modules/@eslint/eslintrc/node_modules/minimatch": {
-      "version": "3.1.2",
-      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
-      "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
-      "dev": true,
-      "license": "ISC",
-      "dependencies": {
-        "brace-expansion": "^1.1.7"
-      },
-      "engines": {
-        "node": "*"
-      }
-    },
-    "node_modules/@eslint/js": {
-      "version": "9.18.0",
-      "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.18.0.tgz",
-      "integrity": "sha512-fK6L7rxcq6/z+AaQMtiFTkvbHkBLNlwyRxHpKawP0x3u9+NC6MQTnFW+AdpwC6gfHTW0051cokQgtTN2FqlxQA==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
-      }
-    },
-    "node_modules/@eslint/object-schema": {
-      "version": "2.1.5",
-      "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.5.tgz",
-      "integrity": "sha512-o0bhxnL89h5Bae5T318nFoFzGy+YE5i/gGkoPAgkmTVdRKTiv3p8JHevPiPaMwoloKfEiiaHlawCqaZMqRm+XQ==",
-      "dev": true,
-      "license": "Apache-2.0",
-      "engines": {
-        "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
-      }
-    },
-    "node_modules/@eslint/plugin-kit": {
-      "version": "0.2.5",
-      "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.2.5.tgz",
-      "integrity": "sha512-lB05FkqEdUg2AA0xEbUz0SnkXT1LcCTa438W4IWTUh4hdOnVbQyOJ81OrDXsJk/LSiJHubgGEFoR5EHq1NsH1A==",
-      "dev": true,
-      "license": "Apache-2.0",
-      "dependencies": {
-        "@eslint/core": "^0.10.0",
-        "levn": "^0.4.1"
-      },
-      "engines": {
-        "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
-      }
-    },
-    "node_modules/@fortawesome/fontawesome-free": {
-      "version": "6.7.2",
-      "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-free/-/fontawesome-free-6.7.2.tgz",
-      "integrity": "sha512-JUOtgFW6k9u4Y+xeIaEiLr3+cjoUPiAuLXoyKOJSia6Duzb7pq+A76P9ZdPDoAoxHdHzq6gE9/jKBGXlZT8FbA==",
-      "license": "(CC-BY-4.0 AND OFL-1.1 AND MIT)",
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/@humanfs/core": {
-      "version": "0.19.1",
-      "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz",
-      "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==",
-      "dev": true,
-      "license": "Apache-2.0",
-      "engines": {
-        "node": ">=18.18.0"
-      }
-    },
-    "node_modules/@humanfs/node": {
-      "version": "0.16.6",
-      "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.6.tgz",
-      "integrity": "sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw==",
-      "dev": true,
-      "license": "Apache-2.0",
-      "dependencies": {
-        "@humanfs/core": "^0.19.1",
-        "@humanwhocodes/retry": "^0.3.0"
-      },
-      "engines": {
-        "node": ">=18.18.0"
-      }
-    },
-    "node_modules/@humanfs/node/node_modules/@humanwhocodes/retry": {
-      "version": "0.3.1",
-      "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.3.1.tgz",
-      "integrity": "sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==",
-      "dev": true,
-      "license": "Apache-2.0",
-      "engines": {
-        "node": ">=18.18"
-      },
-      "funding": {
-        "type": "github",
-        "url": "https://github.com/sponsors/nzakas"
-      }
-    },
-    "node_modules/@humanwhocodes/module-importer": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz",
-      "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==",
-      "dev": true,
-      "license": "Apache-2.0",
-      "engines": {
-        "node": ">=12.22"
-      },
-      "funding": {
-        "type": "github",
-        "url": "https://github.com/sponsors/nzakas"
-      }
-    },
-    "node_modules/@humanwhocodes/retry": {
-      "version": "0.4.1",
-      "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.1.tgz",
-      "integrity": "sha512-c7hNEllBlenFTHBky65mhq8WD2kbN9Q6gk0bTk8lSBvc554jpXSkST1iePudpt7+A/AQvuHs9EMqjHDXMY1lrA==",
-      "dev": true,
-      "license": "Apache-2.0",
-      "engines": {
-        "node": ">=18.18"
-      },
-      "funding": {
-        "type": "github",
-        "url": "https://github.com/sponsors/nzakas"
-      }
-    },
-    "node_modules/@isaacs/cliui": {
-      "version": "8.0.2",
-      "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz",
-      "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==",
-      "dev": true,
-      "license": "ISC",
-      "dependencies": {
-        "string-width": "^5.1.2",
-        "string-width-cjs": "npm:string-width@^4.2.0",
-        "strip-ansi": "^7.0.1",
-        "strip-ansi-cjs": "npm:strip-ansi@^6.0.1",
-        "wrap-ansi": "^8.1.0",
-        "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0"
-      },
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@jridgewell/gen-mapping": {
-      "version": "0.3.8",
-      "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.8.tgz",
-      "integrity": "sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==",
-      "license": "MIT",
-      "dependencies": {
-        "@jridgewell/set-array": "^1.2.1",
-        "@jridgewell/sourcemap-codec": "^1.4.10",
-        "@jridgewell/trace-mapping": "^0.3.24"
-      },
-      "engines": {
-        "node": ">=6.0.0"
-      }
-    },
-    "node_modules/@jridgewell/resolve-uri": {
-      "version": "3.1.2",
-      "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz",
-      "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==",
-      "license": "MIT",
-      "engines": {
-        "node": ">=6.0.0"
-      }
-    },
-    "node_modules/@jridgewell/set-array": {
-      "version": "1.2.1",
-      "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz",
-      "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==",
-      "license": "MIT",
-      "engines": {
-        "node": ">=6.0.0"
-      }
-    },
-    "node_modules/@jridgewell/source-map": {
-      "version": "0.3.6",
-      "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.6.tgz",
-      "integrity": "sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==",
-      "license": "MIT",
-      "dependencies": {
-        "@jridgewell/gen-mapping": "^0.3.5",
-        "@jridgewell/trace-mapping": "^0.3.25"
-      }
-    },
-    "node_modules/@jridgewell/sourcemap-codec": {
-      "version": "1.5.0",
-      "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz",
-      "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==",
-      "license": "MIT"
-    },
-    "node_modules/@jridgewell/trace-mapping": {
-      "version": "0.3.25",
-      "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz",
-      "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==",
-      "license": "MIT",
-      "dependencies": {
-        "@jridgewell/resolve-uri": "^3.1.0",
-        "@jridgewell/sourcemap-codec": "^1.4.14"
-      }
-    },
-    "node_modules/@mdi/font": {
-      "version": "7.4.47",
-      "resolved": "https://registry.npmjs.org/@mdi/font/-/font-7.4.47.tgz",
-      "integrity": "sha512-43MtGpd585SNzHZPcYowu/84Vz2a2g31TvPMTm9uTiCSWzaheQySUcSyUH/46fPnuPQWof2yd0pGBtzee/IQWw==",
-      "license": "Apache-2.0"
-    },
-    "node_modules/@one-ini/wasm": {
-      "version": "0.1.1",
-      "resolved": "https://registry.npmjs.org/@one-ini/wasm/-/wasm-0.1.1.tgz",
-      "integrity": "sha512-XuySG1E38YScSJoMlqovLru4KTUNSjgVTIjyh7qMX6aNN5HY5Ct5LhRJdxO79JtTzKfzV/bnWpz+zquYrISsvw==",
-      "dev": true,
-      "license": "MIT"
-    },
-    "node_modules/@parcel/watcher": {
-      "version": "2.5.1",
-      "resolved": "https://registry.npmjs.org/@parcel/watcher/-/watcher-2.5.1.tgz",
-      "integrity": "sha512-dfUnCxiN9H4ap84DvD2ubjw+3vUNpstxa0TneY/Paat8a3R4uQZDLSvWjmznAY/DoahqTHl9V46HF/Zs3F29pg==",
-      "hasInstallScript": true,
-      "license": "MIT",
-      "optional": true,
-      "dependencies": {
-        "detect-libc": "^1.0.3",
-        "is-glob": "^4.0.3",
-        "micromatch": "^4.0.5",
-        "node-addon-api": "^7.0.0"
-      },
-      "engines": {
-        "node": ">= 10.0.0"
-      },
-      "funding": {
-        "type": "opencollective",
-        "url": "https://opencollective.com/parcel"
-      },
-      "optionalDependencies": {
-        "@parcel/watcher-android-arm64": "2.5.1",
-        "@parcel/watcher-darwin-arm64": "2.5.1",
-        "@parcel/watcher-darwin-x64": "2.5.1",
-        "@parcel/watcher-freebsd-x64": "2.5.1",
-        "@parcel/watcher-linux-arm-glibc": "2.5.1",
-        "@parcel/watcher-linux-arm-musl": "2.5.1",
-        "@parcel/watcher-linux-arm64-glibc": "2.5.1",
-        "@parcel/watcher-linux-arm64-musl": "2.5.1",
-        "@parcel/watcher-linux-x64-glibc": "2.5.1",
-        "@parcel/watcher-linux-x64-musl": "2.5.1",
-        "@parcel/watcher-win32-arm64": "2.5.1",
-        "@parcel/watcher-win32-ia32": "2.5.1",
-        "@parcel/watcher-win32-x64": "2.5.1"
-      }
-    },
-    "node_modules/@parcel/watcher-android-arm64": {
-      "version": "2.5.1",
-      "resolved": "https://registry.npmjs.org/@parcel/watcher-android-arm64/-/watcher-android-arm64-2.5.1.tgz",
-      "integrity": "sha512-KF8+j9nNbUN8vzOFDpRMsaKBHZ/mcjEjMToVMJOhTozkDonQFFrRcfdLWn6yWKCmJKmdVxSgHiYvTCef4/qcBA==",
-      "cpu": [
-        "arm64"
-      ],
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "android"
-      ],
-      "engines": {
-        "node": ">= 10.0.0"
-      },
-      "funding": {
-        "type": "opencollective",
-        "url": "https://opencollective.com/parcel"
-      }
-    },
-    "node_modules/@parcel/watcher-darwin-arm64": {
-      "version": "2.5.1",
-      "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-arm64/-/watcher-darwin-arm64-2.5.1.tgz",
-      "integrity": "sha512-eAzPv5osDmZyBhou8PoF4i6RQXAfeKL9tjb3QzYuccXFMQU0ruIc/POh30ePnaOyD1UXdlKguHBmsTs53tVoPw==",
-      "cpu": [
-        "arm64"
-      ],
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "darwin"
-      ],
-      "engines": {
-        "node": ">= 10.0.0"
-      },
-      "funding": {
-        "type": "opencollective",
-        "url": "https://opencollective.com/parcel"
-      }
-    },
-    "node_modules/@parcel/watcher-darwin-x64": {
-      "version": "2.5.1",
-      "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-x64/-/watcher-darwin-x64-2.5.1.tgz",
-      "integrity": "sha512-1ZXDthrnNmwv10A0/3AJNZ9JGlzrF82i3gNQcWOzd7nJ8aj+ILyW1MTxVk35Db0u91oD5Nlk9MBiujMlwmeXZg==",
-      "cpu": [
-        "x64"
-      ],
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "darwin"
-      ],
-      "engines": {
-        "node": ">= 10.0.0"
-      },
-      "funding": {
-        "type": "opencollective",
-        "url": "https://opencollective.com/parcel"
-      }
-    },
-    "node_modules/@parcel/watcher-freebsd-x64": {
-      "version": "2.5.1",
-      "resolved": "https://registry.npmjs.org/@parcel/watcher-freebsd-x64/-/watcher-freebsd-x64-2.5.1.tgz",
-      "integrity": "sha512-SI4eljM7Flp9yPuKi8W0ird8TI/JK6CSxju3NojVI6BjHsTyK7zxA9urjVjEKJ5MBYC+bLmMcbAWlZ+rFkLpJQ==",
-      "cpu": [
-        "x64"
-      ],
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "freebsd"
-      ],
-      "engines": {
-        "node": ">= 10.0.0"
-      },
-      "funding": {
-        "type": "opencollective",
-        "url": "https://opencollective.com/parcel"
-      }
-    },
-    "node_modules/@parcel/watcher-linux-arm-glibc": {
-      "version": "2.5.1",
-      "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-glibc/-/watcher-linux-arm-glibc-2.5.1.tgz",
-      "integrity": "sha512-RCdZlEyTs8geyBkkcnPWvtXLY44BCeZKmGYRtSgtwwnHR4dxfHRG3gR99XdMEdQ7KeiDdasJwwvNSF5jKtDwdA==",
-      "cpu": [
-        "arm"
-      ],
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">= 10.0.0"
-      },
-      "funding": {
-        "type": "opencollective",
-        "url": "https://opencollective.com/parcel"
-      }
-    },
-    "node_modules/@parcel/watcher-linux-arm-musl": {
-      "version": "2.5.1",
-      "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-musl/-/watcher-linux-arm-musl-2.5.1.tgz",
-      "integrity": "sha512-6E+m/Mm1t1yhB8X412stiKFG3XykmgdIOqhjWj+VL8oHkKABfu/gjFj8DvLrYVHSBNC+/u5PeNrujiSQ1zwd1Q==",
-      "cpu": [
-        "arm"
-      ],
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">= 10.0.0"
-      },
-      "funding": {
-        "type": "opencollective",
-        "url": "https://opencollective.com/parcel"
-      }
-    },
-    "node_modules/@parcel/watcher-linux-arm64-glibc": {
-      "version": "2.5.1",
-      "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-glibc/-/watcher-linux-arm64-glibc-2.5.1.tgz",
-      "integrity": "sha512-LrGp+f02yU3BN9A+DGuY3v3bmnFUggAITBGriZHUREfNEzZh/GO06FF5u2kx8x+GBEUYfyTGamol4j3m9ANe8w==",
-      "cpu": [
-        "arm64"
-      ],
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">= 10.0.0"
-      },
-      "funding": {
-        "type": "opencollective",
-        "url": "https://opencollective.com/parcel"
-      }
-    },
-    "node_modules/@parcel/watcher-linux-arm64-musl": {
-      "version": "2.5.1",
-      "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-musl/-/watcher-linux-arm64-musl-2.5.1.tgz",
-      "integrity": "sha512-cFOjABi92pMYRXS7AcQv9/M1YuKRw8SZniCDw0ssQb/noPkRzA+HBDkwmyOJYp5wXcsTrhxO0zq1U11cK9jsFg==",
-      "cpu": [
-        "arm64"
-      ],
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">= 10.0.0"
-      },
-      "funding": {
-        "type": "opencollective",
-        "url": "https://opencollective.com/parcel"
-      }
-    },
-    "node_modules/@parcel/watcher-linux-x64-glibc": {
-      "version": "2.5.1",
-      "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-glibc/-/watcher-linux-x64-glibc-2.5.1.tgz",
-      "integrity": "sha512-GcESn8NZySmfwlTsIur+49yDqSny2IhPeZfXunQi48DMugKeZ7uy1FX83pO0X22sHntJ4Ub+9k34XQCX+oHt2A==",
-      "cpu": [
-        "x64"
-      ],
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">= 10.0.0"
-      },
-      "funding": {
-        "type": "opencollective",
-        "url": "https://opencollective.com/parcel"
-      }
-    },
-    "node_modules/@parcel/watcher-linux-x64-musl": {
-      "version": "2.5.1",
-      "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-musl/-/watcher-linux-x64-musl-2.5.1.tgz",
-      "integrity": "sha512-n0E2EQbatQ3bXhcH2D1XIAANAcTZkQICBPVaxMeaCVBtOpBZpWJuf7LwyWPSBDITb7In8mqQgJ7gH8CILCURXg==",
-      "cpu": [
-        "x64"
-      ],
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">= 10.0.0"
-      },
-      "funding": {
-        "type": "opencollective",
-        "url": "https://opencollective.com/parcel"
-      }
-    },
-    "node_modules/@parcel/watcher-win32-arm64": {
-      "version": "2.5.1",
-      "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-arm64/-/watcher-win32-arm64-2.5.1.tgz",
-      "integrity": "sha512-RFzklRvmc3PkjKjry3hLF9wD7ppR4AKcWNzH7kXR7GUe0Igb3Nz8fyPwtZCSquGrhU5HhUNDr/mKBqj7tqA2Vw==",
-      "cpu": [
-        "arm64"
-      ],
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "win32"
-      ],
-      "engines": {
-        "node": ">= 10.0.0"
-      },
-      "funding": {
-        "type": "opencollective",
-        "url": "https://opencollective.com/parcel"
-      }
-    },
-    "node_modules/@parcel/watcher-win32-ia32": {
-      "version": "2.5.1",
-      "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-ia32/-/watcher-win32-ia32-2.5.1.tgz",
-      "integrity": "sha512-c2KkcVN+NJmuA7CGlaGD1qJh1cLfDnQsHjE89E60vUEMlqduHGCdCLJCID5geFVM0dOtA3ZiIO8BoEQmzQVfpQ==",
-      "cpu": [
-        "ia32"
-      ],
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "win32"
-      ],
-      "engines": {
-        "node": ">= 10.0.0"
-      },
-      "funding": {
-        "type": "opencollective",
-        "url": "https://opencollective.com/parcel"
-      }
-    },
-    "node_modules/@parcel/watcher-win32-x64": {
-      "version": "2.5.1",
-      "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-x64/-/watcher-win32-x64-2.5.1.tgz",
-      "integrity": "sha512-9lHBdJITeNR++EvSQVUcaZoWupyHfXe1jZvGZ06O/5MflPcuPLtEphScIBL+AiCWBO46tDSHzWyD0uDmmZqsgA==",
-      "cpu": [
-        "x64"
-      ],
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "win32"
-      ],
-      "engines": {
-        "node": ">= 10.0.0"
-      },
-      "funding": {
-        "type": "opencollective",
-        "url": "https://opencollective.com/parcel"
-      }
-    },
-    "node_modules/@pkgjs/parseargs": {
-      "version": "0.11.0",
-      "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz",
-      "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==",
-      "dev": true,
-      "license": "MIT",
-      "optional": true,
-      "engines": {
-        "node": ">=14"
-      }
-    },
-    "node_modules/@pkgr/core": {
-      "version": "0.1.1",
-      "resolved": "https://registry.npmjs.org/@pkgr/core/-/core-0.1.1.tgz",
-      "integrity": "sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": "^12.20.0 || ^14.18.0 || >=16.0.0"
-      },
-      "funding": {
-        "url": "https://opencollective.com/unts"
-      }
-    },
-    "node_modules/@polka/url": {
-      "version": "1.0.0-next.28",
-      "resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.28.tgz",
-      "integrity": "sha512-8LduaNlMZGwdZ6qWrKlfa+2M4gahzFkprZiAt2TF8uS0qQgBizKXpXURqvTJ4WtmupWxaLqjRb2UCTe72mu+Aw==",
-      "dev": true,
-      "license": "MIT"
-    },
-    "node_modules/@popperjs/core": {
-      "version": "2.11.8",
-      "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz",
-      "integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==",
-      "license": "MIT",
-      "peer": true,
-      "funding": {
-        "type": "opencollective",
-        "url": "https://opencollective.com/popperjs"
-      }
-    },
-    "node_modules/@rollup/pluginutils": {
-      "version": "5.1.4",
-      "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.1.4.tgz",
-      "integrity": "sha512-USm05zrsFxYLPdWWq+K3STlWiT/3ELn3RcV5hJMghpeAIhxfsUIg6mt12CBJBInWMV4VneoV7SfGv8xIwo2qNQ==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "@types/estree": "^1.0.0",
-        "estree-walker": "^2.0.2",
-        "picomatch": "^4.0.2"
-      },
-      "engines": {
-        "node": ">=14.0.0"
-      },
-      "peerDependencies": {
-        "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0"
-      },
-      "peerDependenciesMeta": {
-        "rollup": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@rollup/pluginutils/node_modules/picomatch": {
-      "version": "4.0.2",
-      "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz",
-      "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">=12"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/jonschlinkert"
-      }
-    },
-    "node_modules/@rollup/rollup-android-arm-eabi": {
-      "version": "4.31.0",
-      "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.31.0.tgz",
-      "integrity": "sha512-9NrR4033uCbUBRgvLcBrJofa2KY9DzxL2UKZ1/4xA/mnTNyhZCWBuD8X3tPm1n4KxcgaraOYgrFKSgwjASfmlA==",
-      "cpu": [
-        "arm"
-      ],
-      "dev": true,
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "android"
-      ]
-    },
-    "node_modules/@rollup/rollup-android-arm64": {
-      "version": "4.31.0",
-      "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.31.0.tgz",
-      "integrity": "sha512-iBbODqT86YBFHajxxF8ebj2hwKm1k8PTBQSojSt3d1FFt1gN+xf4CowE47iN0vOSdnd+5ierMHBbu/rHc7nq5g==",
-      "cpu": [
-        "arm64"
-      ],
-      "dev": true,
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "android"
-      ]
-    },
-    "node_modules/@rollup/rollup-darwin-arm64": {
-      "version": "4.31.0",
-      "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.31.0.tgz",
-      "integrity": "sha512-WHIZfXgVBX30SWuTMhlHPXTyN20AXrLH4TEeH/D0Bolvx9PjgZnn4H677PlSGvU6MKNsjCQJYczkpvBbrBnG6g==",
-      "cpu": [
-        "arm64"
-      ],
-      "dev": true,
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "darwin"
-      ]
-    },
-    "node_modules/@rollup/rollup-darwin-x64": {
-      "version": "4.31.0",
-      "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.31.0.tgz",
-      "integrity": "sha512-hrWL7uQacTEF8gdrQAqcDy9xllQ0w0zuL1wk1HV8wKGSGbKPVjVUv/DEwT2+Asabf8Dh/As+IvfdU+H8hhzrQQ==",
-      "cpu": [
-        "x64"
-      ],
-      "dev": true,
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "darwin"
-      ]
-    },
-    "node_modules/@rollup/rollup-freebsd-arm64": {
-      "version": "4.31.0",
-      "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.31.0.tgz",
-      "integrity": "sha512-S2oCsZ4hJviG1QjPY1h6sVJLBI6ekBeAEssYKad1soRFv3SocsQCzX6cwnk6fID6UQQACTjeIMB+hyYrFacRew==",
-      "cpu": [
-        "arm64"
-      ],
-      "dev": true,
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "freebsd"
-      ]
-    },
-    "node_modules/@rollup/rollup-freebsd-x64": {
-      "version": "4.31.0",
-      "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.31.0.tgz",
-      "integrity": "sha512-pCANqpynRS4Jirn4IKZH4tnm2+2CqCNLKD7gAdEjzdLGbH1iO0zouHz4mxqg0uEMpO030ejJ0aA6e1PJo2xrPA==",
-      "cpu": [
-        "x64"
-      ],
-      "dev": true,
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "freebsd"
-      ]
-    },
-    "node_modules/@rollup/rollup-linux-arm-gnueabihf": {
-      "version": "4.31.0",
-      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.31.0.tgz",
-      "integrity": "sha512-0O8ViX+QcBd3ZmGlcFTnYXZKGbFu09EhgD27tgTdGnkcYXLat4KIsBBQeKLR2xZDCXdIBAlWLkiXE1+rJpCxFw==",
-      "cpu": [
-        "arm"
-      ],
-      "dev": true,
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "linux"
-      ]
-    },
-    "node_modules/@rollup/rollup-linux-arm-musleabihf": {
-      "version": "4.31.0",
-      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.31.0.tgz",
-      "integrity": "sha512-w5IzG0wTVv7B0/SwDnMYmbr2uERQp999q8FMkKG1I+j8hpPX2BYFjWe69xbhbP6J9h2gId/7ogesl9hwblFwwg==",
-      "cpu": [
-        "arm"
-      ],
-      "dev": true,
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "linux"
-      ]
-    },
-    "node_modules/@rollup/rollup-linux-arm64-gnu": {
-      "version": "4.31.0",
-      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.31.0.tgz",
-      "integrity": "sha512-JyFFshbN5xwy6fulZ8B/8qOqENRmDdEkcIMF0Zz+RsfamEW+Zabl5jAb0IozP/8UKnJ7g2FtZZPEUIAlUSX8cA==",
-      "cpu": [
-        "arm64"
-      ],
-      "dev": true,
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "linux"
-      ]
-    },
-    "node_modules/@rollup/rollup-linux-arm64-musl": {
-      "version": "4.31.0",
-      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.31.0.tgz",
-      "integrity": "sha512-kpQXQ0UPFeMPmPYksiBL9WS/BDiQEjRGMfklVIsA0Sng347H8W2iexch+IEwaR7OVSKtr2ZFxggt11zVIlZ25g==",
-      "cpu": [
-        "arm64"
-      ],
-      "dev": true,
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "linux"
-      ]
-    },
-    "node_modules/@rollup/rollup-linux-loongarch64-gnu": {
-      "version": "4.31.0",
-      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.31.0.tgz",
-      "integrity": "sha512-pMlxLjt60iQTzt9iBb3jZphFIl55a70wexvo8p+vVFK+7ifTRookdoXX3bOsRdmfD+OKnMozKO6XM4zR0sHRrQ==",
-      "cpu": [
-        "loong64"
-      ],
-      "dev": true,
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "linux"
-      ]
-    },
-    "node_modules/@rollup/rollup-linux-powerpc64le-gnu": {
-      "version": "4.31.0",
-      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.31.0.tgz",
-      "integrity": "sha512-D7TXT7I/uKEuWiRkEFbed1UUYZwcJDU4vZQdPTcepK7ecPhzKOYk4Er2YR4uHKme4qDeIh6N3XrLfpuM7vzRWQ==",
-      "cpu": [
-        "ppc64"
-      ],
-      "dev": true,
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "linux"
-      ]
-    },
-    "node_modules/@rollup/rollup-linux-riscv64-gnu": {
-      "version": "4.31.0",
-      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.31.0.tgz",
-      "integrity": "sha512-wal2Tc8O5lMBtoePLBYRKj2CImUCJ4UNGJlLwspx7QApYny7K1cUYlzQ/4IGQBLmm+y0RS7dwc3TDO/pmcneTw==",
-      "cpu": [
-        "riscv64"
-      ],
-      "dev": true,
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "linux"
-      ]
-    },
-    "node_modules/@rollup/rollup-linux-s390x-gnu": {
-      "version": "4.31.0",
-      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.31.0.tgz",
-      "integrity": "sha512-O1o5EUI0+RRMkK9wiTVpk2tyzXdXefHtRTIjBbmFREmNMy7pFeYXCFGbhKFwISA3UOExlo5GGUuuj3oMKdK6JQ==",
-      "cpu": [
-        "s390x"
-      ],
-      "dev": true,
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "linux"
-      ]
-    },
-    "node_modules/@rollup/rollup-linux-x64-gnu": {
-      "version": "4.31.0",
-      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.31.0.tgz",
-      "integrity": "sha512-zSoHl356vKnNxwOWnLd60ixHNPRBglxpv2g7q0Cd3Pmr561gf0HiAcUBRL3S1vPqRC17Zo2CX/9cPkqTIiai1g==",
-      "cpu": [
-        "x64"
-      ],
-      "dev": true,
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "linux"
-      ]
-    },
-    "node_modules/@rollup/rollup-linux-x64-musl": {
-      "version": "4.31.0",
-      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.31.0.tgz",
-      "integrity": "sha512-ypB/HMtcSGhKUQNiFwqgdclWNRrAYDH8iMYH4etw/ZlGwiTVxBz2tDrGRrPlfZu6QjXwtd+C3Zib5pFqID97ZA==",
-      "cpu": [
-        "x64"
-      ],
-      "dev": true,
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "linux"
-      ]
-    },
-    "node_modules/@rollup/rollup-win32-arm64-msvc": {
-      "version": "4.31.0",
-      "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.31.0.tgz",
-      "integrity": "sha512-JuhN2xdI/m8Hr+aVO3vspO7OQfUFO6bKLIRTAy0U15vmWjnZDLrEgCZ2s6+scAYaQVpYSh9tZtRijApw9IXyMw==",
-      "cpu": [
-        "arm64"
-      ],
-      "dev": true,
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "win32"
-      ]
-    },
-    "node_modules/@rollup/rollup-win32-ia32-msvc": {
-      "version": "4.31.0",
-      "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.31.0.tgz",
-      "integrity": "sha512-U1xZZXYkvdf5MIWmftU8wrM5PPXzyaY1nGCI4KI4BFfoZxHamsIe+BtnPLIvvPykvQWlVbqUXdLa4aJUuilwLQ==",
-      "cpu": [
-        "ia32"
-      ],
-      "dev": true,
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "win32"
-      ]
-    },
-    "node_modules/@rollup/rollup-win32-x64-msvc": {
-      "version": "4.31.0",
-      "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.31.0.tgz",
-      "integrity": "sha512-ul8rnCsUumNln5YWwz0ted2ZHFhzhRRnkpBZ+YRuHoRAlUji9KChpOUOndY7uykrPEPXVbHLlsdo6v5yXo/TXw==",
-      "cpu": [
-        "x64"
-      ],
-      "dev": true,
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "win32"
-      ]
-    },
-    "node_modules/@sec-ant/readable-stream": {
-      "version": "0.4.1",
-      "resolved": "https://registry.npmjs.org/@sec-ant/readable-stream/-/readable-stream-0.4.1.tgz",
-      "integrity": "sha512-831qok9r2t8AlxLko40y2ebgSDhenenCatLVeW/uBtnHPyhHOvG0C7TvfgecV+wHzIm5KUICgzmVpWS+IMEAeg==",
-      "dev": true,
-      "license": "MIT"
-    },
-    "node_modules/@sindresorhus/merge-streams": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/@sindresorhus/merge-streams/-/merge-streams-4.0.0.tgz",
-      "integrity": "sha512-tlqY9xq5ukxTUZBmoOp+m61cqwQD5pHJtFY3Mn8CA8ps6yghLH/Hw8UPdqg4OLmFW3IFlcXnQNmo/dh8HzXYIQ==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">=18"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/@types/eslint": {
-      "version": "9.6.1",
-      "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-9.6.1.tgz",
-      "integrity": "sha512-FXx2pKgId/WyYo2jXw63kk7/+TY7u7AziEJxJAnSFzHlqTAS3Ync6SvgYAN/k4/PQpnnVuzoMuVnByKK2qp0ag==",
-      "license": "MIT",
-      "dependencies": {
-        "@types/estree": "*",
-        "@types/json-schema": "*"
-      }
-    },
-    "node_modules/@types/eslint-scope": {
-      "version": "3.7.7",
-      "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.7.tgz",
-      "integrity": "sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==",
-      "license": "MIT",
-      "dependencies": {
-        "@types/eslint": "*",
-        "@types/estree": "*"
-      }
-    },
-    "node_modules/@types/estree": {
-      "version": "1.0.6",
-      "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz",
-      "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==",
-      "license": "MIT"
-    },
-    "node_modules/@types/json-schema": {
-      "version": "7.0.15",
-      "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz",
-      "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==",
-      "license": "MIT"
-    },
-    "node_modules/@types/node": {
-      "version": "22.15.18",
-      "resolved": "https://registry.npmjs.org/@types/node/-/node-22.15.18.tgz",
-      "integrity": "sha512-v1DKRfUdyW+jJhZNEI1PYy29S2YRxMV5AOO/x/SjKmW0acCIOqmbj6Haf9eHAhsPmrhlHSxEhv/1WszcLWV4cg==",
-      "license": "MIT",
-      "dependencies": {
-        "undici-types": "~6.21.0"
-      }
-    },
-    "node_modules/@typescript-eslint/eslint-plugin": {
-      "version": "8.54.0",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.54.0.tgz",
-      "integrity": "sha512-hAAP5io/7csFStuOmR782YmTthKBJ9ND3WVL60hcOjvtGFb+HJxH4O5huAcmcZ9v9G8P+JETiZ/G1B8MALnWZQ==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "@eslint-community/regexpp": "^4.12.2",
-        "@typescript-eslint/scope-manager": "8.54.0",
-        "@typescript-eslint/type-utils": "8.54.0",
-        "@typescript-eslint/utils": "8.54.0",
-        "@typescript-eslint/visitor-keys": "8.54.0",
-        "ignore": "^7.0.5",
-        "natural-compare": "^1.4.0",
-        "ts-api-utils": "^2.4.0"
-      },
-      "engines": {
-        "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
-      },
-      "funding": {
-        "type": "opencollective",
-        "url": "https://opencollective.com/typescript-eslint"
-      },
-      "peerDependencies": {
-        "@typescript-eslint/parser": "^8.54.0",
-        "eslint": "^8.57.0 || ^9.0.0",
-        "typescript": ">=4.8.4 <6.0.0"
-      }
-    },
-    "node_modules/@typescript-eslint/eslint-plugin/node_modules/ignore": {
-      "version": "7.0.5",
-      "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz",
-      "integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">= 4"
-      }
-    },
-    "node_modules/@typescript-eslint/parser": {
-      "version": "8.54.0",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.54.0.tgz",
-      "integrity": "sha512-BtE0k6cjwjLZoZixN0t5AKP0kSzlGu7FctRXYuPAm//aaiZhmfq1JwdYpYr1brzEspYyFeF+8XF5j2VK6oalrA==",
-      "dev": true,
-      "license": "MIT",
-      "peer": true,
-      "dependencies": {
-        "@typescript-eslint/scope-manager": "8.54.0",
-        "@typescript-eslint/types": "8.54.0",
-        "@typescript-eslint/typescript-estree": "8.54.0",
-        "@typescript-eslint/visitor-keys": "8.54.0",
-        "debug": "^4.4.3"
-      },
-      "engines": {
-        "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
-      },
-      "funding": {
-        "type": "opencollective",
-        "url": "https://opencollective.com/typescript-eslint"
-      },
-      "peerDependencies": {
-        "eslint": "^8.57.0 || ^9.0.0",
-        "typescript": ">=4.8.4 <6.0.0"
-      }
-    },
-    "node_modules/@typescript-eslint/project-service": {
-      "version": "8.54.0",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.54.0.tgz",
-      "integrity": "sha512-YPf+rvJ1s7MyiWM4uTRhE4DvBXrEV+d8oC3P9Y2eT7S+HBS0clybdMIPnhiATi9vZOYDc7OQ1L/i6ga6NFYK/g==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "@typescript-eslint/tsconfig-utils": "^8.54.0",
-        "@typescript-eslint/types": "^8.54.0",
-        "debug": "^4.4.3"
-      },
-      "engines": {
-        "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
-      },
-      "funding": {
-        "type": "opencollective",
-        "url": "https://opencollective.com/typescript-eslint"
-      },
-      "peerDependencies": {
-        "typescript": ">=4.8.4 <6.0.0"
-      }
-    },
-    "node_modules/@typescript-eslint/scope-manager": {
-      "version": "8.54.0",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.54.0.tgz",
-      "integrity": "sha512-27rYVQku26j/PbHYcVfRPonmOlVI6gihHtXFbTdB5sb6qA0wdAQAbyXFVarQ5t4HRojIz64IV90YtsjQSSGlQg==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "@typescript-eslint/types": "8.54.0",
-        "@typescript-eslint/visitor-keys": "8.54.0"
-      },
-      "engines": {
-        "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
-      },
-      "funding": {
-        "type": "opencollective",
-        "url": "https://opencollective.com/typescript-eslint"
-      }
-    },
-    "node_modules/@typescript-eslint/tsconfig-utils": {
-      "version": "8.54.0",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.54.0.tgz",
-      "integrity": "sha512-dRgOyT2hPk/JwxNMZDsIXDgyl9axdJI3ogZ2XWhBPsnZUv+hPesa5iuhdYt2gzwA9t8RE5ytOJ6xB0moV0Ujvw==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
-      },
-      "funding": {
-        "type": "opencollective",
-        "url": "https://opencollective.com/typescript-eslint"
-      },
-      "peerDependencies": {
-        "typescript": ">=4.8.4 <6.0.0"
-      }
-    },
-    "node_modules/@typescript-eslint/type-utils": {
-      "version": "8.54.0",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.54.0.tgz",
-      "integrity": "sha512-hiLguxJWHjjwL6xMBwD903ciAwd7DmK30Y9Axs/etOkftC3ZNN9K44IuRD/EB08amu+Zw6W37x9RecLkOo3pMA==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "@typescript-eslint/types": "8.54.0",
-        "@typescript-eslint/typescript-estree": "8.54.0",
-        "@typescript-eslint/utils": "8.54.0",
-        "debug": "^4.4.3",
-        "ts-api-utils": "^2.4.0"
-      },
-      "engines": {
-        "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
-      },
-      "funding": {
-        "type": "opencollective",
-        "url": "https://opencollective.com/typescript-eslint"
-      },
-      "peerDependencies": {
-        "eslint": "^8.57.0 || ^9.0.0",
-        "typescript": ">=4.8.4 <6.0.0"
-      }
-    },
-    "node_modules/@typescript-eslint/types": {
-      "version": "8.54.0",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.54.0.tgz",
-      "integrity": "sha512-PDUI9R1BVjqu7AUDsRBbKMtwmjWcn4J3le+5LpcFgWULN3LvHC5rkc9gCVxbrsrGmO1jfPybN5s6h4Jy+OnkAA==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
-      },
-      "funding": {
-        "type": "opencollective",
-        "url": "https://opencollective.com/typescript-eslint"
-      }
-    },
-    "node_modules/@typescript-eslint/typescript-estree": {
-      "version": "8.54.0",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.54.0.tgz",
-      "integrity": "sha512-BUwcskRaPvTk6fzVWgDPdUndLjB87KYDrN5EYGetnktoeAvPtO4ONHlAZDnj5VFnUANg0Sjm7j4usBlnoVMHwA==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "@typescript-eslint/project-service": "8.54.0",
-        "@typescript-eslint/tsconfig-utils": "8.54.0",
-        "@typescript-eslint/types": "8.54.0",
-        "@typescript-eslint/visitor-keys": "8.54.0",
-        "debug": "^4.4.3",
-        "minimatch": "^9.0.5",
-        "semver": "^7.7.3",
-        "tinyglobby": "^0.2.15",
-        "ts-api-utils": "^2.4.0"
-      },
-      "engines": {
-        "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
-      },
-      "funding": {
-        "type": "opencollective",
-        "url": "https://opencollective.com/typescript-eslint"
-      },
-      "peerDependencies": {
-        "typescript": ">=4.8.4 <6.0.0"
-      }
-    },
-    "node_modules/@typescript-eslint/utils": {
-      "version": "8.54.0",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.54.0.tgz",
-      "integrity": "sha512-9Cnda8GS57AQakvRyG0PTejJNlA2xhvyNtEVIMlDWOOeEyBkYWhGPnfrIAnqxLMTSTo6q8g12XVjjev5l1NvMA==",
-      "dev": true,
-      "license": "MIT",
-      "peer": true,
-      "dependencies": {
-        "@eslint-community/eslint-utils": "^4.9.1",
-        "@typescript-eslint/scope-manager": "8.54.0",
-        "@typescript-eslint/types": "8.54.0",
-        "@typescript-eslint/typescript-estree": "8.54.0"
-      },
-      "engines": {
-        "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
-      },
-      "funding": {
-        "type": "opencollective",
-        "url": "https://opencollective.com/typescript-eslint"
-      },
-      "peerDependencies": {
-        "eslint": "^8.57.0 || ^9.0.0",
-        "typescript": ">=4.8.4 <6.0.0"
-      }
-    },
-    "node_modules/@typescript-eslint/visitor-keys": {
-      "version": "8.54.0",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.54.0.tgz",
-      "integrity": "sha512-VFlhGSl4opC0bprJiItPQ1RfUhGDIBokcPwaFH4yiBCaNPeld/9VeXbiPO1cLyorQi1G1vL+ecBk1x8o1axORA==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "@typescript-eslint/types": "8.54.0",
-        "eslint-visitor-keys": "^4.2.1"
-      },
-      "engines": {
-        "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
-      },
-      "funding": {
-        "type": "opencollective",
-        "url": "https://opencollective.com/typescript-eslint"
-      }
-    },
-    "node_modules/@typescript-eslint/visitor-keys/node_modules/eslint-visitor-keys": {
-      "version": "4.2.1",
-      "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz",
-      "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==",
-      "dev": true,
-      "license": "Apache-2.0",
-      "engines": {
-        "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
-      },
-      "funding": {
-        "url": "https://opencollective.com/eslint"
-      }
-    },
-    "node_modules/@vitejs/plugin-vue": {
-      "version": "5.2.1",
-      "resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-5.2.1.tgz",
-      "integrity": "sha512-cxh314tzaWwOLqVes2gnnCtvBDcM1UMdn+iFR+UjAn411dPT3tOmqrJjbMd7koZpMAmBM/GqeV4n9ge7JSiJJQ==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": "^18.0.0 || >=20.0.0"
-      },
-      "peerDependencies": {
-        "vite": "^5.0.0 || ^6.0.0",
-        "vue": "^3.2.25"
-      }
-    },
-    "node_modules/@vitest/eslint-plugin": {
-      "version": "1.1.25",
-      "resolved": "https://registry.npmjs.org/@vitest/eslint-plugin/-/eslint-plugin-1.1.25.tgz",
-      "integrity": "sha512-u8DpDnMbPcqBmJOB4PeEtn6q7vKmLVTLFMpzoxSAo0hjYdl4iYSHRleqwPQo0ywc7UV0S6RKIahYRQ3BnZdMVw==",
-      "dev": true,
-      "license": "MIT",
-      "peerDependencies": {
-        "@typescript-eslint/utils": ">= 8.0",
-        "eslint": ">= 8.57.0",
-        "typescript": ">= 5.0.0",
-        "vitest": "*"
-      },
-      "peerDependenciesMeta": {
-        "typescript": {
-          "optional": true
-        },
-        "vitest": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@vitest/expect": {
-      "version": "3.0.3",
-      "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-3.0.3.tgz",
-      "integrity": "sha512-SbRCHU4qr91xguu+dH3RUdI5dC86zm8aZWydbp961aIR7G8OYNN6ZiayFuf9WAngRbFOfdrLHCGgXTj3GtoMRQ==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "@vitest/spy": "3.0.3",
-        "@vitest/utils": "3.0.3",
-        "chai": "^5.1.2",
-        "tinyrainbow": "^2.0.0"
-      },
-      "funding": {
-        "url": "https://opencollective.com/vitest"
-      }
-    },
-    "node_modules/@vitest/mocker": {
-      "version": "3.0.3",
-      "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-3.0.3.tgz",
-      "integrity": "sha512-XT2XBc4AN9UdaxJAeIlcSZ0ILi/GzmG5G8XSly4gaiqIvPV3HMTSIDZWJVX6QRJ0PX1m+W8Cy0K9ByXNb/bPIA==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "@vitest/spy": "3.0.3",
-        "estree-walker": "^3.0.3",
-        "magic-string": "^0.30.17"
-      },
-      "funding": {
-        "url": "https://opencollective.com/vitest"
-      },
-      "peerDependencies": {
-        "msw": "^2.4.9",
-        "vite": "^5.0.0 || ^6.0.0"
-      },
-      "peerDependenciesMeta": {
-        "msw": {
-          "optional": true
-        },
-        "vite": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@vitest/mocker/node_modules/estree-walker": {
-      "version": "3.0.3",
-      "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz",
-      "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "@types/estree": "^1.0.0"
-      }
-    },
-    "node_modules/@vitest/pretty-format": {
-      "version": "3.0.3",
-      "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-3.0.3.tgz",
-      "integrity": "sha512-gCrM9F7STYdsDoNjGgYXKPq4SkSxwwIU5nkaQvdUxiQ0EcNlez+PdKOVIsUJvh9P9IeIFmjn4IIREWblOBpP2Q==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "tinyrainbow": "^2.0.0"
-      },
-      "funding": {
-        "url": "https://opencollective.com/vitest"
-      }
-    },
-    "node_modules/@vitest/runner": {
-      "version": "3.0.3",
-      "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-3.0.3.tgz",
-      "integrity": "sha512-Rgi2kOAk5ZxWZlwPguRJFOBmWs6uvvyAAR9k3MvjRvYrG7xYvKChZcmnnpJCS98311CBDMqsW9MzzRFsj2gX3g==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "@vitest/utils": "3.0.3",
-        "pathe": "^2.0.1"
-      },
-      "funding": {
-        "url": "https://opencollective.com/vitest"
-      }
-    },
-    "node_modules/@vitest/runner/node_modules/pathe": {
-      "version": "2.0.2",
-      "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.2.tgz",
-      "integrity": "sha512-15Ztpk+nov8DR524R4BF7uEuzESgzUEAV4Ah7CUMNGXdE5ELuvxElxGXndBl32vMSsWa1jpNf22Z+Er3sKwq+w==",
-      "dev": true,
-      "license": "MIT"
-    },
-    "node_modules/@vitest/snapshot": {
-      "version": "3.0.3",
-      "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-3.0.3.tgz",
-      "integrity": "sha512-kNRcHlI4txBGztuJfPEJ68VezlPAXLRT1u5UCx219TU3kOG2DplNxhWLwDf2h6emwmTPogzLnGVwP6epDaJN6Q==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "@vitest/pretty-format": "3.0.3",
-        "magic-string": "^0.30.17",
-        "pathe": "^2.0.1"
-      },
-      "funding": {
-        "url": "https://opencollective.com/vitest"
-      }
-    },
-    "node_modules/@vitest/snapshot/node_modules/pathe": {
-      "version": "2.0.2",
-      "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.2.tgz",
-      "integrity": "sha512-15Ztpk+nov8DR524R4BF7uEuzESgzUEAV4Ah7CUMNGXdE5ELuvxElxGXndBl32vMSsWa1jpNf22Z+Er3sKwq+w==",
-      "dev": true,
-      "license": "MIT"
-    },
-    "node_modules/@vitest/spy": {
-      "version": "3.0.3",
-      "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-3.0.3.tgz",
-      "integrity": "sha512-7/dgux8ZBbF7lEIKNnEqQlyRaER9nkAL9eTmdKJkDO3hS8p59ATGwKOCUDHcBLKr7h/oi/6hP+7djQk8049T2A==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "tinyspy": "^3.0.2"
-      },
-      "funding": {
-        "url": "https://opencollective.com/vitest"
-      }
-    },
-    "node_modules/@vitest/utils": {
-      "version": "3.0.3",
-      "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-3.0.3.tgz",
-      "integrity": "sha512-f+s8CvyzPtMFY1eZKkIHGhPsQgYo5qCm6O8KZoim9qm1/jT64qBgGpO5tHscNH6BzRHM+edLNOP+3vO8+8pE/A==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "@vitest/pretty-format": "3.0.3",
-        "loupe": "^3.1.2",
-        "tinyrainbow": "^2.0.0"
-      },
-      "funding": {
-        "url": "https://opencollective.com/vitest"
-      }
-    },
-    "node_modules/@vue/babel-helper-vue-transform-on": {
-      "version": "1.2.5",
-      "resolved": "https://registry.npmjs.org/@vue/babel-helper-vue-transform-on/-/babel-helper-vue-transform-on-1.2.5.tgz",
-      "integrity": "sha512-lOz4t39ZdmU4DJAa2hwPYmKc8EsuGa2U0L9KaZaOJUt0UwQNjNA3AZTq6uEivhOKhhG1Wvy96SvYBoFmCg3uuw==",
-      "dev": true,
-      "license": "MIT"
-    },
-    "node_modules/@vue/babel-plugin-jsx": {
-      "version": "1.2.5",
-      "resolved": "https://registry.npmjs.org/@vue/babel-plugin-jsx/-/babel-plugin-jsx-1.2.5.tgz",
-      "integrity": "sha512-zTrNmOd4939H9KsRIGmmzn3q2zvv1mjxkYZHgqHZgDrXz5B1Q3WyGEjO2f+JrmKghvl1JIRcvo63LgM1kH5zFg==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "@babel/helper-module-imports": "^7.24.7",
-        "@babel/helper-plugin-utils": "^7.24.8",
-        "@babel/plugin-syntax-jsx": "^7.24.7",
-        "@babel/template": "^7.25.0",
-        "@babel/traverse": "^7.25.6",
-        "@babel/types": "^7.25.6",
-        "@vue/babel-helper-vue-transform-on": "1.2.5",
-        "@vue/babel-plugin-resolve-type": "1.2.5",
-        "html-tags": "^3.3.1",
-        "svg-tags": "^1.0.0"
-      },
-      "peerDependencies": {
-        "@babel/core": "^7.0.0-0"
-      },
-      "peerDependenciesMeta": {
-        "@babel/core": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@vue/babel-plugin-resolve-type": {
-      "version": "1.2.5",
-      "resolved": "https://registry.npmjs.org/@vue/babel-plugin-resolve-type/-/babel-plugin-resolve-type-1.2.5.tgz",
-      "integrity": "sha512-U/ibkQrf5sx0XXRnUZD1mo5F7PkpKyTbfXM3a3rC4YnUz6crHEz9Jg09jzzL6QYlXNto/9CePdOg/c87O4Nlfg==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "@babel/code-frame": "^7.24.7",
-        "@babel/helper-module-imports": "^7.24.7",
-        "@babel/helper-plugin-utils": "^7.24.8",
-        "@babel/parser": "^7.25.6",
-        "@vue/compiler-sfc": "^3.5.3"
-      },
-      "peerDependencies": {
-        "@babel/core": "^7.0.0-0"
-      }
-    },
-    "node_modules/@vue/compiler-core": {
-      "version": "3.5.13",
-      "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.5.13.tgz",
-      "integrity": "sha512-oOdAkwqUfW1WqpwSYJce06wvt6HljgY3fGeM9NcVA1HaYOij3mZG9Rkysn0OHuyUAGMbEbARIpsG+LPVlBJ5/Q==",
-      "license": "MIT",
-      "dependencies": {
-        "@babel/parser": "^7.25.3",
-        "@vue/shared": "3.5.13",
-        "entities": "^4.5.0",
-        "estree-walker": "^2.0.2",
-        "source-map-js": "^1.2.0"
-      }
-    },
-    "node_modules/@vue/compiler-dom": {
-      "version": "3.5.13",
-      "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.5.13.tgz",
-      "integrity": "sha512-ZOJ46sMOKUjO3e94wPdCzQ6P1Lx/vhp2RSvfaab88Ajexs0AHeV0uasYhi99WPaogmBlRHNRuly8xV75cNTMDA==",
-      "license": "MIT",
-      "dependencies": {
-        "@vue/compiler-core": "3.5.13",
-        "@vue/shared": "3.5.13"
-      }
-    },
-    "node_modules/@vue/compiler-sfc": {
-      "version": "3.5.13",
-      "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.5.13.tgz",
-      "integrity": "sha512-6VdaljMpD82w6c2749Zhf5T9u5uLBWKnVue6XWxprDobftnletJ8+oel7sexFfM3qIxNmVE7LSFGTpv6obNyaQ==",
-      "license": "MIT",
-      "dependencies": {
-        "@babel/parser": "^7.25.3",
-        "@vue/compiler-core": "3.5.13",
-        "@vue/compiler-dom": "3.5.13",
-        "@vue/compiler-ssr": "3.5.13",
-        "@vue/shared": "3.5.13",
-        "estree-walker": "^2.0.2",
-        "magic-string": "^0.30.11",
-        "postcss": "^8.4.48",
-        "source-map-js": "^1.2.0"
-      }
-    },
-    "node_modules/@vue/compiler-ssr": {
-      "version": "3.5.13",
-      "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.5.13.tgz",
-      "integrity": "sha512-wMH6vrYHxQl/IybKJagqbquvxpWCuVYpoUJfCqFZwa/JY1GdATAQ+TgVtgrwwMZ0D07QhA99rs/EAAWfvG6KpA==",
-      "license": "MIT",
-      "dependencies": {
-        "@vue/compiler-dom": "3.5.13",
-        "@vue/shared": "3.5.13"
-      }
-    },
-    "node_modules/@vue/devtools-api": {
-      "version": "6.6.4",
-      "resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-6.6.4.tgz",
-      "integrity": "sha512-sGhTPMuXqZ1rVOk32RylztWkfXTRhuS7vgAKv0zjqk8gbsHkJ7xfFf+jbySxt7tWObEJwyKaHMikV/WGDiQm8g==",
-      "license": "MIT"
-    },
-    "node_modules/@vue/devtools-core": {
-      "version": "7.7.0",
-      "resolved": "https://registry.npmjs.org/@vue/devtools-core/-/devtools-core-7.7.0.tgz",
-      "integrity": "sha512-tSO3pghV5RZGSonZ87S2fOGru3X93epmar5IjZOWjHxH6XSwnK5UbR2aW5puZV+LgLoVYrcNou3krSo5k1F31g==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "@vue/devtools-kit": "^7.7.0",
-        "@vue/devtools-shared": "^7.7.0",
-        "mitt": "^3.0.1",
-        "nanoid": "^5.0.9",
-        "pathe": "^1.1.2",
-        "vite-hot-client": "^0.2.4"
-      },
-      "peerDependencies": {
-        "vue": "^3.0.0"
-      }
-    },
-    "node_modules/@vue/devtools-core/node_modules/nanoid": {
-      "version": "5.0.9",
-      "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-5.0.9.tgz",
-      "integrity": "sha512-Aooyr6MXU6HpvvWXKoVoXwKMs/KyVakWwg7xQfv5/S/RIgJMy0Ifa45H9qqYy7pTCszrHzP21Uk4PZq2HpEM8Q==",
-      "dev": true,
-      "funding": [
-        {
-          "type": "github",
-          "url": "https://github.com/sponsors/ai"
-        }
-      ],
-      "license": "MIT",
-      "bin": {
-        "nanoid": "bin/nanoid.js"
-      },
-      "engines": {
-        "node": "^18 || >=20"
-      }
-    },
-    "node_modules/@vue/devtools-kit": {
-      "version": "7.7.0",
-      "resolved": "https://registry.npmjs.org/@vue/devtools-kit/-/devtools-kit-7.7.0.tgz",
-      "integrity": "sha512-5cvZ+6SA88zKC8XiuxUfqpdTwVjJbvYnQZY5NReh7qlSGPvVDjjzyEtW+gdzLXNSd8tStgOjAdMCpvDQamUXtA==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "@vue/devtools-shared": "^7.7.0",
-        "birpc": "^0.2.19",
-        "hookable": "^5.5.3",
-        "mitt": "^3.0.1",
-        "perfect-debounce": "^1.0.0",
-        "speakingurl": "^14.0.1",
-        "superjson": "^2.2.1"
-      }
-    },
-    "node_modules/@vue/devtools-shared": {
-      "version": "7.7.0",
-      "resolved": "https://registry.npmjs.org/@vue/devtools-shared/-/devtools-shared-7.7.0.tgz",
-      "integrity": "sha512-jtlQY26R5thQxW9YQTpXbI0HoK0Wf9Rd4ekidOkRvSy7ChfK0kIU6vvcBtjj87/EcpeOSK49fZAicaFNJcoTcQ==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "rfdc": "^1.4.1"
-      }
-    },
-    "node_modules/@vue/eslint-config-prettier": {
-      "version": "10.2.0",
-      "resolved": "https://registry.npmjs.org/@vue/eslint-config-prettier/-/eslint-config-prettier-10.2.0.tgz",
-      "integrity": "sha512-GL3YBLwv/+b86yHcNNfPJxOTtVFJ4Mbc9UU3zR+KVoG7SwGTjPT+32fXamscNumElhcpXW3mT0DgzS9w32S7Bw==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "eslint-config-prettier": "^10.0.1",
-        "eslint-plugin-prettier": "^5.2.2"
-      },
-      "peerDependencies": {
-        "eslint": ">= 8.21.0",
-        "prettier": ">= 3.0.0"
-      }
-    },
-    "node_modules/@vue/reactivity": {
-      "version": "3.5.13",
-      "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.5.13.tgz",
-      "integrity": "sha512-NaCwtw8o48B9I6L1zl2p41OHo/2Z4wqYGGIK1Khu5T7yxrn+ATOixn/Udn2m+6kZKB/J7cuT9DbWWhRxqixACg==",
-      "license": "MIT",
-      "dependencies": {
-        "@vue/shared": "3.5.13"
-      }
-    },
-    "node_modules/@vue/runtime-core": {
-      "version": "3.5.13",
-      "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.5.13.tgz",
-      "integrity": "sha512-Fj4YRQ3Az0WTZw1sFe+QDb0aXCerigEpw418pw1HBUKFtnQHWzwojaukAs2X/c9DQz4MQ4bsXTGlcpGxU/RCIw==",
-      "license": "MIT",
-      "dependencies": {
-        "@vue/reactivity": "3.5.13",
-        "@vue/shared": "3.5.13"
-      }
-    },
-    "node_modules/@vue/runtime-dom": {
-      "version": "3.5.13",
-      "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.5.13.tgz",
-      "integrity": "sha512-dLaj94s93NYLqjLiyFzVs9X6dWhTdAlEAciC3Moq7gzAc13VJUdCnjjRurNM6uTLFATRHexHCTu/Xp3eW6yoog==",
-      "license": "MIT",
-      "dependencies": {
-        "@vue/reactivity": "3.5.13",
-        "@vue/runtime-core": "3.5.13",
-        "@vue/shared": "3.5.13",
-        "csstype": "^3.1.3"
-      }
-    },
-    "node_modules/@vue/server-renderer": {
-      "version": "3.5.13",
-      "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.5.13.tgz",
-      "integrity": "sha512-wAi4IRJV/2SAW3htkTlB+dHeRmpTiVIK1OGLWV1yeStVSebSQQOwGwIq0D3ZIoBj2C2qpgz5+vX9iEBkTdk5YA==",
-      "license": "MIT",
-      "dependencies": {
-        "@vue/compiler-ssr": "3.5.13",
-        "@vue/shared": "3.5.13"
-      },
-      "peerDependencies": {
-        "vue": "3.5.13"
-      }
-    },
-    "node_modules/@vue/shared": {
-      "version": "3.5.13",
-      "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.5.13.tgz",
-      "integrity": "sha512-/hnE/qP5ZoGpol0a5mDi45bOd7t3tjYJBjsgCsivow7D48cJeV5l05RD82lPqi7gRiphZM37rnhW1l6ZoCNNnQ==",
-      "license": "MIT"
-    },
-    "node_modules/@vue/test-utils": {
-      "version": "2.4.6",
-      "resolved": "https://registry.npmjs.org/@vue/test-utils/-/test-utils-2.4.6.tgz",
-      "integrity": "sha512-FMxEjOpYNYiFe0GkaHsnJPXFHxQ6m4t8vI/ElPGpMWxZKpmRvQ33OIrvRXemy6yha03RxhOlQuy+gZMC3CQSow==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "js-beautify": "^1.14.9",
-        "vue-component-type-helpers": "^2.0.0"
-      }
-    },
-    "node_modules/@webassemblyjs/ast": {
-      "version": "1.14.1",
-      "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.14.1.tgz",
-      "integrity": "sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ==",
-      "license": "MIT",
-      "dependencies": {
-        "@webassemblyjs/helper-numbers": "1.13.2",
-        "@webassemblyjs/helper-wasm-bytecode": "1.13.2"
-      }
-    },
-    "node_modules/@webassemblyjs/floating-point-hex-parser": {
-      "version": "1.13.2",
-      "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.13.2.tgz",
-      "integrity": "sha512-6oXyTOzbKxGH4steLbLNOu71Oj+C8Lg34n6CqRvqfS2O71BxY6ByfMDRhBytzknj9yGUPVJ1qIKhRlAwO1AovA==",
-      "license": "MIT"
-    },
-    "node_modules/@webassemblyjs/helper-api-error": {
-      "version": "1.13.2",
-      "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.13.2.tgz",
-      "integrity": "sha512-U56GMYxy4ZQCbDZd6JuvvNV/WFildOjsaWD3Tzzvmw/mas3cXzRJPMjP83JqEsgSbyrmaGjBfDtV7KDXV9UzFQ==",
-      "license": "MIT"
-    },
-    "node_modules/@webassemblyjs/helper-buffer": {
-      "version": "1.14.1",
-      "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.14.1.tgz",
-      "integrity": "sha512-jyH7wtcHiKssDtFPRB+iQdxlDf96m0E39yb0k5uJVhFGleZFoNw1c4aeIcVUPPbXUVJ94wwnMOAqUHyzoEPVMA==",
-      "license": "MIT"
-    },
-    "node_modules/@webassemblyjs/helper-numbers": {
-      "version": "1.13.2",
-      "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.13.2.tgz",
-      "integrity": "sha512-FE8aCmS5Q6eQYcV3gI35O4J789wlQA+7JrqTTpJqn5emA4U2hvwJmvFRC0HODS+3Ye6WioDklgd6scJ3+PLnEA==",
-      "license": "MIT",
-      "dependencies": {
-        "@webassemblyjs/floating-point-hex-parser": "1.13.2",
-        "@webassemblyjs/helper-api-error": "1.13.2",
-        "@xtuc/long": "4.2.2"
-      }
-    },
-    "node_modules/@webassemblyjs/helper-wasm-bytecode": {
-      "version": "1.13.2",
-      "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.13.2.tgz",
-      "integrity": "sha512-3QbLKy93F0EAIXLh0ogEVR6rOubA9AoZ+WRYhNbFyuB70j3dRdwH9g+qXhLAO0kiYGlg3TxDV+I4rQTr/YNXkA==",
-      "license": "MIT"
-    },
-    "node_modules/@webassemblyjs/helper-wasm-section": {
-      "version": "1.14.1",
-      "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.14.1.tgz",
-      "integrity": "sha512-ds5mXEqTJ6oxRoqjhWDU83OgzAYjwsCV8Lo/N+oRsNDmx/ZDpqalmrtgOMkHwxsG0iI//3BwWAErYRHtgn0dZw==",
-      "license": "MIT",
-      "dependencies": {
-        "@webassemblyjs/ast": "1.14.1",
-        "@webassemblyjs/helper-buffer": "1.14.1",
-        "@webassemblyjs/helper-wasm-bytecode": "1.13.2",
-        "@webassemblyjs/wasm-gen": "1.14.1"
-      }
-    },
-    "node_modules/@webassemblyjs/ieee754": {
-      "version": "1.13.2",
-      "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.13.2.tgz",
-      "integrity": "sha512-4LtOzh58S/5lX4ITKxnAK2USuNEvpdVV9AlgGQb8rJDHaLeHciwG4zlGr0j/SNWlr7x3vO1lDEsuePvtcDNCkw==",
-      "license": "MIT",
-      "dependencies": {
-        "@xtuc/ieee754": "^1.2.0"
-      }
-    },
-    "node_modules/@webassemblyjs/leb128": {
-      "version": "1.13.2",
-      "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.13.2.tgz",
-      "integrity": "sha512-Lde1oNoIdzVzdkNEAWZ1dZ5orIbff80YPdHx20mrHwHrVNNTjNr8E3xz9BdpcGqRQbAEa+fkrCb+fRFTl/6sQw==",
-      "license": "Apache-2.0",
-      "dependencies": {
-        "@xtuc/long": "4.2.2"
-      }
-    },
-    "node_modules/@webassemblyjs/utf8": {
-      "version": "1.13.2",
-      "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.13.2.tgz",
-      "integrity": "sha512-3NQWGjKTASY1xV5m7Hr0iPeXD9+RDobLll3T9d2AO+g3my8xy5peVyjSag4I50mR1bBSN/Ct12lo+R9tJk0NZQ==",
-      "license": "MIT"
-    },
-    "node_modules/@webassemblyjs/wasm-edit": {
-      "version": "1.14.1",
-      "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.14.1.tgz",
-      "integrity": "sha512-RNJUIQH/J8iA/1NzlE4N7KtyZNHi3w7at7hDjvRNm5rcUXa00z1vRz3glZoULfJ5mpvYhLybmVcwcjGrC1pRrQ==",
-      "license": "MIT",
-      "dependencies": {
-        "@webassemblyjs/ast": "1.14.1",
-        "@webassemblyjs/helper-buffer": "1.14.1",
-        "@webassemblyjs/helper-wasm-bytecode": "1.13.2",
-        "@webassemblyjs/helper-wasm-section": "1.14.1",
-        "@webassemblyjs/wasm-gen": "1.14.1",
-        "@webassemblyjs/wasm-opt": "1.14.1",
-        "@webassemblyjs/wasm-parser": "1.14.1",
-        "@webassemblyjs/wast-printer": "1.14.1"
-      }
-    },
-    "node_modules/@webassemblyjs/wasm-gen": {
-      "version": "1.14.1",
-      "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.14.1.tgz",
-      "integrity": "sha512-AmomSIjP8ZbfGQhumkNvgC33AY7qtMCXnN6bL2u2Js4gVCg8fp735aEiMSBbDR7UQIj90n4wKAFUSEd0QN2Ukg==",
-      "license": "MIT",
-      "dependencies": {
-        "@webassemblyjs/ast": "1.14.1",
-        "@webassemblyjs/helper-wasm-bytecode": "1.13.2",
-        "@webassemblyjs/ieee754": "1.13.2",
-        "@webassemblyjs/leb128": "1.13.2",
-        "@webassemblyjs/utf8": "1.13.2"
-      }
-    },
-    "node_modules/@webassemblyjs/wasm-opt": {
-      "version": "1.14.1",
-      "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.14.1.tgz",
-      "integrity": "sha512-PTcKLUNvBqnY2U6E5bdOQcSM+oVP/PmrDY9NzowJjislEjwP/C4an2303MCVS2Mg9d3AJpIGdUFIQQWbPds0Sw==",
-      "license": "MIT",
-      "dependencies": {
-        "@webassemblyjs/ast": "1.14.1",
-        "@webassemblyjs/helper-buffer": "1.14.1",
-        "@webassemblyjs/wasm-gen": "1.14.1",
-        "@webassemblyjs/wasm-parser": "1.14.1"
-      }
-    },
-    "node_modules/@webassemblyjs/wasm-parser": {
-      "version": "1.14.1",
-      "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.14.1.tgz",
-      "integrity": "sha512-JLBl+KZ0R5qB7mCnud/yyX08jWFw5MsoalJ1pQ4EdFlgj9VdXKGuENGsiCIjegI1W7p91rUlcB/LB5yRJKNTcQ==",
-      "license": "MIT",
-      "dependencies": {
-        "@webassemblyjs/ast": "1.14.1",
-        "@webassemblyjs/helper-api-error": "1.13.2",
-        "@webassemblyjs/helper-wasm-bytecode": "1.13.2",
-        "@webassemblyjs/ieee754": "1.13.2",
-        "@webassemblyjs/leb128": "1.13.2",
-        "@webassemblyjs/utf8": "1.13.2"
-      }
-    },
-    "node_modules/@webassemblyjs/wast-printer": {
-      "version": "1.14.1",
-      "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.14.1.tgz",
-      "integrity": "sha512-kPSSXE6De1XOR820C90RIo2ogvZG+c3KiHzqUoO/F34Y2shGzesfqv7o57xrxovZJH/MetF5UjroJ/R/3isoiw==",
-      "license": "MIT",
-      "dependencies": {
-        "@webassemblyjs/ast": "1.14.1",
-        "@xtuc/long": "4.2.2"
-      }
-    },
-    "node_modules/@xtuc/ieee754": {
-      "version": "1.2.0",
-      "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz",
-      "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==",
-      "license": "BSD-3-Clause"
-    },
-    "node_modules/@xtuc/long": {
-      "version": "4.2.2",
-      "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz",
-      "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==",
-      "license": "Apache-2.0"
-    },
-    "node_modules/abbrev": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-2.0.0.tgz",
-      "integrity": "sha512-6/mh1E2u2YgEsCHdY0Yx5oW+61gZU+1vXaoiHHrpKeuRNNgFvS+/jrwHiQhB5apAf5oB7UB7E19ol2R2LKH8hQ==",
-      "dev": true,
-      "license": "ISC",
-      "engines": {
-        "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
-      }
-    },
-    "node_modules/acorn": {
-      "version": "8.14.0",
-      "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz",
-      "integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==",
-      "license": "MIT",
-      "peer": true,
-      "bin": {
-        "acorn": "bin/acorn"
-      },
-      "engines": {
-        "node": ">=0.4.0"
-      }
-    },
-    "node_modules/acorn-jsx": {
-      "version": "5.3.2",
-      "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz",
-      "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==",
-      "dev": true,
-      "license": "MIT",
-      "peerDependencies": {
-        "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0"
-      }
-    },
-    "node_modules/agent-base": {
-      "version": "7.1.3",
-      "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.3.tgz",
-      "integrity": "sha512-jRR5wdylq8CkOe6hei19GGZnxM6rBGwFl3Bg0YItGDimvjGtAvdZk4Pu6Cl4u4Igsws4a1fd1Vq3ezrhn4KmFw==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">= 14"
-      }
-    },
-    "node_modules/ajv": {
-      "version": "6.12.6",
-      "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
-      "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "fast-deep-equal": "^3.1.1",
-        "fast-json-stable-stringify": "^2.0.0",
-        "json-schema-traverse": "^0.4.1",
-        "uri-js": "^4.2.2"
-      },
-      "funding": {
-        "type": "github",
-        "url": "https://github.com/sponsors/epoberezkin"
-      }
-    },
-    "node_modules/ajv-formats": {
-      "version": "2.1.1",
-      "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz",
-      "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==",
-      "license": "MIT",
-      "dependencies": {
-        "ajv": "^8.0.0"
-      },
-      "peerDependencies": {
-        "ajv": "^8.0.0"
-      },
-      "peerDependenciesMeta": {
-        "ajv": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/ajv-formats/node_modules/ajv": {
-      "version": "8.17.1",
-      "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz",
-      "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==",
-      "license": "MIT",
-      "dependencies": {
-        "fast-deep-equal": "^3.1.3",
-        "fast-uri": "^3.0.1",
-        "json-schema-traverse": "^1.0.0",
-        "require-from-string": "^2.0.2"
-      },
-      "funding": {
-        "type": "github",
-        "url": "https://github.com/sponsors/epoberezkin"
-      }
-    },
-    "node_modules/ajv-formats/node_modules/json-schema-traverse": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
-      "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
-      "license": "MIT"
-    },
-    "node_modules/ansi-regex": {
-      "version": "6.1.0",
-      "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz",
-      "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">=12"
-      },
-      "funding": {
-        "url": "https://github.com/chalk/ansi-regex?sponsor=1"
-      }
-    },
-    "node_modules/ansi-styles": {
-      "version": "4.3.0",
-      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
-      "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "color-convert": "^2.0.1"
-      },
-      "engines": {
-        "node": ">=8"
-      },
-      "funding": {
-        "url": "https://github.com/chalk/ansi-styles?sponsor=1"
-      }
-    },
-    "node_modules/argparse": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
-      "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
-      "dev": true,
-      "license": "Python-2.0"
-    },
-    "node_modules/assertion-error": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz",
-      "integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/asynckit": {
-      "version": "0.4.0",
-      "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
-      "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==",
-      "dev": true,
-      "license": "MIT"
-    },
-    "node_modules/balanced-match": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
-      "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
-      "dev": true,
-      "license": "MIT"
-    },
-    "node_modules/birpc": {
-      "version": "0.2.19",
-      "resolved": "https://registry.npmjs.org/birpc/-/birpc-0.2.19.tgz",
-      "integrity": "sha512-5WeXXAvTmitV1RqJFppT5QtUiz2p1mRSYU000Jkft5ZUCLJIk4uQriYNO50HknxKwM6jd8utNc66K1qGIwwWBQ==",
-      "dev": true,
-      "license": "MIT",
-      "funding": {
-        "url": "https://github.com/sponsors/antfu"
-      }
-    },
-    "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==",
-      "dev": true,
-      "license": "ISC"
-    },
-    "node_modules/bootstrap": {
-      "version": "5.3.8",
-      "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-5.3.8.tgz",
-      "integrity": "sha512-HP1SZDqaLDPwsNiqRqi5NcP0SSXciX2s9E+RyqJIIqGo+vJeN5AJVM98CXmW/Wux0nQ5L7jeWUdplCEf0Ee+tg==",
-      "funding": [
-        {
-          "type": "github",
-          "url": "https://github.com/sponsors/twbs"
-        },
-        {
-          "type": "opencollective",
-          "url": "https://opencollective.com/bootstrap"
-        }
-      ],
-      "license": "MIT",
-      "peerDependencies": {
-        "@popperjs/core": "^2.11.8"
-      }
-    },
-    "node_modules/brace-expansion": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
-      "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "balanced-match": "^1.0.0"
-      }
-    },
-    "node_modules/braces": {
-      "version": "3.0.3",
-      "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
-      "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
-      "license": "MIT",
-      "optional": true,
-      "dependencies": {
-        "fill-range": "^7.1.1"
-      },
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/browserslist": {
-      "version": "4.24.4",
-      "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.4.tgz",
-      "integrity": "sha512-KDi1Ny1gSePi1vm0q4oxSF8b4DR44GF4BbmS2YdhPLOEqd8pDviZOGH/GsmRwoWJ2+5Lr085X7naowMwKHDG1A==",
-      "funding": [
-        {
-          "type": "opencollective",
-          "url": "https://opencollective.com/browserslist"
-        },
-        {
-          "type": "tidelift",
-          "url": "https://tidelift.com/funding/github/npm/browserslist"
-        },
-        {
-          "type": "github",
-          "url": "https://github.com/sponsors/ai"
-        }
-      ],
-      "license": "MIT",
-      "peer": true,
-      "dependencies": {
-        "caniuse-lite": "^1.0.30001688",
-        "electron-to-chromium": "^1.5.73",
-        "node-releases": "^2.0.19",
-        "update-browserslist-db": "^1.1.1"
-      },
-      "bin": {
-        "browserslist": "cli.js"
-      },
-      "engines": {
-        "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7"
-      }
-    },
-    "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/bundle-name": {
-      "version": "4.1.0",
-      "resolved": "https://registry.npmjs.org/bundle-name/-/bundle-name-4.1.0.tgz",
-      "integrity": "sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "run-applescript": "^7.0.0"
-      },
-      "engines": {
-        "node": ">=18"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/cac": {
-      "version": "6.7.14",
-      "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz",
-      "integrity": "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/callsites": {
-      "version": "3.1.0",
-      "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
-      "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/caniuse-lite": {
-      "version": "1.0.30001695",
-      "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001695.tgz",
-      "integrity": "sha512-vHyLade6wTgI2u1ec3WQBxv+2BrTERV28UXQu9LO6lZ9pYeMk34vjXFLOxo1A4UBA8XTL4njRQZdno/yYaSmWw==",
-      "funding": [
-        {
-          "type": "opencollective",
-          "url": "https://opencollective.com/browserslist"
-        },
-        {
-          "type": "tidelift",
-          "url": "https://tidelift.com/funding/github/npm/caniuse-lite"
-        },
-        {
-          "type": "github",
-          "url": "https://github.com/sponsors/ai"
-        }
-      ],
-      "license": "CC-BY-4.0"
-    },
-    "node_modules/chai": {
-      "version": "5.1.2",
-      "resolved": "https://registry.npmjs.org/chai/-/chai-5.1.2.tgz",
-      "integrity": "sha512-aGtmf24DW6MLHHG5gCx4zaI3uBq3KRtxeVs0DjFH6Z0rDNbsvTxFASFvdj79pxjxZ8/5u3PIiN3IwEIQkiiuPw==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "assertion-error": "^2.0.1",
-        "check-error": "^2.1.1",
-        "deep-eql": "^5.0.1",
-        "loupe": "^3.1.0",
-        "pathval": "^2.0.0"
-      },
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/chalk": {
-      "version": "4.1.2",
-      "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
-      "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "ansi-styles": "^4.1.0",
-        "supports-color": "^7.1.0"
-      },
-      "engines": {
-        "node": ">=10"
-      },
-      "funding": {
-        "url": "https://github.com/chalk/chalk?sponsor=1"
-      }
-    },
-    "node_modules/check-error": {
-      "version": "2.1.1",
-      "resolved": "https://registry.npmjs.org/check-error/-/check-error-2.1.1.tgz",
-      "integrity": "sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">= 16"
-      }
-    },
-    "node_modules/chokidar": {
-      "version": "4.0.3",
-      "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz",
-      "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==",
-      "license": "MIT",
-      "dependencies": {
-        "readdirp": "^4.0.1"
-      },
-      "engines": {
-        "node": ">= 14.16.0"
-      },
-      "funding": {
-        "url": "https://paulmillr.com/funding/"
-      }
-    },
-    "node_modules/chrome-trace-event": {
-      "version": "1.0.4",
-      "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.4.tgz",
-      "integrity": "sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==",
-      "license": "MIT",
-      "engines": {
-        "node": ">=6.0"
-      }
-    },
-    "node_modules/color-convert": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
-      "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "color-name": "~1.1.4"
-      },
-      "engines": {
-        "node": ">=7.0.0"
-      }
-    },
-    "node_modules/color-name": {
-      "version": "1.1.4",
-      "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
-      "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
-      "dev": true,
-      "license": "MIT"
-    },
-    "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==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "delayed-stream": "~1.0.0"
-      },
-      "engines": {
-        "node": ">= 0.8"
-      }
-    },
-    "node_modules/commander": {
-      "version": "10.0.1",
-      "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz",
-      "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">=14"
-      }
-    },
-    "node_modules/concat-map": {
-      "version": "0.0.1",
-      "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
-      "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
-      "dev": true,
-      "license": "MIT"
-    },
-    "node_modules/config-chain": {
-      "version": "1.1.13",
-      "resolved": "https://registry.npmjs.org/config-chain/-/config-chain-1.1.13.tgz",
-      "integrity": "sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "ini": "^1.3.4",
-        "proto-list": "~1.2.1"
-      }
-    },
-    "node_modules/convert-source-map": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz",
-      "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==",
-      "dev": true,
-      "license": "MIT"
-    },
-    "node_modules/copy-anything": {
-      "version": "3.0.5",
-      "resolved": "https://registry.npmjs.org/copy-anything/-/copy-anything-3.0.5.tgz",
-      "integrity": "sha512-yCEafptTtb4bk7GLEQoM8KVJpxAfdBJYaXyzQEgQQQgYrZiDp8SJmGKlYza6CYjEDNstAdNdKA3UuoULlEbS6w==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "is-what": "^4.1.8"
-      },
-      "engines": {
-        "node": ">=12.13"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/mesqueeb"
-      }
-    },
-    "node_modules/cross-spawn": {
-      "version": "7.0.6",
-      "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
-      "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "path-key": "^3.1.0",
-        "shebang-command": "^2.0.0",
-        "which": "^2.0.1"
-      },
-      "engines": {
-        "node": ">= 8"
-      }
-    },
-    "node_modules/cssesc": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz",
-      "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==",
-      "dev": true,
-      "license": "MIT",
-      "bin": {
-        "cssesc": "bin/cssesc"
-      },
-      "engines": {
-        "node": ">=4"
-      }
-    },
-    "node_modules/cssstyle": {
-      "version": "4.2.1",
-      "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-4.2.1.tgz",
-      "integrity": "sha512-9+vem03dMXG7gDmZ62uqmRiMRNtinIZ9ZyuF6BdxzfOD+FdN5hretzynkn0ReS2DO2GSw76RWHs0UmJPI2zUjw==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "@asamuzakjp/css-color": "^2.8.2",
-        "rrweb-cssom": "^0.8.0"
-      },
-      "engines": {
-        "node": ">=18"
-      }
-    },
-    "node_modules/csstype": {
-      "version": "3.1.3",
-      "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz",
-      "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==",
-      "license": "MIT"
-    },
-    "node_modules/data-urls": {
-      "version": "5.0.0",
-      "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-5.0.0.tgz",
-      "integrity": "sha512-ZYP5VBHshaDAiVZxjbRVcFJpc+4xGgT0bK3vzy1HLN8jTO975HEbuYzZJcHoQEY5K1a0z8YayJkyVETa08eNTg==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "whatwg-mimetype": "^4.0.0",
-        "whatwg-url": "^14.0.0"
-      },
-      "engines": {
-        "node": ">=18"
-      }
-    },
-    "node_modules/debug": {
-      "version": "4.4.3",
-      "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz",
-      "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "ms": "^2.1.3"
-      },
-      "engines": {
-        "node": ">=6.0"
-      },
-      "peerDependenciesMeta": {
-        "supports-color": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/decimal.js": {
-      "version": "10.4.3",
-      "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.4.3.tgz",
-      "integrity": "sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA==",
-      "dev": true,
-      "license": "MIT"
-    },
-    "node_modules/deep-eql": {
-      "version": "5.0.2",
-      "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-5.0.2.tgz",
-      "integrity": "sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/deep-is": {
-      "version": "0.1.4",
-      "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz",
-      "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==",
-      "dev": true,
-      "license": "MIT"
-    },
-    "node_modules/default-browser": {
-      "version": "5.2.1",
-      "resolved": "https://registry.npmjs.org/default-browser/-/default-browser-5.2.1.tgz",
-      "integrity": "sha512-WY/3TUME0x3KPYdRRxEJJvXRHV4PyPoUsxtZa78lwItwRQRHhd2U9xOscaT/YTf8uCXIAjeJOFBVEh/7FtD8Xg==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "bundle-name": "^4.1.0",
-        "default-browser-id": "^5.0.0"
-      },
-      "engines": {
-        "node": ">=18"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/default-browser-id": {
-      "version": "5.0.0",
-      "resolved": "https://registry.npmjs.org/default-browser-id/-/default-browser-id-5.0.0.tgz",
-      "integrity": "sha512-A6p/pu/6fyBcA1TRz/GqWYPViplrftcW2gZC9q79ngNCKAeR/X3gcEdXQHl4KNXV+3wgIJ1CPkJQ3IHM6lcsyA==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">=18"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/define-lazy-prop": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz",
-      "integrity": "sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">=12"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/delayed-stream": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
-      "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">=0.4.0"
-      }
-    },
-    "node_modules/detect-libc": {
-      "version": "1.0.3",
-      "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz",
-      "integrity": "sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==",
-      "license": "Apache-2.0",
-      "optional": true,
-      "bin": {
-        "detect-libc": "bin/detect-libc.js"
-      },
-      "engines": {
-        "node": ">=0.10"
-      }
-    },
-    "node_modules/eastasianwidth": {
-      "version": "0.2.0",
-      "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz",
-      "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==",
-      "dev": true,
-      "license": "MIT"
-    },
-    "node_modules/editorconfig": {
-      "version": "1.0.4",
-      "resolved": "https://registry.npmjs.org/editorconfig/-/editorconfig-1.0.4.tgz",
-      "integrity": "sha512-L9Qe08KWTlqYMVvMcTIvMAdl1cDUubzRNYL+WfA4bLDMHe4nemKkpmYzkznE1FwLKu0EEmy6obgQKzMJrg4x9Q==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "@one-ini/wasm": "0.1.1",
-        "commander": "^10.0.0",
-        "minimatch": "9.0.1",
-        "semver": "^7.5.3"
-      },
-      "bin": {
-        "editorconfig": "bin/editorconfig"
-      },
-      "engines": {
-        "node": ">=14"
-      }
-    },
-    "node_modules/editorconfig/node_modules/minimatch": {
-      "version": "9.0.1",
-      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.1.tgz",
-      "integrity": "sha512-0jWhJpD/MdhPXwPuiRkCbfYfSKp2qnn2eOc279qI7f+osl/l+prKSrvhg157zSYvx/1nmgn2NqdT6k2Z7zSH9w==",
-      "dev": true,
-      "license": "ISC",
-      "dependencies": {
-        "brace-expansion": "^2.0.1"
-      },
-      "engines": {
-        "node": ">=16 || 14 >=14.17"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/isaacs"
-      }
-    },
-    "node_modules/electron-to-chromium": {
-      "version": "1.5.84",
-      "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.84.tgz",
-      "integrity": "sha512-I+DQ8xgafao9Ha6y0qjHHvpZ9OfyA1qKlkHkjywxzniORU2awxyz7f/iVJcULmrF2yrM3nHQf+iDjJtbbexd/g==",
-      "license": "ISC"
-    },
-    "node_modules/emoji-regex": {
-      "version": "9.2.2",
-      "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz",
-      "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==",
-      "dev": true,
-      "license": "MIT"
-    },
-    "node_modules/enhanced-resolve": {
-      "version": "5.18.1",
-      "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.1.tgz",
-      "integrity": "sha512-ZSW3ma5GkcQBIpwZTSRAI8N71Uuwgs93IezB7mf7R60tC8ZbJideoDNKjHn2O9KIlx6rkGTTEk1xUCK2E1Y2Yg==",
-      "license": "MIT",
-      "dependencies": {
-        "graceful-fs": "^4.2.4",
-        "tapable": "^2.2.0"
-      },
-      "engines": {
-        "node": ">=10.13.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/error-stack-parser-es": {
-      "version": "0.1.5",
-      "resolved": "https://registry.npmjs.org/error-stack-parser-es/-/error-stack-parser-es-0.1.5.tgz",
-      "integrity": "sha512-xHku1X40RO+fO8yJ8Wh2f2rZWVjqyhb1zgq1yZ8aZRQkv6OOKhKWRUaht3eSCUbAOBaKIgM+ykwFLE+QUxgGeg==",
-      "dev": true,
-      "license": "MIT",
-      "funding": {
-        "url": "https://github.com/sponsors/antfu"
-      }
-    },
-    "node_modules/es-module-lexer": {
-      "version": "1.6.0",
-      "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.6.0.tgz",
-      "integrity": "sha512-qqnD1yMU6tk/jnaMosogGySTZP8YtUgAffA9nMN+E/rjxcfRQ6IEk7IiozUjgxKoFHBGjTLnrHB/YC45r/59EQ==",
-      "license": "MIT"
-    },
-    "node_modules/esbuild": {
-      "version": "0.24.2",
-      "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.24.2.tgz",
-      "integrity": "sha512-+9egpBW8I3CD5XPe0n6BfT5fxLzxrlDzqydF3aviG+9ni1lDC/OvMHcxqEFV0+LANZG5R1bFMWfUrjVsdwxJvA==",
-      "dev": true,
-      "hasInstallScript": true,
-      "license": "MIT",
-      "bin": {
-        "esbuild": "bin/esbuild"
-      },
-      "engines": {
-        "node": ">=18"
-      },
-      "optionalDependencies": {
-        "@esbuild/aix-ppc64": "0.24.2",
-        "@esbuild/android-arm": "0.24.2",
-        "@esbuild/android-arm64": "0.24.2",
-        "@esbuild/android-x64": "0.24.2",
-        "@esbuild/darwin-arm64": "0.24.2",
-        "@esbuild/darwin-x64": "0.24.2",
-        "@esbuild/freebsd-arm64": "0.24.2",
-        "@esbuild/freebsd-x64": "0.24.2",
-        "@esbuild/linux-arm": "0.24.2",
-        "@esbuild/linux-arm64": "0.24.2",
-        "@esbuild/linux-ia32": "0.24.2",
-        "@esbuild/linux-loong64": "0.24.2",
-        "@esbuild/linux-mips64el": "0.24.2",
-        "@esbuild/linux-ppc64": "0.24.2",
-        "@esbuild/linux-riscv64": "0.24.2",
-        "@esbuild/linux-s390x": "0.24.2",
-        "@esbuild/linux-x64": "0.24.2",
-        "@esbuild/netbsd-arm64": "0.24.2",
-        "@esbuild/netbsd-x64": "0.24.2",
-        "@esbuild/openbsd-arm64": "0.24.2",
-        "@esbuild/openbsd-x64": "0.24.2",
-        "@esbuild/sunos-x64": "0.24.2",
-        "@esbuild/win32-arm64": "0.24.2",
-        "@esbuild/win32-ia32": "0.24.2",
-        "@esbuild/win32-x64": "0.24.2"
-      }
-    },
-    "node_modules/escalade": {
-      "version": "3.2.0",
-      "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz",
-      "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==",
-      "license": "MIT",
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/escape-string-regexp": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
-      "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">=10"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/eslint": {
-      "version": "9.18.0",
-      "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.18.0.tgz",
-      "integrity": "sha512-+waTfRWQlSbpt3KWE+CjrPPYnbq9kfZIYUqapc0uBXyjTp8aYXZDsUH16m39Ryq3NjAVP4tjuF7KaukeqoCoaA==",
-      "dev": true,
-      "license": "MIT",
-      "peer": true,
-      "dependencies": {
-        "@eslint-community/eslint-utils": "^4.2.0",
-        "@eslint-community/regexpp": "^4.12.1",
-        "@eslint/config-array": "^0.19.0",
-        "@eslint/core": "^0.10.0",
-        "@eslint/eslintrc": "^3.2.0",
-        "@eslint/js": "9.18.0",
-        "@eslint/plugin-kit": "^0.2.5",
-        "@humanfs/node": "^0.16.6",
-        "@humanwhocodes/module-importer": "^1.0.1",
-        "@humanwhocodes/retry": "^0.4.1",
-        "@types/estree": "^1.0.6",
-        "@types/json-schema": "^7.0.15",
-        "ajv": "^6.12.4",
-        "chalk": "^4.0.0",
-        "cross-spawn": "^7.0.6",
-        "debug": "^4.3.2",
-        "escape-string-regexp": "^4.0.0",
-        "eslint-scope": "^8.2.0",
-        "eslint-visitor-keys": "^4.2.0",
-        "espree": "^10.3.0",
-        "esquery": "^1.5.0",
-        "esutils": "^2.0.2",
-        "fast-deep-equal": "^3.1.3",
-        "file-entry-cache": "^8.0.0",
-        "find-up": "^5.0.0",
-        "glob-parent": "^6.0.2",
-        "ignore": "^5.2.0",
-        "imurmurhash": "^0.1.4",
-        "is-glob": "^4.0.0",
-        "json-stable-stringify-without-jsonify": "^1.0.1",
-        "lodash.merge": "^4.6.2",
-        "minimatch": "^3.1.2",
-        "natural-compare": "^1.4.0",
-        "optionator": "^0.9.3"
-      },
-      "bin": {
-        "eslint": "bin/eslint.js"
-      },
-      "engines": {
-        "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
-      },
-      "funding": {
-        "url": "https://eslint.org/donate"
-      },
-      "peerDependencies": {
-        "jiti": "*"
-      },
-      "peerDependenciesMeta": {
-        "jiti": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/eslint-config-prettier": {
-      "version": "10.0.1",
-      "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-10.0.1.tgz",
-      "integrity": "sha512-lZBts941cyJyeaooiKxAtzoPHTN+GbQTJFAIdQbRhA4/8whaAraEh47Whw/ZFfrjNSnlAxqfm9i0XVAEkULjCw==",
-      "dev": true,
-      "license": "MIT",
-      "peer": true,
-      "bin": {
-        "eslint-config-prettier": "build/bin/cli.js"
-      },
-      "peerDependencies": {
-        "eslint": ">=7.0.0"
-      }
-    },
-    "node_modules/eslint-plugin-prettier": {
-      "version": "5.2.3",
-      "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-5.2.3.tgz",
-      "integrity": "sha512-qJ+y0FfCp/mQYQ/vWQ3s7eUlFEL4PyKfAJxsnYTJ4YT73nsJBWqmEpFryxV9OeUiqmsTsYJ5Y+KDNaeP31wrRw==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "prettier-linter-helpers": "^1.0.0",
-        "synckit": "^0.9.1"
-      },
-      "engines": {
-        "node": "^14.18.0 || >=16.0.0"
-      },
-      "funding": {
-        "url": "https://opencollective.com/eslint-plugin-prettier"
-      },
-      "peerDependencies": {
-        "@types/eslint": ">=8.0.0",
-        "eslint": ">=8.0.0",
-        "eslint-config-prettier": "*",
-        "prettier": ">=3.0.0"
-      },
-      "peerDependenciesMeta": {
-        "@types/eslint": {
-          "optional": true
-        },
-        "eslint-config-prettier": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/eslint-plugin-vue": {
-      "version": "9.32.0",
-      "resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-9.32.0.tgz",
-      "integrity": "sha512-b/Y05HYmnB/32wqVcjxjHZzNpwxj1onBOvqW89W+V+XNG1dRuaFbNd3vT9CLbr2LXjEoq+3vn8DanWf7XU22Ug==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "@eslint-community/eslint-utils": "^4.4.0",
-        "globals": "^13.24.0",
-        "natural-compare": "^1.4.0",
-        "nth-check": "^2.1.1",
-        "postcss-selector-parser": "^6.0.15",
-        "semver": "^7.6.3",
-        "vue-eslint-parser": "^9.4.3",
-        "xml-name-validator": "^4.0.0"
-      },
-      "engines": {
-        "node": "^14.17.0 || >=16.0.0"
-      },
-      "peerDependencies": {
-        "eslint": "^6.2.0 || ^7.0.0 || ^8.0.0 || ^9.0.0"
-      }
-    },
-    "node_modules/eslint-plugin-vue/node_modules/globals": {
-      "version": "13.24.0",
-      "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz",
-      "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "type-fest": "^0.20.2"
-      },
-      "engines": {
-        "node": ">=8"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/eslint-scope": {
-      "version": "8.2.0",
-      "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.2.0.tgz",
-      "integrity": "sha512-PHlWUfG6lvPc3yvP5A4PNyBL1W8fkDUccmI21JUu/+GKZBoH/W5u6usENXUrWFRsyoW5ACUjFGgAFQp5gUlb/A==",
-      "dev": true,
-      "license": "BSD-2-Clause",
-      "dependencies": {
-        "esrecurse": "^4.3.0",
-        "estraverse": "^5.2.0"
-      },
-      "engines": {
-        "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
-      },
-      "funding": {
-        "url": "https://opencollective.com/eslint"
-      }
-    },
-    "node_modules/eslint-visitor-keys": {
-      "version": "3.4.3",
-      "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz",
-      "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==",
-      "dev": true,
-      "license": "Apache-2.0",
-      "engines": {
-        "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
-      },
-      "funding": {
-        "url": "https://opencollective.com/eslint"
-      }
-    },
-    "node_modules/eslint/node_modules/brace-expansion": {
-      "version": "1.1.11",
-      "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
-      "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "balanced-match": "^1.0.0",
-        "concat-map": "0.0.1"
-      }
-    },
-    "node_modules/eslint/node_modules/eslint-visitor-keys": {
-      "version": "4.2.0",
-      "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz",
-      "integrity": "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==",
-      "dev": true,
-      "license": "Apache-2.0",
-      "engines": {
-        "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
-      },
-      "funding": {
-        "url": "https://opencollective.com/eslint"
-      }
-    },
-    "node_modules/eslint/node_modules/minimatch": {
-      "version": "3.1.2",
-      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
-      "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
-      "dev": true,
-      "license": "ISC",
-      "dependencies": {
-        "brace-expansion": "^1.1.7"
-      },
-      "engines": {
-        "node": "*"
-      }
-    },
-    "node_modules/espree": {
-      "version": "10.3.0",
-      "resolved": "https://registry.npmjs.org/espree/-/espree-10.3.0.tgz",
-      "integrity": "sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg==",
-      "dev": true,
-      "license": "BSD-2-Clause",
-      "dependencies": {
-        "acorn": "^8.14.0",
-        "acorn-jsx": "^5.3.2",
-        "eslint-visitor-keys": "^4.2.0"
-      },
-      "engines": {
-        "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
-      },
-      "funding": {
-        "url": "https://opencollective.com/eslint"
-      }
-    },
-    "node_modules/espree/node_modules/eslint-visitor-keys": {
-      "version": "4.2.0",
-      "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz",
-      "integrity": "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==",
-      "dev": true,
-      "license": "Apache-2.0",
-      "engines": {
-        "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
-      },
-      "funding": {
-        "url": "https://opencollective.com/eslint"
-      }
-    },
-    "node_modules/esquery": {
-      "version": "1.6.0",
-      "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz",
-      "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==",
-      "dev": true,
-      "license": "BSD-3-Clause",
-      "dependencies": {
-        "estraverse": "^5.1.0"
-      },
-      "engines": {
-        "node": ">=0.10"
-      }
-    },
-    "node_modules/esrecurse": {
-      "version": "4.3.0",
-      "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz",
-      "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==",
-      "license": "BSD-2-Clause",
-      "dependencies": {
-        "estraverse": "^5.2.0"
-      },
-      "engines": {
-        "node": ">=4.0"
-      }
-    },
-    "node_modules/estraverse": {
-      "version": "5.3.0",
-      "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
-      "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
-      "license": "BSD-2-Clause",
-      "engines": {
-        "node": ">=4.0"
-      }
-    },
-    "node_modules/estree-walker": {
-      "version": "2.0.2",
-      "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz",
-      "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==",
-      "license": "MIT"
-    },
-    "node_modules/esutils": {
-      "version": "2.0.3",
-      "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
-      "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==",
-      "dev": true,
-      "license": "BSD-2-Clause",
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "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",
-      "engines": {
-        "node": ">=0.8.x"
-      }
-    },
-    "node_modules/execa": {
-      "version": "9.5.2",
-      "resolved": "https://registry.npmjs.org/execa/-/execa-9.5.2.tgz",
-      "integrity": "sha512-EHlpxMCpHWSAh1dgS6bVeoLAXGnJNdR93aabr4QCGbzOM73o5XmRfM/e5FUqsw3aagP8S8XEWUWFAxnRBnAF0Q==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "@sindresorhus/merge-streams": "^4.0.0",
-        "cross-spawn": "^7.0.3",
-        "figures": "^6.1.0",
-        "get-stream": "^9.0.0",
-        "human-signals": "^8.0.0",
-        "is-plain-obj": "^4.1.0",
-        "is-stream": "^4.0.1",
-        "npm-run-path": "^6.0.0",
-        "pretty-ms": "^9.0.0",
-        "signal-exit": "^4.1.0",
-        "strip-final-newline": "^4.0.0",
-        "yoctocolors": "^2.0.0"
-      },
-      "engines": {
-        "node": "^18.19.0 || >=20.5.0"
-      },
-      "funding": {
-        "url": "https://github.com/sindresorhus/execa?sponsor=1"
-      }
-    },
-    "node_modules/expect-type": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.1.0.tgz",
-      "integrity": "sha512-bFi65yM+xZgk+u/KRIpekdSYkTB5W1pEf0Lt8Q8Msh7b+eQ7LXVtIB1Bkm4fvclDEL1b2CZkMhv2mOeF8tMdkA==",
-      "dev": true,
-      "license": "Apache-2.0",
-      "engines": {
-        "node": ">=12.0.0"
-      }
-    },
-    "node_modules/fast-deep-equal": {
-      "version": "3.1.3",
-      "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
-      "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
-      "license": "MIT"
-    },
-    "node_modules/fast-diff": {
-      "version": "1.3.0",
-      "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.3.0.tgz",
-      "integrity": "sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==",
-      "dev": true,
-      "license": "Apache-2.0"
-    },
-    "node_modules/fast-json-stable-stringify": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
-      "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==",
-      "dev": true,
-      "license": "MIT"
-    },
-    "node_modules/fast-levenshtein": {
-      "version": "2.0.6",
-      "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
-      "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==",
-      "dev": true,
-      "license": "MIT"
-    },
-    "node_modules/fast-uri": {
-      "version": "3.0.6",
-      "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.6.tgz",
-      "integrity": "sha512-Atfo14OibSv5wAp4VWNsFYE1AchQRTv9cBGWET4pZWHzYshFSS9NQI6I57rdKn9croWVMbYFbLhJ+yJvmZIIHw==",
-      "funding": [
-        {
-          "type": "github",
-          "url": "https://github.com/sponsors/fastify"
-        },
-        {
-          "type": "opencollective",
-          "url": "https://opencollective.com/fastify"
-        }
-      ],
-      "license": "BSD-3-Clause"
-    },
-    "node_modules/figures": {
-      "version": "6.1.0",
-      "resolved": "https://registry.npmjs.org/figures/-/figures-6.1.0.tgz",
-      "integrity": "sha512-d+l3qxjSesT4V7v2fh+QnmFnUWv9lSpjarhShNTgBOfA0ttejbQUAlHLitbjkoRiDulW0OPoQPYIGhIC8ohejg==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "is-unicode-supported": "^2.0.0"
-      },
-      "engines": {
-        "node": ">=18"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/file-entry-cache": {
-      "version": "8.0.0",
-      "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz",
-      "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "flat-cache": "^4.0.0"
-      },
-      "engines": {
-        "node": ">=16.0.0"
-      }
-    },
-    "node_modules/fill-range": {
-      "version": "7.1.1",
-      "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
-      "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
-      "license": "MIT",
-      "optional": true,
-      "dependencies": {
-        "to-regex-range": "^5.0.1"
-      },
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/find-up": {
-      "version": "5.0.0",
-      "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz",
-      "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "locate-path": "^6.0.0",
-        "path-exists": "^4.0.0"
-      },
-      "engines": {
-        "node": ">=10"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/flat-cache": {
-      "version": "4.0.1",
-      "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz",
-      "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "flatted": "^3.2.9",
-        "keyv": "^4.5.4"
-      },
-      "engines": {
-        "node": ">=16"
-      }
-    },
-    "node_modules/flatted": {
-      "version": "3.3.2",
-      "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.2.tgz",
-      "integrity": "sha512-AiwGJM8YcNOaobumgtng+6NHuOqC3A7MixFeDafM3X9cIUM+xUXoS5Vfgf+OihAYe20fxqNM9yPBXJzRtZ/4eA==",
-      "dev": true,
-      "license": "ISC"
-    },
-    "node_modules/foreground-child": {
-      "version": "3.3.0",
-      "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.0.tgz",
-      "integrity": "sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==",
-      "dev": true,
-      "license": "ISC",
-      "dependencies": {
-        "cross-spawn": "^7.0.0",
-        "signal-exit": "^4.0.1"
-      },
-      "engines": {
-        "node": ">=14"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/isaacs"
-      }
-    },
-    "node_modules/form-data": {
-      "version": "4.0.1",
-      "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.1.tgz",
-      "integrity": "sha512-tzN8e4TX8+kkxGPK8D5u0FNmjPUjw3lwC9lSLxxoB/+GtsJG91CO8bSWy73APlgAZzZbXEYZJuxjkHH2w+Ezhw==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "asynckit": "^0.4.0",
-        "combined-stream": "^1.0.8",
-        "mime-types": "^2.1.12"
-      },
-      "engines": {
-        "node": ">= 6"
-      }
-    },
-    "node_modules/fs-extra": {
-      "version": "11.3.0",
-      "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.0.tgz",
-      "integrity": "sha512-Z4XaCL6dUDHfP/jT25jJKMmtxvuwbkrD1vNSMFlo9lNLY2c5FHYSQgHPRZUjAB26TpDEoW9HCOgplrdbaPV/ew==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "graceful-fs": "^4.2.0",
-        "jsonfile": "^6.0.1",
-        "universalify": "^2.0.0"
-      },
-      "engines": {
-        "node": ">=14.14"
-      }
-    },
-    "node_modules/fsevents": {
-      "version": "2.3.3",
-      "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
-      "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
-      "dev": true,
-      "hasInstallScript": true,
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "darwin"
-      ],
-      "engines": {
-        "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
-      }
-    },
-    "node_modules/gensync": {
-      "version": "1.0.0-beta.2",
-      "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz",
-      "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">=6.9.0"
-      }
-    },
-    "node_modules/get-stream": {
-      "version": "9.0.1",
-      "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-9.0.1.tgz",
-      "integrity": "sha512-kVCxPF3vQM/N0B1PmoqVUqgHP+EeVjmZSQn+1oCRPxd2P21P2F19lIgbR3HBosbB1PUhOAoctJnfEn2GbN2eZA==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "@sec-ant/readable-stream": "^0.4.1",
-        "is-stream": "^4.0.1"
-      },
-      "engines": {
-        "node": ">=18"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/glob": {
-      "version": "10.4.5",
-      "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz",
-      "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==",
-      "dev": true,
-      "license": "ISC",
-      "dependencies": {
-        "foreground-child": "^3.1.0",
-        "jackspeak": "^3.1.2",
-        "minimatch": "^9.0.4",
-        "minipass": "^7.1.2",
-        "package-json-from-dist": "^1.0.0",
-        "path-scurry": "^1.11.1"
-      },
-      "bin": {
-        "glob": "dist/esm/bin.mjs"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/isaacs"
-      }
-    },
-    "node_modules/glob-parent": {
-      "version": "6.0.2",
-      "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz",
-      "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==",
-      "dev": true,
-      "license": "ISC",
-      "dependencies": {
-        "is-glob": "^4.0.3"
-      },
-      "engines": {
-        "node": ">=10.13.0"
-      }
-    },
-    "node_modules/glob-to-regexp": {
-      "version": "0.4.1",
-      "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz",
-      "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==",
-      "license": "BSD-2-Clause"
-    },
-    "node_modules/globals": {
-      "version": "14.0.0",
-      "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz",
-      "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">=18"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/graceful-fs": {
-      "version": "4.2.11",
-      "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
-      "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==",
-      "license": "ISC"
-    },
-    "node_modules/has-flag": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
-      "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
-      "license": "MIT",
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/hookable": {
-      "version": "5.5.3",
-      "resolved": "https://registry.npmjs.org/hookable/-/hookable-5.5.3.tgz",
-      "integrity": "sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ==",
-      "dev": true,
-      "license": "MIT"
-    },
-    "node_modules/html-encoding-sniffer": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-4.0.0.tgz",
-      "integrity": "sha512-Y22oTqIU4uuPgEemfz7NDJz6OeKf12Lsu+QC+s3BVpda64lTiMYCyGwg5ki4vFxkMwQdeZDl2adZoqUgdFuTgQ==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "whatwg-encoding": "^3.1.1"
-      },
-      "engines": {
-        "node": ">=18"
-      }
-    },
-    "node_modules/html-tags": {
-      "version": "3.3.1",
-      "resolved": "https://registry.npmjs.org/html-tags/-/html-tags-3.3.1.tgz",
-      "integrity": "sha512-ztqyC3kLto0e9WbNp0aeP+M3kTt+nbaIveGmUxAtZa+8iFgKLUOD4YKM5j+f3QD89bra7UeumolZHKuOXnTmeQ==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">=8"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/http-proxy-agent": {
-      "version": "7.0.2",
-      "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz",
-      "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "agent-base": "^7.1.0",
-        "debug": "^4.3.4"
-      },
-      "engines": {
-        "node": ">= 14"
-      }
-    },
-    "node_modules/https-proxy-agent": {
-      "version": "7.0.6",
-      "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz",
-      "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "agent-base": "^7.1.2",
-        "debug": "4"
-      },
-      "engines": {
-        "node": ">= 14"
-      }
-    },
-    "node_modules/human-signals": {
-      "version": "8.0.0",
-      "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-8.0.0.tgz",
-      "integrity": "sha512-/1/GPCpDUCCYwlERiYjxoczfP0zfvZMU/OWgQPMya9AbAE24vseigFdhAMObpc8Q4lc/kjutPfUddDYyAmejnA==",
-      "dev": true,
-      "license": "Apache-2.0",
-      "engines": {
-        "node": ">=18.18.0"
-      }
-    },
-    "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==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "safer-buffer": ">= 2.1.2 < 3.0.0"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/ignore": {
-      "version": "5.3.2",
-      "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz",
-      "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">= 4"
-      }
-    },
-    "node_modules/immutable": {
-      "version": "5.1.2",
-      "resolved": "https://registry.npmjs.org/immutable/-/immutable-5.1.2.tgz",
-      "integrity": "sha512-qHKXW1q6liAk1Oys6umoaZbDRqjcjgSrbnrifHsfsttza7zcvRAsL7mMV6xWcyhwQy7Xj5v4hhbr6b+iDYwlmQ==",
-      "license": "MIT"
-    },
-    "node_modules/import-fresh": {
-      "version": "3.3.0",
-      "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz",
-      "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "parent-module": "^1.0.0",
-        "resolve-from": "^4.0.0"
-      },
-      "engines": {
-        "node": ">=6"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/imurmurhash": {
-      "version": "0.1.4",
-      "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
-      "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">=0.8.19"
-      }
-    },
-    "node_modules/ini": {
-      "version": "1.3.8",
-      "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz",
-      "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==",
-      "dev": true,
-      "license": "ISC"
-    },
-    "node_modules/is-docker": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-3.0.0.tgz",
-      "integrity": "sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==",
-      "dev": true,
-      "license": "MIT",
-      "bin": {
-        "is-docker": "cli.js"
-      },
-      "engines": {
-        "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/is-extglob": {
-      "version": "2.1.1",
-      "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
-      "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
-      "devOptional": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/is-fullwidth-code-point": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
-      "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/is-glob": {
-      "version": "4.0.3",
-      "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
-      "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
-      "devOptional": true,
-      "license": "MIT",
-      "dependencies": {
-        "is-extglob": "^2.1.1"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/is-inside-container": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/is-inside-container/-/is-inside-container-1.0.0.tgz",
-      "integrity": "sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "is-docker": "^3.0.0"
-      },
-      "bin": {
-        "is-inside-container": "cli.js"
-      },
-      "engines": {
-        "node": ">=14.16"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/is-number": {
-      "version": "7.0.0",
-      "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
-      "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
-      "license": "MIT",
-      "optional": true,
-      "engines": {
-        "node": ">=0.12.0"
-      }
-    },
-    "node_modules/is-plain-obj": {
-      "version": "4.1.0",
-      "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz",
-      "integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">=12"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/is-potential-custom-element-name": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz",
-      "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==",
-      "dev": true,
-      "license": "MIT"
-    },
-    "node_modules/is-stream": {
-      "version": "4.0.1",
-      "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-4.0.1.tgz",
-      "integrity": "sha512-Dnz92NInDqYckGEUJv689RbRiTSEHCQ7wOVeALbkOz999YpqT46yMRIGtSNl2iCL1waAZSx40+h59NV/EwzV/A==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">=18"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/is-unicode-supported": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-2.1.0.tgz",
-      "integrity": "sha512-mE00Gnza5EEB3Ds0HfMyllZzbBrmLOX3vfWoj9A9PEnTfratQ/BcaJOuMhnkhjXvb2+FkY3VuHqtAGpTPmglFQ==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">=18"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/is-what": {
-      "version": "4.1.16",
-      "resolved": "https://registry.npmjs.org/is-what/-/is-what-4.1.16.tgz",
-      "integrity": "sha512-ZhMwEosbFJkA0YhFnNDgTM4ZxDRsS6HqTo7qsZM08fehyRYIYa0yHu5R6mgo1n/8MgaPBXiPimPD77baVFYg+A==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">=12.13"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/mesqueeb"
-      }
-    },
-    "node_modules/is-wsl": {
-      "version": "3.1.0",
-      "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-3.1.0.tgz",
-      "integrity": "sha512-UcVfVfaK4Sc4m7X3dUSoHoozQGBEFeDC+zVo06t98xe8CzHSZZBekNXH+tu0NalHolcJ/QAGqS46Hef7QXBIMw==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "is-inside-container": "^1.0.0"
-      },
-      "engines": {
-        "node": ">=16"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/isexe": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
-      "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
-      "dev": true,
-      "license": "ISC"
-    },
-    "node_modules/jackspeak": {
-      "version": "3.4.3",
-      "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz",
-      "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==",
-      "dev": true,
-      "license": "BlueOak-1.0.0",
-      "dependencies": {
-        "@isaacs/cliui": "^8.0.2"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/isaacs"
-      },
-      "optionalDependencies": {
-        "@pkgjs/parseargs": "^0.11.0"
-      }
-    },
-    "node_modules/jest-worker": {
-      "version": "27.5.1",
-      "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz",
-      "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==",
-      "license": "MIT",
-      "dependencies": {
-        "@types/node": "*",
-        "merge-stream": "^2.0.0",
-        "supports-color": "^8.0.0"
-      },
-      "engines": {
-        "node": ">= 10.13.0"
-      }
-    },
-    "node_modules/jest-worker/node_modules/supports-color": {
-      "version": "8.1.1",
-      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz",
-      "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==",
-      "license": "MIT",
-      "dependencies": {
-        "has-flag": "^4.0.0"
-      },
-      "engines": {
-        "node": ">=10"
-      },
-      "funding": {
-        "url": "https://github.com/chalk/supports-color?sponsor=1"
-      }
-    },
-    "node_modules/js-beautify": {
-      "version": "1.15.1",
-      "resolved": "https://registry.npmjs.org/js-beautify/-/js-beautify-1.15.1.tgz",
-      "integrity": "sha512-ESjNzSlt/sWE8sciZH8kBF8BPlwXPwhR6pWKAw8bw4Bwj+iZcnKW6ONWUutJ7eObuBZQpiIb8S7OYspWrKt7rA==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "config-chain": "^1.1.13",
-        "editorconfig": "^1.0.4",
-        "glob": "^10.3.3",
-        "js-cookie": "^3.0.5",
-        "nopt": "^7.2.0"
-      },
-      "bin": {
-        "css-beautify": "js/bin/css-beautify.js",
-        "html-beautify": "js/bin/html-beautify.js",
-        "js-beautify": "js/bin/js-beautify.js"
-      },
-      "engines": {
-        "node": ">=14"
-      }
-    },
-    "node_modules/js-cookie": {
-      "version": "3.0.5",
-      "resolved": "https://registry.npmjs.org/js-cookie/-/js-cookie-3.0.5.tgz",
-      "integrity": "sha512-cEiJEAEoIbWfCZYKWhVwFuvPX1gETRYPw6LlaTKoxD3s2AkXzkCjnp6h0V77ozyqj0jakteJ4YqDJT830+lVGw==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">=14"
-      }
-    },
-    "node_modules/js-tokens": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
-      "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
-      "dev": true,
-      "license": "MIT"
-    },
-    "node_modules/js-yaml": {
-      "version": "4.1.0",
-      "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
-      "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "argparse": "^2.0.1"
-      },
-      "bin": {
-        "js-yaml": "bin/js-yaml.js"
-      }
-    },
-    "node_modules/jsdom": {
-      "version": "26.0.0",
-      "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-26.0.0.tgz",
-      "integrity": "sha512-BZYDGVAIriBWTpIxYzrXjv3E/4u8+/pSG5bQdIYCbNCGOvsPkDQfTVLAIXAf9ETdCpduCVTkDe2NNZ8NIwUVzw==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "cssstyle": "^4.2.1",
-        "data-urls": "^5.0.0",
-        "decimal.js": "^10.4.3",
-        "form-data": "^4.0.1",
-        "html-encoding-sniffer": "^4.0.0",
-        "http-proxy-agent": "^7.0.2",
-        "https-proxy-agent": "^7.0.6",
-        "is-potential-custom-element-name": "^1.0.1",
-        "nwsapi": "^2.2.16",
-        "parse5": "^7.2.1",
-        "rrweb-cssom": "^0.8.0",
-        "saxes": "^6.0.0",
-        "symbol-tree": "^3.2.4",
-        "tough-cookie": "^5.0.0",
-        "w3c-xmlserializer": "^5.0.0",
-        "webidl-conversions": "^7.0.0",
-        "whatwg-encoding": "^3.1.1",
-        "whatwg-mimetype": "^4.0.0",
-        "whatwg-url": "^14.1.0",
-        "ws": "^8.18.0",
-        "xml-name-validator": "^5.0.0"
-      },
-      "engines": {
-        "node": ">=18"
-      },
-      "peerDependencies": {
-        "canvas": "^3.0.0"
-      },
-      "peerDependenciesMeta": {
-        "canvas": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/jsdom/node_modules/xml-name-validator": {
-      "version": "5.0.0",
-      "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-5.0.0.tgz",
-      "integrity": "sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg==",
-      "dev": true,
-      "license": "Apache-2.0",
-      "engines": {
-        "node": ">=18"
-      }
-    },
-    "node_modules/jsesc": {
-      "version": "3.1.0",
-      "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz",
-      "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==",
-      "dev": true,
-      "license": "MIT",
-      "bin": {
-        "jsesc": "bin/jsesc"
-      },
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/json-buffer": {
-      "version": "3.0.1",
-      "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz",
-      "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==",
-      "dev": true,
-      "license": "MIT"
-    },
-    "node_modules/json-parse-even-better-errors": {
-      "version": "2.3.1",
-      "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz",
-      "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==",
-      "license": "MIT"
-    },
-    "node_modules/json-schema-traverse": {
-      "version": "0.4.1",
-      "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
-      "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
-      "dev": true,
-      "license": "MIT"
-    },
-    "node_modules/json-stable-stringify-without-jsonify": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz",
-      "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==",
-      "dev": true,
-      "license": "MIT"
-    },
-    "node_modules/json5": {
-      "version": "2.2.3",
-      "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
-      "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",
-      "dev": true,
-      "license": "MIT",
-      "bin": {
-        "json5": "lib/cli.js"
-      },
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/jsonfile": {
-      "version": "6.1.0",
-      "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz",
-      "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "universalify": "^2.0.0"
-      },
-      "optionalDependencies": {
-        "graceful-fs": "^4.1.6"
-      }
-    },
-    "node_modules/keyv": {
-      "version": "4.5.4",
-      "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz",
-      "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "json-buffer": "3.0.1"
-      }
-    },
-    "node_modules/kolorist": {
-      "version": "1.8.0",
-      "resolved": "https://registry.npmjs.org/kolorist/-/kolorist-1.8.0.tgz",
-      "integrity": "sha512-Y+60/zizpJ3HRH8DCss+q95yr6145JXZo46OTpFvDZWLfRCE4qChOyk1b26nMaNpfHHgxagk9dXT5OP0Tfe+dQ==",
-      "dev": true,
-      "license": "MIT"
-    },
-    "node_modules/levn": {
-      "version": "0.4.1",
-      "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz",
-      "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "prelude-ls": "^1.2.1",
-        "type-check": "~0.4.0"
-      },
-      "engines": {
-        "node": ">= 0.8.0"
-      }
-    },
-    "node_modules/loader-runner": {
-      "version": "4.3.0",
-      "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz",
-      "integrity": "sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==",
-      "license": "MIT",
-      "engines": {
-        "node": ">=6.11.5"
-      }
-    },
-    "node_modules/locate-path": {
-      "version": "6.0.0",
-      "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
-      "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "p-locate": "^5.0.0"
-      },
-      "engines": {
-        "node": ">=10"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/lodash": {
-      "version": "4.17.21",
-      "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
-      "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
-      "dev": true,
-      "license": "MIT"
-    },
-    "node_modules/lodash.merge": {
-      "version": "4.6.2",
-      "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
-      "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==",
-      "dev": true,
-      "license": "MIT"
-    },
-    "node_modules/loupe": {
-      "version": "3.1.2",
-      "resolved": "https://registry.npmjs.org/loupe/-/loupe-3.1.2.tgz",
-      "integrity": "sha512-23I4pFZHmAemUnz8WZXbYRSKYj801VDaNv9ETuMh7IrMc7VuVVSo+Z9iLE3ni30+U48iDWfi30d3twAXBYmnCg==",
-      "dev": true,
-      "license": "MIT"
-    },
-    "node_modules/lru-cache": {
-      "version": "10.4.3",
-      "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz",
-      "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==",
-      "dev": true,
-      "license": "ISC"
-    },
-    "node_modules/magic-string": {
-      "version": "0.30.17",
-      "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.17.tgz",
-      "integrity": "sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==",
-      "license": "MIT",
-      "dependencies": {
-        "@jridgewell/sourcemap-codec": "^1.5.0"
-      }
-    },
-    "node_modules/merge-stream": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz",
-      "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==",
-      "license": "MIT"
-    },
-    "node_modules/micromatch": {
-      "version": "4.0.8",
-      "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz",
-      "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==",
-      "license": "MIT",
-      "optional": true,
-      "dependencies": {
-        "braces": "^3.0.3",
-        "picomatch": "^2.3.1"
-      },
-      "engines": {
-        "node": ">=8.6"
-      }
-    },
-    "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/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/minimatch": {
-      "version": "9.0.5",
-      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
-      "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
-      "dev": true,
-      "license": "ISC",
-      "dependencies": {
-        "brace-expansion": "^2.0.1"
-      },
-      "engines": {
-        "node": ">=16 || 14 >=14.17"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/isaacs"
-      }
-    },
-    "node_modules/minipass": {
-      "version": "7.1.2",
-      "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz",
-      "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==",
-      "dev": true,
-      "license": "ISC",
-      "engines": {
-        "node": ">=16 || 14 >=14.17"
-      }
-    },
-    "node_modules/mitt": {
-      "version": "3.0.1",
-      "resolved": "https://registry.npmjs.org/mitt/-/mitt-3.0.1.tgz",
-      "integrity": "sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==",
-      "dev": true,
-      "license": "MIT"
-    },
-    "node_modules/mrmime": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-2.0.0.tgz",
-      "integrity": "sha512-eu38+hdgojoyq63s+yTpN4XMBdt5l8HhMhc4VKLO9KM5caLIBvUm4thi7fFaxyTmCKeNnXZ5pAlBwCUnhA09uw==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">=10"
-      }
-    },
-    "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==",
-      "dev": true,
-      "license": "MIT"
-    },
-    "node_modules/nanoid": {
-      "version": "3.3.8",
-      "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.8.tgz",
-      "integrity": "sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==",
-      "funding": [
-        {
-          "type": "github",
-          "url": "https://github.com/sponsors/ai"
-        }
-      ],
-      "license": "MIT",
-      "bin": {
-        "nanoid": "bin/nanoid.cjs"
-      },
-      "engines": {
-        "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
-      }
-    },
-    "node_modules/natural-compare": {
-      "version": "1.4.0",
-      "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
-      "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==",
-      "dev": true,
-      "license": "MIT"
-    },
-    "node_modules/neo-async": {
-      "version": "2.6.2",
-      "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz",
-      "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==",
-      "license": "MIT"
-    },
-    "node_modules/node-addon-api": {
-      "version": "7.1.1",
-      "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-7.1.1.tgz",
-      "integrity": "sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==",
-      "license": "MIT",
-      "optional": true
-    },
-    "node_modules/node-releases": {
-      "version": "2.0.19",
-      "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz",
-      "integrity": "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==",
-      "license": "MIT"
-    },
-    "node_modules/nopt": {
-      "version": "7.2.1",
-      "resolved": "https://registry.npmjs.org/nopt/-/nopt-7.2.1.tgz",
-      "integrity": "sha512-taM24ViiimT/XntxbPyJQzCG+p4EKOpgD3mxFwW38mGjVUrfERQOeY4EDHjdnptttfHuHQXFx+lTP08Q+mLa/w==",
-      "dev": true,
-      "license": "ISC",
-      "dependencies": {
-        "abbrev": "^2.0.0"
-      },
-      "bin": {
-        "nopt": "bin/nopt.js"
-      },
-      "engines": {
-        "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
-      }
-    },
-    "node_modules/npm-run-path": {
-      "version": "6.0.0",
-      "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-6.0.0.tgz",
-      "integrity": "sha512-9qny7Z9DsQU8Ou39ERsPU4OZQlSTP47ShQzuKZ6PRXpYLtIFgl/DEBYEXKlvcEa+9tHVcK8CF81Y2V72qaZhWA==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "path-key": "^4.0.0",
-        "unicorn-magic": "^0.3.0"
-      },
-      "engines": {
-        "node": ">=18"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/npm-run-path/node_modules/path-key": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz",
-      "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">=12"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "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==",
-      "dev": true,
-      "license": "BSD-2-Clause",
-      "dependencies": {
-        "boolbase": "^1.0.0"
-      },
-      "funding": {
-        "url": "https://github.com/fb55/nth-check?sponsor=1"
-      }
-    },
-    "node_modules/nwsapi": {
-      "version": "2.2.16",
-      "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.16.tgz",
-      "integrity": "sha512-F1I/bimDpj3ncaNDhfyMWuFqmQDBwDB0Fogc2qpL3BWvkQteFD/8BzWuIRl83rq0DXfm8SGt/HFhLXZyljTXcQ==",
-      "dev": true,
-      "license": "MIT"
-    },
-    "node_modules/open": {
-      "version": "10.1.0",
-      "resolved": "https://registry.npmjs.org/open/-/open-10.1.0.tgz",
-      "integrity": "sha512-mnkeQ1qP5Ue2wd+aivTD3NHd/lZ96Lu0jgf0pwktLPtx6cTZiH7tyeGRRHs0zX0rbrahXPnXlUnbeXyaBBuIaw==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "default-browser": "^5.2.1",
-        "define-lazy-prop": "^3.0.0",
-        "is-inside-container": "^1.0.0",
-        "is-wsl": "^3.1.0"
-      },
-      "engines": {
-        "node": ">=18"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/optionator": {
-      "version": "0.9.4",
-      "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz",
-      "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "deep-is": "^0.1.3",
-        "fast-levenshtein": "^2.0.6",
-        "levn": "^0.4.1",
-        "prelude-ls": "^1.2.1",
-        "type-check": "^0.4.0",
-        "word-wrap": "^1.2.5"
-      },
-      "engines": {
-        "node": ">= 0.8.0"
-      }
-    },
-    "node_modules/p-limit": {
-      "version": "3.1.0",
-      "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
-      "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "yocto-queue": "^0.1.0"
-      },
-      "engines": {
-        "node": ">=10"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/p-locate": {
-      "version": "5.0.0",
-      "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz",
-      "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "p-limit": "^3.0.2"
-      },
-      "engines": {
-        "node": ">=10"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/package-json-from-dist": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz",
-      "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==",
-      "dev": true,
-      "license": "BlueOak-1.0.0"
-    },
-    "node_modules/parent-module": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
-      "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "callsites": "^3.0.0"
-      },
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/parse-ms": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/parse-ms/-/parse-ms-4.0.0.tgz",
-      "integrity": "sha512-TXfryirbmq34y8QBwgqCVLi+8oA3oWx2eAnSn62ITyEhEYaWRlVZ2DvMM9eZbMs/RfxPu/PK/aBLyGj4IrqMHw==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">=18"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/parse5": {
-      "version": "7.2.1",
-      "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.2.1.tgz",
-      "integrity": "sha512-BuBYQYlv1ckiPdQi/ohiivi9Sagc9JG+Ozs0r7b/0iK3sKmrb0b9FdWdBbOdx6hBCM/F9Ir82ofnBhtZOjCRPQ==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "entities": "^4.5.0"
-      },
-      "funding": {
-        "url": "https://github.com/inikulin/parse5?sponsor=1"
-      }
-    },
-    "node_modules/path-exists": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
-      "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/path-key": {
-      "version": "3.1.1",
-      "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
-      "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/path-scurry": {
-      "version": "1.11.1",
-      "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz",
-      "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==",
-      "dev": true,
-      "license": "BlueOak-1.0.0",
-      "dependencies": {
-        "lru-cache": "^10.2.0",
-        "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0"
-      },
-      "engines": {
-        "node": ">=16 || 14 >=14.18"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/isaacs"
-      }
-    },
-    "node_modules/pathe": {
-      "version": "1.1.2",
-      "resolved": "https://registry.npmjs.org/pathe/-/pathe-1.1.2.tgz",
-      "integrity": "sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==",
-      "dev": true,
-      "license": "MIT"
-    },
-    "node_modules/pathval": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/pathval/-/pathval-2.0.0.tgz",
-      "integrity": "sha512-vE7JKRyES09KiunauX7nd2Q9/L7lhok4smP9RZTDeD4MVs72Dp2qNFVz39Nz5a0FVEW0BJR6C0DYrq6unoziZA==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">= 14.16"
-      }
-    },
-    "node_modules/perfect-debounce": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/perfect-debounce/-/perfect-debounce-1.0.0.tgz",
-      "integrity": "sha512-xCy9V055GLEqoFaHoC1SoLIaLmWctgCUaBaWxDZ7/Zx4CTyX7cJQLJOok/orfjZAh9kEYpjJa4d0KcJmCbctZA==",
-      "dev": true,
-      "license": "MIT"
-    },
-    "node_modules/picocolors": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
-      "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==",
-      "license": "ISC"
-    },
-    "node_modules/picomatch": {
-      "version": "2.3.1",
-      "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
-      "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
-      "license": "MIT",
-      "optional": true,
-      "engines": {
-        "node": ">=8.6"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/jonschlinkert"
-      }
-    },
-    "node_modules/pinia": {
-      "version": "2.3.1",
-      "resolved": "https://registry.npmjs.org/pinia/-/pinia-2.3.1.tgz",
-      "integrity": "sha512-khUlZSwt9xXCaTbbxFYBKDc/bWAGWJjOgvxETwkTN7KRm66EeT1ZdZj6i2ceh9sP2Pzqsbc704r2yngBrxBVug==",
-      "license": "MIT",
-      "dependencies": {
-        "@vue/devtools-api": "^6.6.3",
-        "vue-demi": "^0.14.10"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/posva"
-      },
-      "peerDependencies": {
-        "typescript": ">=4.4.4",
-        "vue": "^2.7.0 || ^3.5.11"
-      },
-      "peerDependenciesMeta": {
-        "typescript": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/postcss": {
-      "version": "8.5.1",
-      "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.1.tgz",
-      "integrity": "sha512-6oz2beyjc5VMn/KV1pPw8fliQkhBXrVn1Z3TVyqZxU8kZpzEKhBdmCFqI6ZbmGtamQvQGuU1sgPTk8ZrXDD7jQ==",
-      "funding": [
-        {
-          "type": "opencollective",
-          "url": "https://opencollective.com/postcss/"
-        },
-        {
-          "type": "tidelift",
-          "url": "https://tidelift.com/funding/github/npm/postcss"
-        },
-        {
-          "type": "github",
-          "url": "https://github.com/sponsors/ai"
-        }
-      ],
-      "license": "MIT",
-      "dependencies": {
-        "nanoid": "^3.3.8",
-        "picocolors": "^1.1.1",
-        "source-map-js": "^1.2.1"
-      },
-      "engines": {
-        "node": "^10 || ^12 || >=14"
-      }
-    },
-    "node_modules/postcss-selector-parser": {
-      "version": "6.1.2",
-      "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz",
-      "integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "cssesc": "^3.0.0",
-        "util-deprecate": "^1.0.2"
-      },
-      "engines": {
-        "node": ">=4"
-      }
-    },
-    "node_modules/prelude-ls": {
-      "version": "1.2.1",
-      "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz",
-      "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">= 0.8.0"
-      }
-    },
-    "node_modules/prettier": {
-      "version": "3.4.2",
-      "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.4.2.tgz",
-      "integrity": "sha512-e9MewbtFo+Fevyuxn/4rrcDAaq0IYxPGLvObpQjiZBMAzB9IGmzlnG9RZy3FFas+eBMu2vA0CszMeduow5dIuQ==",
-      "dev": true,
-      "license": "MIT",
-      "peer": true,
-      "bin": {
-        "prettier": "bin/prettier.cjs"
-      },
-      "engines": {
-        "node": ">=14"
-      },
-      "funding": {
-        "url": "https://github.com/prettier/prettier?sponsor=1"
-      }
-    },
-    "node_modules/prettier-linter-helpers": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz",
-      "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "fast-diff": "^1.1.2"
-      },
-      "engines": {
-        "node": ">=6.0.0"
-      }
-    },
-    "node_modules/pretty-ms": {
-      "version": "9.2.0",
-      "resolved": "https://registry.npmjs.org/pretty-ms/-/pretty-ms-9.2.0.tgz",
-      "integrity": "sha512-4yf0QO/sllf/1zbZWYnvWw3NxCQwLXKzIj0G849LSufP15BXKM0rbD2Z3wVnkMfjdn/CB0Dpp444gYAACdsplg==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "parse-ms": "^4.0.0"
-      },
-      "engines": {
-        "node": ">=18"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/proto-list": {
-      "version": "1.2.4",
-      "resolved": "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz",
-      "integrity": "sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==",
-      "dev": true,
-      "license": "ISC"
-    },
-    "node_modules/punycode": {
-      "version": "2.3.1",
-      "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz",
-      "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/randombytes": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz",
-      "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==",
-      "license": "MIT",
-      "dependencies": {
-        "safe-buffer": "^5.1.0"
-      }
-    },
-    "node_modules/readdirp": {
-      "version": "4.1.2",
-      "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz",
-      "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==",
-      "license": "MIT",
-      "engines": {
-        "node": ">= 14.18.0"
-      },
-      "funding": {
-        "type": "individual",
-        "url": "https://paulmillr.com/funding/"
-      }
-    },
-    "node_modules/require-from-string": {
-      "version": "2.0.2",
-      "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz",
-      "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==",
-      "license": "MIT",
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/resolve-from": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
-      "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">=4"
-      }
-    },
-    "node_modules/rfdc": {
-      "version": "1.4.1",
-      "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.4.1.tgz",
-      "integrity": "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==",
-      "dev": true,
-      "license": "MIT"
-    },
-    "node_modules/rollup": {
-      "version": "4.31.0",
-      "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.31.0.tgz",
-      "integrity": "sha512-9cCE8P4rZLx9+PjoyqHLs31V9a9Vpvfo4qNcs6JCiGWYhw2gijSetFbH6SSy1whnkgcefnUwr8sad7tgqsGvnw==",
-      "dev": true,
-      "license": "MIT",
-      "peer": true,
-      "dependencies": {
-        "@types/estree": "1.0.6"
-      },
-      "bin": {
-        "rollup": "dist/bin/rollup"
-      },
-      "engines": {
-        "node": ">=18.0.0",
-        "npm": ">=8.0.0"
-      },
-      "optionalDependencies": {
-        "@rollup/rollup-android-arm-eabi": "4.31.0",
-        "@rollup/rollup-android-arm64": "4.31.0",
-        "@rollup/rollup-darwin-arm64": "4.31.0",
-        "@rollup/rollup-darwin-x64": "4.31.0",
-        "@rollup/rollup-freebsd-arm64": "4.31.0",
-        "@rollup/rollup-freebsd-x64": "4.31.0",
-        "@rollup/rollup-linux-arm-gnueabihf": "4.31.0",
-        "@rollup/rollup-linux-arm-musleabihf": "4.31.0",
-        "@rollup/rollup-linux-arm64-gnu": "4.31.0",
-        "@rollup/rollup-linux-arm64-musl": "4.31.0",
-        "@rollup/rollup-linux-loongarch64-gnu": "4.31.0",
-        "@rollup/rollup-linux-powerpc64le-gnu": "4.31.0",
-        "@rollup/rollup-linux-riscv64-gnu": "4.31.0",
-        "@rollup/rollup-linux-s390x-gnu": "4.31.0",
-        "@rollup/rollup-linux-x64-gnu": "4.31.0",
-        "@rollup/rollup-linux-x64-musl": "4.31.0",
-        "@rollup/rollup-win32-arm64-msvc": "4.31.0",
-        "@rollup/rollup-win32-ia32-msvc": "4.31.0",
-        "@rollup/rollup-win32-x64-msvc": "4.31.0",
-        "fsevents": "~2.3.2"
-      }
-    },
-    "node_modules/rrweb-cssom": {
-      "version": "0.8.0",
-      "resolved": "https://registry.npmjs.org/rrweb-cssom/-/rrweb-cssom-0.8.0.tgz",
-      "integrity": "sha512-guoltQEx+9aMf2gDZ0s62EcV8lsXR+0w8915TC3ITdn2YueuNjdAYh/levpU9nFaoChh9RUS5ZdQMrKfVEN9tw==",
-      "dev": true,
-      "license": "MIT"
-    },
-    "node_modules/run-applescript": {
-      "version": "7.0.0",
-      "resolved": "https://registry.npmjs.org/run-applescript/-/run-applescript-7.0.0.tgz",
-      "integrity": "sha512-9by4Ij99JUr/MCFBUkDKLWK3G9HVXmabKz9U5MlIAIuvuzkiOicRYs8XJLxX+xahD+mLiiCYDqF9dKAgtzKP1A==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">=18"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "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==",
-      "dev": true,
-      "license": "MIT"
-    },
-    "node_modules/sass": {
-      "version": "1.89.0",
-      "resolved": "https://registry.npmjs.org/sass/-/sass-1.89.0.tgz",
-      "integrity": "sha512-ld+kQU8YTdGNjOLfRWBzewJpU5cwEv/h5yyqlSeJcj6Yh8U4TDA9UA5FPicqDz/xgRPWRSYIQNiFks21TbA9KQ==",
-      "license": "MIT",
-      "peer": true,
-      "dependencies": {
-        "chokidar": "^4.0.0",
-        "immutable": "^5.0.2",
-        "source-map-js": ">=0.6.2 <2.0.0"
-      },
-      "bin": {
-        "sass": "sass.js"
-      },
-      "engines": {
-        "node": ">=14.0.0"
-      },
-      "optionalDependencies": {
-        "@parcel/watcher": "^2.4.1"
-      }
-    },
-    "node_modules/sass-loader": {
-      "version": "13.3.3",
-      "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-13.3.3.tgz",
-      "integrity": "sha512-mt5YN2F1MOZr3d/wBRcZxeFgwgkH44wVc2zohO2YF6JiOMkiXe4BYRZpSu2sO1g71mo/j16txzUhsKZlqjVGzA==",
-      "license": "MIT",
-      "dependencies": {
-        "neo-async": "^2.6.2"
-      },
-      "engines": {
-        "node": ">= 14.15.0"
-      },
-      "funding": {
-        "type": "opencollective",
-        "url": "https://opencollective.com/webpack"
-      },
-      "peerDependencies": {
-        "fibers": ">= 3.1.0",
-        "node-sass": "^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0 || ^9.0.0",
-        "sass": "^1.3.0",
-        "sass-embedded": "*",
-        "webpack": "^5.0.0"
-      },
-      "peerDependenciesMeta": {
-        "fibers": {
-          "optional": true
-        },
-        "node-sass": {
-          "optional": true
-        },
-        "sass": {
-          "optional": true
-        },
-        "sass-embedded": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/saxes": {
-      "version": "6.0.0",
-      "resolved": "https://registry.npmjs.org/saxes/-/saxes-6.0.0.tgz",
-      "integrity": "sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==",
-      "dev": true,
-      "license": "ISC",
-      "dependencies": {
-        "xmlchars": "^2.2.0"
-      },
-      "engines": {
-        "node": ">=v12.22.7"
-      }
-    },
-    "node_modules/schema-utils": {
-      "version": "4.3.2",
-      "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.3.2.tgz",
-      "integrity": "sha512-Gn/JaSk/Mt9gYubxTtSn/QCV4em9mpAPiR1rqy/Ocu19u/G9J5WWdNoUT4SiV6mFC3y6cxyFcFwdzPM3FgxGAQ==",
-      "license": "MIT",
-      "dependencies": {
-        "@types/json-schema": "^7.0.9",
-        "ajv": "^8.9.0",
-        "ajv-formats": "^2.1.1",
-        "ajv-keywords": "^5.1.0"
-      },
-      "engines": {
-        "node": ">= 10.13.0"
-      },
-      "funding": {
-        "type": "opencollective",
-        "url": "https://opencollective.com/webpack"
-      }
-    },
-    "node_modules/schema-utils/node_modules/ajv": {
-      "version": "8.17.1",
-      "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz",
-      "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==",
-      "license": "MIT",
-      "peer": true,
-      "dependencies": {
-        "fast-deep-equal": "^3.1.3",
-        "fast-uri": "^3.0.1",
-        "json-schema-traverse": "^1.0.0",
-        "require-from-string": "^2.0.2"
-      },
-      "funding": {
-        "type": "github",
-        "url": "https://github.com/sponsors/epoberezkin"
-      }
-    },
-    "node_modules/schema-utils/node_modules/ajv-keywords": {
-      "version": "5.1.0",
-      "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz",
-      "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==",
-      "license": "MIT",
-      "dependencies": {
-        "fast-deep-equal": "^3.1.3"
-      },
-      "peerDependencies": {
-        "ajv": "^8.8.2"
-      }
-    },
-    "node_modules/schema-utils/node_modules/json-schema-traverse": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
-      "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
-      "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==",
-      "dev": true,
-      "license": "ISC",
-      "bin": {
-        "semver": "bin/semver.js"
-      },
-      "engines": {
-        "node": ">=10"
-      }
-    },
-    "node_modules/serialize-javascript": {
-      "version": "6.0.2",
-      "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz",
-      "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==",
-      "license": "BSD-3-Clause",
-      "dependencies": {
-        "randombytes": "^2.1.0"
-      }
-    },
-    "node_modules/shebang-command": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
-      "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "shebang-regex": "^3.0.0"
-      },
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/shebang-regex": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
-      "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/siginfo": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz",
-      "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==",
-      "dev": true,
-      "license": "ISC"
-    },
-    "node_modules/signal-exit": {
-      "version": "4.1.0",
-      "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz",
-      "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==",
-      "dev": true,
-      "license": "ISC",
-      "engines": {
-        "node": ">=14"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/isaacs"
-      }
-    },
-    "node_modules/sirv": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/sirv/-/sirv-3.0.0.tgz",
-      "integrity": "sha512-BPwJGUeDaDCHihkORDchNyyTvWFhcusy1XMmhEVTQTwGeybFbp8YEmB+njbPnth1FibULBSBVwCQni25XlCUDg==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "@polka/url": "^1.0.0-next.24",
-        "mrmime": "^2.0.0",
-        "totalist": "^3.0.0"
-      },
-      "engines": {
-        "node": ">=18"
-      }
-    },
-    "node_modules/source-map": {
-      "version": "0.6.1",
-      "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
-      "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
-      "license": "BSD-3-Clause",
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/source-map-js": {
-      "version": "1.2.1",
-      "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
-      "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==",
-      "license": "BSD-3-Clause",
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/source-map-support": {
-      "version": "0.5.21",
-      "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz",
-      "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==",
-      "license": "MIT",
-      "dependencies": {
-        "buffer-from": "^1.0.0",
-        "source-map": "^0.6.0"
-      }
-    },
-    "node_modules/speakingurl": {
-      "version": "14.0.1",
-      "resolved": "https://registry.npmjs.org/speakingurl/-/speakingurl-14.0.1.tgz",
-      "integrity": "sha512-1POYv7uv2gXoyGFpBCmpDVSNV74IfsWlDW216UPjbWufNf+bSU6GdbDsxdcxtfwb4xlI3yxzOTKClUosxARYrQ==",
-      "dev": true,
-      "license": "BSD-3-Clause",
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/stackback": {
-      "version": "0.0.2",
-      "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz",
-      "integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==",
-      "dev": true,
-      "license": "MIT"
-    },
-    "node_modules/std-env": {
-      "version": "3.8.0",
-      "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.8.0.tgz",
-      "integrity": "sha512-Bc3YwwCB+OzldMxOXJIIvC6cPRWr/LxOp48CdQTOkPyk/t4JWWJbrilwBd7RJzKV8QW7tJkcgAmeuLLJugl5/w==",
-      "dev": true,
-      "license": "MIT"
-    },
-    "node_modules/string-width": {
-      "version": "5.1.2",
-      "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz",
-      "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "eastasianwidth": "^0.2.0",
-        "emoji-regex": "^9.2.2",
-        "strip-ansi": "^7.0.1"
-      },
-      "engines": {
-        "node": ">=12"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/string-width-cjs": {
-      "name": "string-width",
-      "version": "4.2.3",
-      "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
-      "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "emoji-regex": "^8.0.0",
-        "is-fullwidth-code-point": "^3.0.0",
-        "strip-ansi": "^6.0.1"
-      },
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/string-width-cjs/node_modules/ansi-regex": {
-      "version": "5.0.1",
-      "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
-      "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/string-width-cjs/node_modules/emoji-regex": {
-      "version": "8.0.0",
-      "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
-      "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
-      "dev": true,
-      "license": "MIT"
-    },
-    "node_modules/string-width-cjs/node_modules/strip-ansi": {
-      "version": "6.0.1",
-      "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
-      "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "ansi-regex": "^5.0.1"
-      },
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/strip-ansi": {
-      "version": "7.1.0",
-      "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz",
-      "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "ansi-regex": "^6.0.1"
-      },
-      "engines": {
-        "node": ">=12"
-      },
-      "funding": {
-        "url": "https://github.com/chalk/strip-ansi?sponsor=1"
-      }
-    },
-    "node_modules/strip-ansi-cjs": {
-      "name": "strip-ansi",
-      "version": "6.0.1",
-      "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
-      "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "ansi-regex": "^5.0.1"
-      },
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/strip-ansi-cjs/node_modules/ansi-regex": {
-      "version": "5.0.1",
-      "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
-      "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/strip-final-newline": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-4.0.0.tgz",
-      "integrity": "sha512-aulFJcD6YK8V1G7iRB5tigAP4TsHBZZrOV8pjV++zdUwmeV8uzbY7yn6h9MswN62adStNZFuCIx4haBnRuMDaw==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">=18"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/strip-json-comments": {
-      "version": "3.1.1",
-      "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz",
-      "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">=8"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/superjson": {
-      "version": "2.2.2",
-      "resolved": "https://registry.npmjs.org/superjson/-/superjson-2.2.2.tgz",
-      "integrity": "sha512-5JRxVqC8I8NuOUjzBbvVJAKNM8qoVuH0O77h4WInc/qC2q5IreqKxYwgkga3PfA22OayK2ikceb/B26dztPl+Q==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "copy-anything": "^3.0.2"
-      },
-      "engines": {
-        "node": ">=16"
-      }
-    },
-    "node_modules/supports-color": {
-      "version": "7.2.0",
-      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
-      "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "has-flag": "^4.0.0"
-      },
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/svg-tags": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/svg-tags/-/svg-tags-1.0.0.tgz",
-      "integrity": "sha512-ovssysQTa+luh7A5Weu3Rta6FJlFBBbInjOh722LIt6klpU2/HtdUbszju/G4devcvk8PGt7FCLv5wftu3THUA==",
-      "dev": true
-    },
-    "node_modules/symbol-tree": {
-      "version": "3.2.4",
-      "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz",
-      "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==",
-      "dev": true,
-      "license": "MIT"
-    },
-    "node_modules/synckit": {
-      "version": "0.9.2",
-      "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.9.2.tgz",
-      "integrity": "sha512-vrozgXDQwYO72vHjUb/HnFbQx1exDjoKzqx23aXEg2a9VIg2TSFZ8FmeZpTjUCFMYw7mpX4BE2SFu8wI7asYsw==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "@pkgr/core": "^0.1.0",
-        "tslib": "^2.6.2"
-      },
-      "engines": {
-        "node": "^14.18.0 || >=16.0.0"
-      },
-      "funding": {
-        "url": "https://opencollective.com/unts"
-      }
-    },
-    "node_modules/tapable": {
-      "version": "2.2.1",
-      "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz",
-      "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==",
-      "license": "MIT",
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/terser": {
-      "version": "5.39.2",
-      "resolved": "https://registry.npmjs.org/terser/-/terser-5.39.2.tgz",
-      "integrity": "sha512-yEPUmWve+VA78bI71BW70Dh0TuV4HHd+I5SHOAfS1+QBOmvmCiiffgjR8ryyEd3KIfvPGFqoADt8LdQ6XpXIvg==",
-      "license": "BSD-2-Clause",
-      "dependencies": {
-        "@jridgewell/source-map": "^0.3.3",
-        "acorn": "^8.14.0",
-        "commander": "^2.20.0",
-        "source-map-support": "~0.5.20"
-      },
-      "bin": {
-        "terser": "bin/terser"
-      },
-      "engines": {
-        "node": ">=10"
-      }
-    },
-    "node_modules/terser-webpack-plugin": {
-      "version": "5.3.14",
-      "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.14.tgz",
-      "integrity": "sha512-vkZjpUjb6OMS7dhV+tILUW6BhpDR7P2L/aQSAv+Uwk+m8KATX9EccViHTJR2qDtACKPIYndLGCyl3FMo+r2LMw==",
-      "license": "MIT",
-      "dependencies": {
-        "@jridgewell/trace-mapping": "^0.3.25",
-        "jest-worker": "^27.4.5",
-        "schema-utils": "^4.3.0",
-        "serialize-javascript": "^6.0.2",
-        "terser": "^5.31.1"
-      },
-      "engines": {
-        "node": ">= 10.13.0"
-      },
-      "funding": {
-        "type": "opencollective",
-        "url": "https://opencollective.com/webpack"
-      },
-      "peerDependencies": {
-        "webpack": "^5.1.0"
-      },
-      "peerDependenciesMeta": {
-        "@swc/core": {
-          "optional": true
-        },
-        "esbuild": {
-          "optional": true
-        },
-        "uglify-js": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/terser/node_modules/commander": {
-      "version": "2.20.3",
-      "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
-      "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
-      "license": "MIT"
-    },
-    "node_modules/tinybench": {
-      "version": "2.9.0",
-      "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.9.0.tgz",
-      "integrity": "sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==",
-      "dev": true,
-      "license": "MIT"
-    },
-    "node_modules/tinyexec": {
-      "version": "0.3.2",
-      "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-0.3.2.tgz",
-      "integrity": "sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==",
-      "dev": true,
-      "license": "MIT"
-    },
-    "node_modules/tinyglobby": {
-      "version": "0.2.15",
-      "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz",
-      "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "fdir": "^6.5.0",
-        "picomatch": "^4.0.3"
-      },
-      "engines": {
-        "node": ">=12.0.0"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/SuperchupuDev"
-      }
-    },
-    "node_modules/tinyglobby/node_modules/fdir": {
-      "version": "6.5.0",
-      "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz",
-      "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">=12.0.0"
-      },
-      "peerDependencies": {
-        "picomatch": "^3 || ^4"
-      },
-      "peerDependenciesMeta": {
-        "picomatch": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/tinyglobby/node_modules/picomatch": {
-      "version": "4.0.3",
-      "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz",
-      "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
-      "dev": true,
-      "license": "MIT",
-      "peer": true,
-      "engines": {
-        "node": ">=12"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/jonschlinkert"
-      }
-    },
-    "node_modules/tinypool": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-1.0.2.tgz",
-      "integrity": "sha512-al6n+QEANGFOMf/dmUMsuS5/r9B06uwlyNjZZql/zv8J7ybHCgoihBNORZCY2mzUuAnomQa2JdhyHKzZxPCrFA==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": "^18.0.0 || >=20.0.0"
-      }
-    },
-    "node_modules/tinyrainbow": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-2.0.0.tgz",
-      "integrity": "sha512-op4nsTR47R6p0vMUUoYl/a+ljLFVtlfaXkLQmqfLR1qHma1h/ysYk4hEXZ880bf2CYgTskvTa/e196Vd5dDQXw==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">=14.0.0"
-      }
-    },
-    "node_modules/tinyspy": {
-      "version": "3.0.2",
-      "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-3.0.2.tgz",
-      "integrity": "sha512-n1cw8k1k0x4pgA2+9XrOkFydTerNcJ1zWCO5Nn9scWHTD+5tp8dghT2x1uduQePZTZgd3Tupf+x9BxJjeJi77Q==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">=14.0.0"
-      }
-    },
-    "node_modules/tldts": {
-      "version": "6.1.73",
-      "resolved": "https://registry.npmjs.org/tldts/-/tldts-6.1.73.tgz",
-      "integrity": "sha512-/h4bVmuEMm57c2uCiAf1Q9mlQk7cA22m+1Bu0K92vUUtTVT9D4mOFWD9r4WQuTULcG9eeZtNKhLl0Il1LdKGog==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "tldts-core": "^6.1.73"
-      },
-      "bin": {
-        "tldts": "bin/cli.js"
-      }
-    },
-    "node_modules/tldts-core": {
-      "version": "6.1.73",
-      "resolved": "https://registry.npmjs.org/tldts-core/-/tldts-core-6.1.73.tgz",
-      "integrity": "sha512-k1g5eX87vxu3g//6XMn62y4qjayu4cYby/PF7Ksnh4F4uUK1Z1ze/mJ4a+y5OjdJ+cXRp+YTInZhH+FGdUWy1w==",
-      "dev": true,
-      "license": "MIT"
-    },
-    "node_modules/to-regex-range": {
-      "version": "5.0.1",
-      "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
-      "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
-      "license": "MIT",
-      "optional": true,
-      "dependencies": {
-        "is-number": "^7.0.0"
-      },
-      "engines": {
-        "node": ">=8.0"
-      }
-    },
-    "node_modules/totalist": {
-      "version": "3.0.1",
-      "resolved": "https://registry.npmjs.org/totalist/-/totalist-3.0.1.tgz",
-      "integrity": "sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/tough-cookie": {
-      "version": "5.1.0",
-      "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-5.1.0.tgz",
-      "integrity": "sha512-rvZUv+7MoBYTiDmFPBrhL7Ujx9Sk+q9wwm22x8c8T5IJaR+Wsyc7TNxbVxo84kZoRJZZMazowFLqpankBEQrGg==",
-      "dev": true,
-      "license": "BSD-3-Clause",
-      "dependencies": {
-        "tldts": "^6.1.32"
-      },
-      "engines": {
-        "node": ">=16"
-      }
-    },
-    "node_modules/tr46": {
-      "version": "5.0.0",
-      "resolved": "https://registry.npmjs.org/tr46/-/tr46-5.0.0.tgz",
-      "integrity": "sha512-tk2G5R2KRwBd+ZN0zaEXpmzdKyOYksXwywulIX95MBODjSzMIuQnQ3m8JxgbhnL1LeVo7lqQKsYa1O3Htl7K5g==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "punycode": "^2.3.1"
-      },
-      "engines": {
-        "node": ">=18"
-      }
-    },
-    "node_modules/ts-api-utils": {
-      "version": "2.4.0",
-      "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.4.0.tgz",
-      "integrity": "sha512-3TaVTaAv2gTiMB35i3FiGJaRfwb3Pyn/j3m/bfAvGe8FB7CF6u+LMYqYlDh7reQf7UNvoTvdfAqHGmPGOSsPmA==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">=18.12"
-      },
-      "peerDependencies": {
-        "typescript": ">=4.8.4"
-      }
-    },
-    "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==",
-      "dev": true,
-      "license": "0BSD"
-    },
-    "node_modules/type-check": {
-      "version": "0.4.0",
-      "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz",
-      "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "prelude-ls": "^1.2.1"
-      },
-      "engines": {
-        "node": ">= 0.8.0"
-      }
-    },
-    "node_modules/type-fest": {
-      "version": "0.20.2",
-      "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz",
-      "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==",
-      "dev": true,
-      "license": "(MIT OR CC0-1.0)",
-      "engines": {
-        "node": ">=10"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/typescript": {
-      "version": "5.7.3",
-      "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.7.3.tgz",
-      "integrity": "sha512-84MVSjMEHP+FQRPy3pX9sTVV/INIex71s9TL2Gm5FG/WG1SqXeKyZ0k7/blY/4FdOzI12CBy1vGc4og/eus0fw==",
-      "devOptional": true,
-      "license": "Apache-2.0",
-      "peer": true,
-      "bin": {
-        "tsc": "bin/tsc",
-        "tsserver": "bin/tsserver"
-      },
-      "engines": {
-        "node": ">=14.17"
-      }
-    },
-    "node_modules/undici-types": {
-      "version": "6.21.0",
-      "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz",
-      "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==",
-      "license": "MIT"
-    },
-    "node_modules/unicorn-magic": {
-      "version": "0.3.0",
-      "resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.3.0.tgz",
-      "integrity": "sha512-+QBBXBCvifc56fsbuxZQ6Sic3wqqc3WWaqxs58gvJrcOuN83HGTCwz3oS5phzU9LthRNE9VrJCFCLUgHeeFnfA==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">=18"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/universalify": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz",
-      "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">= 10.0.0"
-      }
-    },
-    "node_modules/update-browserslist-db": {
-      "version": "1.1.2",
-      "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.2.tgz",
-      "integrity": "sha512-PPypAm5qvlD7XMZC3BujecnaOxwhrtoFR+Dqkk5Aa/6DssiH0ibKoketaj9w8LP7Bont1rYeoV5plxD7RTEPRg==",
-      "funding": [
-        {
-          "type": "opencollective",
-          "url": "https://opencollective.com/browserslist"
-        },
-        {
-          "type": "tidelift",
-          "url": "https://tidelift.com/funding/github/npm/browserslist"
-        },
-        {
-          "type": "github",
-          "url": "https://github.com/sponsors/ai"
-        }
-      ],
-      "license": "MIT",
-      "dependencies": {
-        "escalade": "^3.2.0",
-        "picocolors": "^1.1.1"
-      },
-      "bin": {
-        "update-browserslist-db": "cli.js"
-      },
-      "peerDependencies": {
-        "browserslist": ">= 4.21.0"
-      }
-    },
-    "node_modules/uri-js": {
-      "version": "4.4.1",
-      "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
-      "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==",
-      "dev": true,
-      "license": "BSD-2-Clause",
-      "dependencies": {
-        "punycode": "^2.1.0"
-      }
-    },
-    "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==",
-      "dev": true,
-      "license": "MIT"
-    },
-    "node_modules/vite": {
-      "version": "6.0.11",
-      "resolved": "https://registry.npmjs.org/vite/-/vite-6.0.11.tgz",
-      "integrity": "sha512-4VL9mQPKoHy4+FE0NnRE/kbY51TOfaknxAjt3fJbGJxhIpBZiqVzlZDEesWWsuREXHwNdAoOFZ9MkPEVXczHwg==",
-      "dev": true,
-      "license": "MIT",
-      "peer": true,
-      "dependencies": {
-        "esbuild": "^0.24.2",
-        "postcss": "^8.4.49",
-        "rollup": "^4.23.0"
-      },
-      "bin": {
-        "vite": "bin/vite.js"
-      },
-      "engines": {
-        "node": "^18.0.0 || ^20.0.0 || >=22.0.0"
-      },
-      "funding": {
-        "url": "https://github.com/vitejs/vite?sponsor=1"
-      },
-      "optionalDependencies": {
-        "fsevents": "~2.3.3"
-      },
-      "peerDependencies": {
-        "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0",
-        "jiti": ">=1.21.0",
-        "less": "*",
-        "lightningcss": "^1.21.0",
-        "sass": "*",
-        "sass-embedded": "*",
-        "stylus": "*",
-        "sugarss": "*",
-        "terser": "^5.16.0",
-        "tsx": "^4.8.1",
-        "yaml": "^2.4.2"
-      },
-      "peerDependenciesMeta": {
-        "@types/node": {
-          "optional": true
-        },
-        "jiti": {
-          "optional": true
-        },
-        "less": {
-          "optional": true
-        },
-        "lightningcss": {
-          "optional": true
-        },
-        "sass": {
-          "optional": true
-        },
-        "sass-embedded": {
-          "optional": true
-        },
-        "stylus": {
-          "optional": true
-        },
-        "sugarss": {
-          "optional": true
-        },
-        "terser": {
-          "optional": true
-        },
-        "tsx": {
-          "optional": true
-        },
-        "yaml": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/vite-hot-client": {
-      "version": "0.2.4",
-      "resolved": "https://registry.npmjs.org/vite-hot-client/-/vite-hot-client-0.2.4.tgz",
-      "integrity": "sha512-a1nzURqO7DDmnXqabFOliz908FRmIppkBKsJthS8rbe8hBEXwEwe4C3Pp33Z1JoFCYfVL4kTOMLKk0ZZxREIeA==",
-      "dev": true,
-      "license": "MIT",
-      "funding": {
-        "url": "https://github.com/sponsors/antfu"
-      },
-      "peerDependencies": {
-        "vite": "^2.6.0 || ^3.0.0 || ^4.0.0 || ^5.0.0-0 || ^6.0.0-0"
-      }
-    },
-    "node_modules/vite-node": {
-      "version": "3.0.3",
-      "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-3.0.3.tgz",
-      "integrity": "sha512-0sQcwhwAEw/UJGojbhOrnq3HtiZ3tC7BzpAa0lx3QaTX0S3YX70iGcik25UBdB96pmdwjyY2uyKNYruxCDmiEg==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "cac": "^6.7.14",
-        "debug": "^4.4.0",
-        "es-module-lexer": "^1.6.0",
-        "pathe": "^2.0.1",
-        "vite": "^5.0.0 || ^6.0.0"
-      },
-      "bin": {
-        "vite-node": "vite-node.mjs"
-      },
-      "engines": {
-        "node": "^18.0.0 || ^20.0.0 || >=22.0.0"
-      },
-      "funding": {
-        "url": "https://opencollective.com/vitest"
-      }
-    },
-    "node_modules/vite-node/node_modules/pathe": {
-      "version": "2.0.2",
-      "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.2.tgz",
-      "integrity": "sha512-15Ztpk+nov8DR524R4BF7uEuzESgzUEAV4Ah7CUMNGXdE5ELuvxElxGXndBl32vMSsWa1jpNf22Z+Er3sKwq+w==",
-      "dev": true,
-      "license": "MIT"
-    },
-    "node_modules/vite-plugin-inspect": {
-      "version": "0.8.9",
-      "resolved": "https://registry.npmjs.org/vite-plugin-inspect/-/vite-plugin-inspect-0.8.9.tgz",
-      "integrity": "sha512-22/8qn+LYonzibb1VeFZmISdVao5kC22jmEKm24vfFE8siEn47EpVcCLYMv6iKOYMJfjSvSJfueOwcFCkUnV3A==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "@antfu/utils": "^0.7.10",
-        "@rollup/pluginutils": "^5.1.3",
-        "debug": "^4.3.7",
-        "error-stack-parser-es": "^0.1.5",
-        "fs-extra": "^11.2.0",
-        "open": "^10.1.0",
-        "perfect-debounce": "^1.0.0",
-        "picocolors": "^1.1.1",
-        "sirv": "^3.0.0"
-      },
-      "engines": {
-        "node": ">=14"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/antfu"
-      },
-      "peerDependencies": {
-        "vite": "^3.1.0 || ^4.0.0 || ^5.0.0-0 || ^6.0.1"
-      },
-      "peerDependenciesMeta": {
-        "@nuxt/kit": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/vite-plugin-vue-devtools": {
-      "version": "7.7.0",
-      "resolved": "https://registry.npmjs.org/vite-plugin-vue-devtools/-/vite-plugin-vue-devtools-7.7.0.tgz",
-      "integrity": "sha512-1dWiREwIl4JELwXGHXih80hIgjcViMcZGr3j0edo6NQ9kNzAOxMIUgFqc/TO1ary4ZroJUxoB0YDI6jnDf13iQ==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "@vue/devtools-core": "^7.7.0",
-        "@vue/devtools-kit": "^7.7.0",
-        "@vue/devtools-shared": "^7.7.0",
-        "execa": "^9.5.1",
-        "sirv": "^3.0.0",
-        "vite-plugin-inspect": "0.8.9",
-        "vite-plugin-vue-inspector": "^5.3.1"
-      },
-      "engines": {
-        "node": ">=v14.21.3"
-      },
-      "peerDependencies": {
-        "vite": "^3.1.0 || ^4.0.0-0 || ^5.0.0-0 || ^6.0.0-0"
-      }
-    },
-    "node_modules/vite-plugin-vue-inspector": {
-      "version": "5.3.1",
-      "resolved": "https://registry.npmjs.org/vite-plugin-vue-inspector/-/vite-plugin-vue-inspector-5.3.1.tgz",
-      "integrity": "sha512-cBk172kZKTdvGpJuzCCLg8lJ909wopwsu3Ve9FsL1XsnLBiRT9U3MePcqrgGHgCX2ZgkqZmAGR8taxw+TV6s7A==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "@babel/core": "^7.23.0",
-        "@babel/plugin-proposal-decorators": "^7.23.0",
-        "@babel/plugin-syntax-import-attributes": "^7.22.5",
-        "@babel/plugin-syntax-import-meta": "^7.10.4",
-        "@babel/plugin-transform-typescript": "^7.22.15",
-        "@vue/babel-plugin-jsx": "^1.1.5",
-        "@vue/compiler-dom": "^3.3.4",
-        "kolorist": "^1.8.0",
-        "magic-string": "^0.30.4"
-      },
-      "peerDependencies": {
-        "vite": "^3.0.0-0 || ^4.0.0-0 || ^5.0.0-0 || ^6.0.0-0"
-      }
-    },
-    "node_modules/vitest": {
-      "version": "3.0.3",
-      "resolved": "https://registry.npmjs.org/vitest/-/vitest-3.0.3.tgz",
-      "integrity": "sha512-dWdwTFUW9rcnL0LyF2F+IfvNQWB0w9DERySCk8VMG75F8k25C7LsZoh6XfCjPvcR8Nb+Lqi9JKr6vnzH7HSrpQ==",
-      "dev": true,
-      "license": "MIT",
-      "peer": true,
-      "dependencies": {
-        "@vitest/expect": "3.0.3",
-        "@vitest/mocker": "3.0.3",
-        "@vitest/pretty-format": "^3.0.3",
-        "@vitest/runner": "3.0.3",
-        "@vitest/snapshot": "3.0.3",
-        "@vitest/spy": "3.0.3",
-        "@vitest/utils": "3.0.3",
-        "chai": "^5.1.2",
-        "debug": "^4.4.0",
-        "expect-type": "^1.1.0",
-        "magic-string": "^0.30.17",
-        "pathe": "^2.0.1",
-        "std-env": "^3.8.0",
-        "tinybench": "^2.9.0",
-        "tinyexec": "^0.3.2",
-        "tinypool": "^1.0.2",
-        "tinyrainbow": "^2.0.0",
-        "vite": "^5.0.0 || ^6.0.0",
-        "vite-node": "3.0.3",
-        "why-is-node-running": "^2.3.0"
-      },
-      "bin": {
-        "vitest": "vitest.mjs"
-      },
-      "engines": {
-        "node": "^18.0.0 || ^20.0.0 || >=22.0.0"
-      },
-      "funding": {
-        "url": "https://opencollective.com/vitest"
-      },
-      "peerDependencies": {
-        "@edge-runtime/vm": "*",
-        "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0",
-        "@vitest/browser": "3.0.3",
-        "@vitest/ui": "3.0.3",
-        "happy-dom": "*",
-        "jsdom": "*"
-      },
-      "peerDependenciesMeta": {
-        "@edge-runtime/vm": {
-          "optional": true
-        },
-        "@types/node": {
-          "optional": true
-        },
-        "@vitest/browser": {
-          "optional": true
-        },
-        "@vitest/ui": {
-          "optional": true
-        },
-        "happy-dom": {
-          "optional": true
-        },
-        "jsdom": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/vitest/node_modules/pathe": {
-      "version": "2.0.2",
-      "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.2.tgz",
-      "integrity": "sha512-15Ztpk+nov8DR524R4BF7uEuzESgzUEAV4Ah7CUMNGXdE5ELuvxElxGXndBl32vMSsWa1jpNf22Z+Er3sKwq+w==",
-      "dev": true,
-      "license": "MIT"
-    },
-    "node_modules/vue": {
-      "version": "3.5.13",
-      "resolved": "https://registry.npmjs.org/vue/-/vue-3.5.13.tgz",
-      "integrity": "sha512-wmeiSMxkZCSc+PM2w2VRsOYAZC8GdipNFRTsLSfodVqI9mbejKeXEGr8SckuLnrQPGe3oJN5c3K0vpoU9q/wCQ==",
-      "license": "MIT",
-      "peer": true,
-      "dependencies": {
-        "@vue/compiler-dom": "3.5.13",
-        "@vue/compiler-sfc": "3.5.13",
-        "@vue/runtime-dom": "3.5.13",
-        "@vue/server-renderer": "3.5.13",
-        "@vue/shared": "3.5.13"
-      },
-      "peerDependencies": {
-        "typescript": "*"
-      },
-      "peerDependenciesMeta": {
-        "typescript": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/vue-component-type-helpers": {
-      "version": "2.2.0",
-      "resolved": "https://registry.npmjs.org/vue-component-type-helpers/-/vue-component-type-helpers-2.2.0.tgz",
-      "integrity": "sha512-cYrAnv2me7bPDcg9kIcGwjJiSB6Qyi08+jLDo9yuvoFQjzHiPTzML7RnkJB1+3P6KMsX/KbCD4QE3Tv/knEllw==",
-      "dev": true,
-      "license": "MIT"
-    },
-    "node_modules/vue-demi": {
-      "version": "0.14.10",
-      "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.10.tgz",
-      "integrity": "sha512-nMZBOwuzabUO0nLgIcc6rycZEebF6eeUfaiQx9+WSk8e29IbLvPU9feI6tqW4kTo3hvoYAJkMh8n8D0fuISphg==",
-      "hasInstallScript": true,
-      "license": "MIT",
-      "bin": {
-        "vue-demi-fix": "bin/vue-demi-fix.js",
-        "vue-demi-switch": "bin/vue-demi-switch.js"
-      },
-      "engines": {
-        "node": ">=12"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/antfu"
-      },
-      "peerDependencies": {
-        "@vue/composition-api": "^1.0.0-rc.1",
-        "vue": "^3.0.0-0 || ^2.6.0"
-      },
-      "peerDependenciesMeta": {
-        "@vue/composition-api": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/vue-eslint-parser": {
-      "version": "9.4.3",
-      "resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-9.4.3.tgz",
-      "integrity": "sha512-2rYRLWlIpaiN8xbPiDyXZXRgLGOtWxERV7ND5fFAv5qo1D2N9Fu9MNajBNc6o13lZ+24DAWCkQCvj4klgmcITg==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "debug": "^4.3.4",
-        "eslint-scope": "^7.1.1",
-        "eslint-visitor-keys": "^3.3.0",
-        "espree": "^9.3.1",
-        "esquery": "^1.4.0",
-        "lodash": "^4.17.21",
-        "semver": "^7.3.6"
-      },
-      "engines": {
-        "node": "^14.17.0 || >=16.0.0"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/mysticatea"
-      },
-      "peerDependencies": {
-        "eslint": ">=6.0.0"
-      }
-    },
-    "node_modules/vue-eslint-parser/node_modules/eslint-scope": {
-      "version": "7.2.2",
-      "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz",
-      "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==",
-      "dev": true,
-      "license": "BSD-2-Clause",
-      "dependencies": {
-        "esrecurse": "^4.3.0",
-        "estraverse": "^5.2.0"
-      },
-      "engines": {
-        "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
-      },
-      "funding": {
-        "url": "https://opencollective.com/eslint"
-      }
-    },
-    "node_modules/vue-eslint-parser/node_modules/espree": {
-      "version": "9.6.1",
-      "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz",
-      "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==",
-      "dev": true,
-      "license": "BSD-2-Clause",
-      "dependencies": {
-        "acorn": "^8.9.0",
-        "acorn-jsx": "^5.3.2",
-        "eslint-visitor-keys": "^3.4.1"
-      },
-      "engines": {
-        "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
-      },
-      "funding": {
-        "url": "https://opencollective.com/eslint"
-      }
-    },
-    "node_modules/vue-router": {
-      "version": "4.5.0",
-      "resolved": "https://registry.npmjs.org/vue-router/-/vue-router-4.5.0.tgz",
-      "integrity": "sha512-HDuk+PuH5monfNuY+ct49mNmkCRK4xJAV9Ts4z9UFc4rzdDnxQLyCMGGc8pKhZhHTVzfanpNwB/lwqevcBwI4w==",
-      "license": "MIT",
-      "dependencies": {
-        "@vue/devtools-api": "^6.6.4"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/posva"
-      },
-      "peerDependencies": {
-        "vue": "^3.2.0"
-      }
-    },
-    "node_modules/vue3-google-login": {
-      "version": "2.0.34",
-      "resolved": "https://registry.npmjs.org/vue3-google-login/-/vue3-google-login-2.0.34.tgz",
-      "integrity": "sha512-YLEYcv8eKzA7BLsTciDogvxXxyJga4879HkmvWjYsm1t0mJ0Vx5A1EWKMx0YCtMQ2VwQJGy3F8aOw6zO+KkUhA==",
-      "license": "MIT",
-      "peerDependencies": {
-        "vue": "^3.0.3"
-      }
-    },
-    "node_modules/vue3-google-signin": {
-      "version": "2.1.1",
-      "resolved": "https://registry.npmjs.org/vue3-google-signin/-/vue3-google-signin-2.1.1.tgz",
-      "integrity": "sha512-RwlwyeCv8+PZjK35C/UyJN4/9MH+Fsz4bJDO7IjtmRuOaTMrvmMmI6SP5qkJgD7w9MIKOCj5rYVFMAL7+NCM0A==",
-      "license": "MIT",
-      "peerDependencies": {
-        "vue": "^3"
-      }
-    },
-    "node_modules/vue3-otp-input": {
-      "version": "0.5.40",
-      "resolved": "https://registry.npmjs.org/vue3-otp-input/-/vue3-otp-input-0.5.40.tgz",
-      "integrity": "sha512-3AMYHqNz9ZDa9y7ICwcEcsJG7XdZGaLAr6IRLIl3whvseFE95F5Duc9q963HcqEbu8CeMWilkmbAt/0eZOZxow==",
-      "license": "MIT",
-      "dependencies": {
-        "vue": "^3.4.27"
-      },
-      "peerDependencies": {
-        "vue": "^3.0.*"
-      }
-    },
-    "node_modules/vuetify": {
-      "version": "3.8.0-beta.0",
-      "resolved": "https://registry.npmjs.org/vuetify/-/vuetify-3.8.0-beta.0.tgz",
-      "integrity": "sha512-wixr3ybX25yMmhnd43XxnChuaGDnz0KuKY2ttvbrdojtkmMqNkDssIM0qty2L7PDy1xc2wFuRTfm20hyayldYQ==",
-      "license": "MIT",
-      "engines": {
-        "node": "^12.20 || >=14.13"
-      },
-      "funding": {
-        "type": "github",
-        "url": "https://github.com/sponsors/johnleider"
-      },
-      "peerDependencies": {
-        "typescript": ">=4.7",
-        "vite-plugin-vuetify": ">=2.1.0",
-        "vue": "^3.5.0",
-        "webpack-plugin-vuetify": ">=3.1.0"
-      },
-      "peerDependenciesMeta": {
-        "typescript": {
-          "optional": true
-        },
-        "vite-plugin-vuetify": {
-          "optional": true
-        },
-        "webpack-plugin-vuetify": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/w3c-xmlserializer": {
-      "version": "5.0.0",
-      "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-5.0.0.tgz",
-      "integrity": "sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "xml-name-validator": "^5.0.0"
-      },
-      "engines": {
-        "node": ">=18"
-      }
-    },
-    "node_modules/w3c-xmlserializer/node_modules/xml-name-validator": {
-      "version": "5.0.0",
-      "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-5.0.0.tgz",
-      "integrity": "sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg==",
-      "dev": true,
-      "license": "Apache-2.0",
-      "engines": {
-        "node": ">=18"
-      }
-    },
-    "node_modules/watchpack": {
-      "version": "2.4.2",
-      "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.2.tgz",
-      "integrity": "sha512-TnbFSbcOCcDgjZ4piURLCbJ3nJhznVh9kw6F6iokjiFPl8ONxe9A6nMDVXDiNbrSfLILs6vB07F7wLBrwPYzJw==",
-      "license": "MIT",
-      "dependencies": {
-        "glob-to-regexp": "^0.4.1",
-        "graceful-fs": "^4.1.2"
-      },
-      "engines": {
-        "node": ">=10.13.0"
-      }
-    },
-    "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==",
-      "dev": true,
-      "license": "BSD-2-Clause",
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/webpack": {
-      "version": "5.99.8",
-      "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.99.8.tgz",
-      "integrity": "sha512-lQ3CPiSTpfOnrEGeXDwoq5hIGzSjmwD72GdfVzF7CQAI7t47rJG9eDWvcEkEn3CUQymAElVvDg3YNTlCYj+qUQ==",
-      "license": "MIT",
-      "dependencies": {
-        "@types/eslint-scope": "^3.7.7",
-        "@types/estree": "^1.0.6",
-        "@types/json-schema": "^7.0.15",
-        "@webassemblyjs/ast": "^1.14.1",
-        "@webassemblyjs/wasm-edit": "^1.14.1",
-        "@webassemblyjs/wasm-parser": "^1.14.1",
-        "acorn": "^8.14.0",
-        "browserslist": "^4.24.0",
-        "chrome-trace-event": "^1.0.2",
-        "enhanced-resolve": "^5.17.1",
-        "es-module-lexer": "^1.2.1",
-        "eslint-scope": "5.1.1",
-        "events": "^3.2.0",
-        "glob-to-regexp": "^0.4.1",
-        "graceful-fs": "^4.2.11",
-        "json-parse-even-better-errors": "^2.3.1",
-        "loader-runner": "^4.2.0",
-        "mime-types": "^2.1.27",
-        "neo-async": "^2.6.2",
-        "schema-utils": "^4.3.2",
-        "tapable": "^2.1.1",
-        "terser-webpack-plugin": "^5.3.11",
-        "watchpack": "^2.4.1",
-        "webpack-sources": "^3.2.3"
-      },
-      "bin": {
-        "webpack": "bin/webpack.js"
-      },
-      "engines": {
-        "node": ">=10.13.0"
-      },
-      "funding": {
-        "type": "opencollective",
-        "url": "https://opencollective.com/webpack"
-      },
-      "peerDependenciesMeta": {
-        "webpack-cli": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/webpack-sources": {
-      "version": "3.2.3",
-      "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz",
-      "integrity": "sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==",
-      "license": "MIT",
-      "engines": {
-        "node": ">=10.13.0"
-      }
-    },
-    "node_modules/webpack/node_modules/eslint-scope": {
-      "version": "5.1.1",
-      "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz",
-      "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==",
-      "license": "BSD-2-Clause",
-      "dependencies": {
-        "esrecurse": "^4.3.0",
-        "estraverse": "^4.1.1"
-      },
-      "engines": {
-        "node": ">=8.0.0"
-      }
-    },
-    "node_modules/webpack/node_modules/estraverse": {
-      "version": "4.3.0",
-      "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz",
-      "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==",
-      "license": "BSD-2-Clause",
-      "engines": {
-        "node": ">=4.0"
-      }
-    },
-    "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==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "iconv-lite": "0.6.3"
-      },
-      "engines": {
-        "node": ">=18"
-      }
-    },
-    "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==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">=18"
-      }
-    },
-    "node_modules/whatwg-url": {
-      "version": "14.1.0",
-      "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-14.1.0.tgz",
-      "integrity": "sha512-jlf/foYIKywAt3x/XWKZ/3rz8OSJPiWktjmk891alJUEjiVxKX9LEO92qH3hv4aJ0mN3MWPvGMCy8jQi95xK4w==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "tr46": "^5.0.0",
-        "webidl-conversions": "^7.0.0"
-      },
-      "engines": {
-        "node": ">=18"
-      }
-    },
-    "node_modules/which": {
-      "version": "2.0.2",
-      "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
-      "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
-      "dev": true,
-      "license": "ISC",
-      "dependencies": {
-        "isexe": "^2.0.0"
-      },
-      "bin": {
-        "node-which": "bin/node-which"
-      },
-      "engines": {
-        "node": ">= 8"
-      }
-    },
-    "node_modules/why-is-node-running": {
-      "version": "2.3.0",
-      "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.3.0.tgz",
-      "integrity": "sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "siginfo": "^2.0.0",
-        "stackback": "0.0.2"
-      },
-      "bin": {
-        "why-is-node-running": "cli.js"
-      },
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/word-wrap": {
-      "version": "1.2.5",
-      "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz",
-      "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/wrap-ansi": {
-      "version": "8.1.0",
-      "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz",
-      "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "ansi-styles": "^6.1.0",
-        "string-width": "^5.0.1",
-        "strip-ansi": "^7.0.1"
-      },
-      "engines": {
-        "node": ">=12"
-      },
-      "funding": {
-        "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
-      }
-    },
-    "node_modules/wrap-ansi-cjs": {
-      "name": "wrap-ansi",
-      "version": "7.0.0",
-      "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
-      "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "ansi-styles": "^4.0.0",
-        "string-width": "^4.1.0",
-        "strip-ansi": "^6.0.0"
-      },
-      "engines": {
-        "node": ">=10"
-      },
-      "funding": {
-        "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
-      }
-    },
-    "node_modules/wrap-ansi-cjs/node_modules/ansi-regex": {
-      "version": "5.0.1",
-      "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
-      "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/wrap-ansi-cjs/node_modules/emoji-regex": {
-      "version": "8.0.0",
-      "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
-      "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
-      "dev": true,
-      "license": "MIT"
-    },
-    "node_modules/wrap-ansi-cjs/node_modules/string-width": {
-      "version": "4.2.3",
-      "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
-      "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "emoji-regex": "^8.0.0",
-        "is-fullwidth-code-point": "^3.0.0",
-        "strip-ansi": "^6.0.1"
-      },
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/wrap-ansi-cjs/node_modules/strip-ansi": {
-      "version": "6.0.1",
-      "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
-      "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "ansi-regex": "^5.0.1"
-      },
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/wrap-ansi/node_modules/ansi-styles": {
-      "version": "6.2.1",
-      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz",
-      "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">=12"
-      },
-      "funding": {
-        "url": "https://github.com/chalk/ansi-styles?sponsor=1"
-      }
-    },
-    "node_modules/ws": {
-      "version": "8.18.0",
-      "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz",
-      "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">=10.0.0"
-      },
-      "peerDependencies": {
-        "bufferutil": "^4.0.1",
-        "utf-8-validate": ">=5.0.2"
-      },
-      "peerDependenciesMeta": {
-        "bufferutil": {
-          "optional": true
-        },
-        "utf-8-validate": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/xml-name-validator": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-4.0.0.tgz",
-      "integrity": "sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==",
-      "dev": true,
-      "license": "Apache-2.0",
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/xmlchars": {
-      "version": "2.2.0",
-      "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz",
-      "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==",
-      "dev": true,
-      "license": "MIT"
-    },
-    "node_modules/yallist": {
-      "version": "3.1.1",
-      "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
-      "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==",
-      "dev": true,
-      "license": "ISC"
-    },
-    "node_modules/yocto-queue": {
-      "version": "0.1.0",
-      "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
-      "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">=10"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/yoctocolors": {
-      "version": "2.1.1",
-      "resolved": "https://registry.npmjs.org/yoctocolors/-/yoctocolors-2.1.1.tgz",
-      "integrity": "sha512-GQHQqAopRhwU8Kt1DDM8NjibDXHC8eoh1erhGAJPEyveY9qqVeXvVikNKrDz69sHowPMorbPUrH/mx8c50eiBQ==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">=18"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    }
-  }
-}
Index: serveNGo-frontend/package.json
===================================================================
--- ReserveNGo-frontend/package.json	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,44 +1,0 @@
-{
-  "name": "vue-project",
-  "version": "0.0.0",
-  "private": true,
-  "type": "module",
-  "scripts": {
-    "dev": "vite",
-    "build": "vite build",
-    "preview": "vite preview",
-    "test:unit": "vitest",
-    "lint": "eslint . --fix",
-    "format": "prettier --write src/"
-  },
-  "dependencies": {
-    "@fortawesome/fontawesome-free": "^6.7.2",
-    "@mdi/font": "^7.4.47",
-    "bootstrap": "^5.3.8",
-    "pinia": "^2.3.1",
-    "sass": "^1.89.0",
-    "sass-loader": "^13.3.3",
-    "vue": "^3.5.13",
-    "vue-router": "^4.5.0",
-    "vue3-google-login": "^2.0.34",
-    "vue3-google-signin": "^2.1.1",
-    "vue3-otp-input": "^0.5.40",
-    "vuetify": "^3.8.0-beta.0"
-  },
-  "devDependencies": {
-    "@eslint/js": "^9.18.0",
-    "@typescript-eslint/eslint-plugin": "^8.54.0",
-    "@typescript-eslint/parser": "^8.54.0",
-    "@vitejs/plugin-vue": "^5.2.1",
-    "@vitest/eslint-plugin": "1.1.25",
-    "@vue/eslint-config-prettier": "^10.1.0",
-    "@vue/test-utils": "^2.4.6",
-    "eslint": "^9.18.0",
-    "eslint-plugin-vue": "^9.32.0",
-    "jsdom": "^26.0.0",
-    "prettier": "^3.4.2",
-    "vite": "^6.0.11",
-    "vite-plugin-vue-devtools": "^7.7.0",
-    "vitest": "^3.0.2"
-  }
-}
Index: serveNGo-frontend/src/Api_Classes/ApiClient.js
===================================================================
--- ReserveNGo-frontend/src/Api_Classes/ApiClient.js	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,12 +1,0 @@
-import { config } from '/src/constants/Api_config.js'
-import { HttpClient } from '@/Api_Classes/HttpClient.js'
-
-const BASE_API_URL = config.API_BASE_URL
-
-export class ApiClient {
-  constructor(baseURL) {
-    this.httpClient = new HttpClient(baseURL)
-  }
-}
-
-export const apiClient = new ApiClient(BASE_API_URL)
Index: serveNGo-frontend/src/Api_Classes/HttpClient.js
===================================================================
--- ReserveNGo-frontend/src/Api_Classes/HttpClient.js	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,155 +1,0 @@
-export class HttpClient {
-  constructor(baseURL) {
-    this.baseURL = baseURL
-  }
-
-  async baseFetch(endpoint, { method = 'GET', headers = {}, body, queryParams } = {}) {
-    if (endpoint === undefined || endpoint === '' || endpoint === null) {
-      endpoint = this.baseURL
-    } else {
-      endpoint = this.baseURL + '/' + endpoint
-    }
-    const url = new URL(endpoint)
-    if (queryParams) {
-      Object.entries(queryParams).forEach(([k, v]) => {
-        if (v !== undefined && v !== null && v !== '') {
-          url.searchParams.append(k, String(v))
-        }
-      })
-    }
-
-    const finalHeaders = { ...headers }
-
-    //Crucial code, adds the jwt, maybe to be changed later.
-    const nonParsed = localStorage.getItem('userData')
-    if (nonParsed) {
-      const token = JSON.parse(nonParsed).token
-      if (token) {
-        finalHeaders['Authorization'] = `Bearer ${token}`
-      }
-    }
-
-    const config = { method, headers: finalHeaders, body }
-
-    /* console.warn(config);*/
-
-    /* console.warn(url.toString());*/
-
-    const res = await fetch(url.toString(), config)
-    const clonedRes = res.clone()
-
-    const contentType = res.headers.get('Content-Type') || ''
-
-    let parsed
-
-    try {
-      if (contentType.includes('application/json')) {
-        parsed = await res.json()
-      } else if (contentType.startsWith('text/')) {
-        parsed = await res.text()
-      } else {
-        parsed = await res.blob()
-      }
-    } catch (err) {
-      console.warn('Error parsing response body:', err)
-      parsed = null
-    }
-
-    if (!res.ok) {
-      const error = new Error(`Request failed with status ${res.status}`)
-      error.status = res.status
-      error.statusText = res.statusText
-      error.url = url.toString()
-      error.response = parsed // <--- THIS LINE
-      error.rawResponse = clonedRes
-      throw error
-    }
-
-    return parsed
-  }
-
-  json(endpoint, method, data = null, options = {}) {
-    return this.baseFetch(endpoint, {
-      ...options,
-      method,
-      headers: {
-        'Content-Type': 'application/json',
-        ...(options.headers || {}),
-      },
-      body: data ? JSON.stringify(data) : undefined,
-    })
-  }
-
-  form(endpoint, method, formData, options = {}) {
-    return this.baseFetch(endpoint, {
-      ...options,
-      method,
-      body: formData,
-      headers: {
-        ...(options.headers || {}),
-      },
-    })
-  }
-
-  get(endpoint, options = {}) {
-    const config = {
-      ...options,
-      method: 'GET',
-      body: undefined,
-    }
-    return this.baseFetch(endpoint, config)
-  }
-
-  post(endpoint, data, options = {}) {
-    return this.json(endpoint, 'POST', data, options)
-  }
-
-  put(endpoint, data, options = {}) {
-    return this.json(endpoint, 'PUT', data, options)
-  }
-
-  patch(endpoint, data, options = {}) {
-    return this.json(endpoint, 'PATCH', data, options)
-  }
-
-  delete(endpoint, body = null, options = {}) {
-    return this.json(endpoint, 'DELETE', body, options)
-  }
-
-  upload(endpoint, formData, options = {}) {
-    return this.form(endpoint, 'POST', formData, options)
-  }
-
-  async fetchImageAsBase64(imagePath) {
-    try {
-      console.warn(`Fetching image as Base64 using baseFetch from: ${imagePath}`)
-      const blob = await this.baseFetch(imagePath, { method: 'GET' })
-
-      // Ensure that the response is indeed a Blob
-      if (!(blob instanceof Blob)) {
-        throw new Error(
-          'Expected a Blob response, but received a different type. Check Content-Type header.',
-        )
-      }
-
-      return new Promise((resolve, reject) => {
-        const reader = new FileReader()
-        reader.onloadend = () => {
-          if (typeof reader.result === 'string') {
-            resolve(reader.result) // This is the base64 string
-          } else {
-            reject(new Error('FileReader did not return a string result for Base64 conversion.'))
-          }
-        }
-        reader.onerror = (error) => {
-          console.error('FileReader error:', error)
-          reject(new Error('Failed to read image as Base64.'))
-        }
-        reader.readAsDataURL(blob) // Convert blob to base64 data URL
-      })
-    } catch (err) {
-      console.error('Error fetching or converting image to Base64:', err)
-      throw err // Re-throw the error for the caller to handle
-    }
-  }
-}
Index: serveNGo-frontend/src/App.vue
===================================================================
--- ReserveNGo-frontend/src/App.vue	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,128 +1,0 @@
-<script>
-import HeaderNavigationBar from './components/Project/Bars/HeaderNavigationBar.vue'
-import FooterBar from '@/components/Project/Bars/FooterBar.vue'
-import { userStore } from '@/PiniaStores/UserStore.js'
-import ToastContainer from './components/Project/Utility/ToastContainer.vue'
-
-export default {
-  components: { NavBar: HeaderNavigationBar, FooterStatic: FooterBar, ToastContainer },
-
-  data() {
-    return {
-      showScrollTop: false,
-    }
-  },
-
-  beforeMount() {
-    userStore().getLocalStorage()
-  },
-
-  mounted() {
-    window.addEventListener('scroll', this.handleScroll)
-    this.handleScroll()
-  },
-
-  beforeUnmount() {
-    window.removeEventListener('scroll', this.handleScroll)
-  },
-
-  methods: {
-    handleScroll() {
-      this.showScrollTop = window.scrollY > 200
-    },
-    scrollToTop() {
-      window.scrollTo({
-        top: 0,
-        behavior: 'smooth',
-      })
-    },
-  },
-}
-</script>
-
-<template>
-  <div class="wrapper">
-    <NavBar />
-
-    <main class="content">
-      <router-view />
-    </main>
-
-    <FooterStatic />
-
-    <transition name="fade">
-      <button
-        v-if="showScrollTop"
-        class="back-to-top-btn"
-        aria-label="Back to top"
-        @click="scrollToTop"
-      >
-        <i class="fas fa-arrow-up"></i>
-      </button>
-    </transition>
-  </div>
-  <ToastContainer />
-</template>
-
-<style>
-.wrapper {
-  display: flex;
-  flex-direction: column;
-  min-height: 100vh;
-}
-
-nav.navbar {
-  position: fixed;
-  top: 0;
-  left: 0;
-  right: 0;
-  height: auto;
-  z-index: 1000;
-  background: #8377d1;
-}
-
-main.content {
-  flex: 1;
-  margin-top: 80px;
-  background: #f3f5f8;
-  overflow-y: auto;
-}
-
-.back-to-top-btn {
-  position: fixed;
-  bottom: 2rem;
-  right: 2rem;
-  width: 50px;
-  height: 50px;
-  border-radius: 50%;
-  background-color: #5ea5bc;
-  color: #fff;
-  border: none;
-  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
-  cursor: pointer;
-  display: flex;
-  align-items: center;
-  justify-content: center;
-  z-index: 9999;
-  transition: all 0.3s ease;
-  font-size: 1.2rem;
-}
-
-.back-to-top-btn:hover {
-  background-color: #4a8fa3;
-  transform: translateY(-2px);
-}
-
-.fade-enter-active,
-.fade-leave-active {
-  transition:
-    opacity 0.3s ease,
-    transform 0.3s ease;
-}
-
-.fade-enter-from,
-.fade-leave-to {
-  opacity: 0;
-  transform: scale(0.85);
-}
-</style>
Index: serveNGo-frontend/src/PiniaStores/UserStore.js
===================================================================
--- ReserveNGo-frontend/src/PiniaStores/UserStore.js	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,92 +1,0 @@
-import { defineStore } from 'pinia'
-
-export const userStore = defineStore('userStore', {
-  state() {
-    return {
-      data: {
-        id: 0,
-        firstName: '',
-        lastName: '',
-        email: '',
-        phoneNumber: '',
-        role: 'UN_AUTHENTICATED',
-        token: null,
-        logoUrl: null,
-        profilePictureBase64Encoded: null,
-      },
-    }
-  },
-  actions: {
-    setLocalStorage(jsonObject) {
-      this.data = jsonObject
-      //this.data.profilePictureBase64Encoded =
-
-      if (this.data.logoUrl != null) {
-        this.setProfilePicturePathToLocalStorage(this.data.logoUrl)
-      }
-
-      localStorage.setItem('userData', JSON.stringify(jsonObject))
-    },
-    removeProfilePictureFromLocaleStorage() {
-      this.data.logoUrl = null
-      localStorage.setItem('userData', JSON.stringify(this.data))
-    },
-
-    setNewEditedDataToLocalStorage(jsonObject) {
-      const { firstName, lastName, phoneNumber } = jsonObject
-      this.data.firstName = firstName
-      this.data.lastName = lastName
-      this.data.phoneNumber = phoneNumber
-
-      localStorage.setItem('userData', JSON.stringify(this.data))
-    },
-    setNewEmailToLocalStorage(jsonObject) {
-      const { email, jwt } = jsonObject
-      this.data.email = email
-      this.data.token = jwt
-
-      localStorage.setItem('userData', JSON.stringify(this.data))
-    },
-    setProfilePicturePathToLocalStorage(profilePicturePath) {
-      this.data.logoUrl = profilePicturePath
-      localStorage.setItem('userData', JSON.stringify(this.data))
-    },
-    getLocalStorage() {
-      let nonparsed = localStorage.getItem('userData')
-      if (nonparsed !== null) {
-        this.data = JSON.parse(nonparsed)
-      }
-    },
-    clearLocalStorage() {
-      this.data = {
-        id: 0,
-        firstName: '',
-        lastName: '',
-        email: '',
-        phoneNumber: '',
-        role: 'UN_AUTHENTICATED',
-        token: null,
-        logoUrl: null,
-        profilePictureBase64Encoded: null,
-      }
-      localStorage.setItem('userData', JSON.stringify(this.data))
-    },
-  },
-  getters: {
-    getToken() {
-      return 'Bearer ' + this.data.token
-    },
-    isLocaleManager() {
-      return this.data.role === 'ROLE_LOCAL_MANAGER'
-    },
-    isLocaleWorker() {
-      return this.data.role === 'ROLE_LOCAL_WORKER'
-    },
-    isCustomer() {
-      return this.data.role === 'ROLE_CUSTOMER'
-    },
-    isAdmin() {
-      return this.data.role === 'ROLE_ADMIN'
-    },
-  },
-})
Index: serveNGo-frontend/src/PiniaStores/restaurantStore.js
===================================================================
--- ReserveNGo-frontend/src/PiniaStores/restaurantStore.js	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,68 +1,0 @@
-import { defineStore } from 'pinia'
-
-export const restaurantStore = defineStore('restaurantStore', {
-  state() {
-    return {
-      id: '',
-      name: '',
-      description: '',
-      address: '',
-      workingHours: '',
-      availableServices: [],
-      ratingAvg: 0,
-      events: [],
-      restaurantPhotos: [],
-      menuPhoto: '',
-      menuLink: '',
-      contact: '',
-      logo: '',
-    }
-  },
-  actions: {
-    setRestaurant(id, name, description, address, workingHours, logo, averageRating) {
-      this.id = id
-      this.name = name
-      this.description = description
-      this.address = address
-      this.workingHours = workingHours
-      this.logo = logo
-      this.ratingAvg = averageRating
-    },
-    setRestaurantDetails(
-      id,
-      name,
-      description,
-      address,
-      workingHours,
-      availableServices,
-      averageRating,
-      events,
-      restaurantPhotos,
-      menuPhoto,
-      menuLink,
-      contact,
-      logo,
-    ) {
-      this.id = id
-      this.name = name
-      this.description = description
-      this.address = address
-      this.workingHours = workingHours
-      this.availableServices = availableServices
-      this.ratingAvg = averageRating
-      this.events = events
-      this.restaurantPhotos = restaurantPhotos
-      this.menuPhoto = menuPhoto
-      this.menuLink = menuLink
-      this.contact = contact
-      this.logo = logo
-    },
-    newRestaurant(id) {
-      this.id = id
-    },
-    clearRestaurant() {
-      this.setRestaurant(null)
-    },
-  },
-  getters: {},
-})
Index: serveNGo-frontend/src/assets/main.css
===================================================================
--- ReserveNGo-frontend/src/assets/main.css	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,31 +1,0 @@
-/* src/assets/main.css */
-@import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap');
-
-html,
-body {
-    font-family: 'MyAwesomeFont', 'Inter', system-ui, -apple-system, BlinkMacSystemFont,
-    'Segoe UI', Roboto, sans-serif;
-}
-
-/* Force Vuetify to inherit your font */
-.v-application {
-    font-family: inherit !important;
-}
-
-@media print {
-    /* Hide header & footer */
-    nav.navbar,
-    footer {
-        display: none !important;
-    }
-
-    /* Hide any helper UI */
-    .no-print {
-        display: none !important;
-    }
-
-    /* Clean print background */
-    body {
-        background: #fff !important;
-    }
-}
Index: serveNGo-frontend/src/components/Project/Admin/AdminDashboard.vue
===================================================================
--- ReserveNGo-frontend/src/components/Project/Admin/AdminDashboard.vue	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,453 +1,0 @@
-<script>
-import { userStore } from '@/PiniaStores/UserStore.js'
-import { useToasts } from '@/composables/useToast.js'
-import { isValidEmail } from '@/utils/utilFunctions.js'
-import { useAdmin } from '@/repository/Admin.ts'
-import LoadingIcon from '@/components/Project/Utility/LoadingIcon.vue'
-import { config } from '@/constants/Api_config'
-import noImg from '@/assets/no-img.png'
-
-export default {
-  components: { LoadingIcon },
-  data() {
-    return {
-      restaurants: [],
-      managers: [],
-      managersForLocal: [],
-      sortKey: '',
-      sortOrder: 'asc',
-      name: '',
-      showAddRestaurantModal: false,
-      showAddManagerModal: false,
-      showEditRestaurantManagersModal: false,
-      selectedLocalId: null,
-      useUserStore: userStore(),
-      emailToManager: '',
-      showToast: useToasts().showToast,
-      isEmailSending: false,
-      isAddingRestaurant: false,
-      assigningManagerId: null,
-      removingManagerId: null,
-    }
-  },
-  computed: {
-    sortedRestaurants() {
-      if (!this.sortKey) return this.restaurants
-      return [...this.restaurants].sort((a, b) => {
-        let valueA = a[this.sortKey]
-        let valueB = b[this.sortKey]
-        if (this.sortKey === 'createdAt' || this.sortKey === 'modifiedAt') {
-          valueA = new Date(valueA)
-          valueB = new Date(valueB)
-        }
-        if (valueA < valueB) return this.sortOrder === 'asc' ? -1 : 1
-        if (valueA > valueB) return this.sortOrder === 'asc' ? 1 : -1
-        return 0
-      })
-    },
-  },
-  methods: {
-    onImageError(event) {
-      event.target.src = noImg
-    },
-    logoUrl(path) {
-      if (!path) return ''
-      try {
-        return new URL(path, config.API_BASE_URL).toString()
-      } catch {
-        return config.API_BASE_URL + path
-      }
-    },
-    sortBy(key) {
-      if (this.sortKey === key) {
-        this.sortOrder = this.sortOrder === 'asc' ? 'desc' : 'asc'
-      } else {
-        this.sortKey = key
-        this.sortOrder = 'asc'
-      }
-    },
-    formatDate(dateStr) {
-      const date = new Date(dateStr)
-      return date.toLocaleDateString() + ' ' + date.toLocaleTimeString()
-    },
-    async removeRestaurant(localId) {
-      if (
-        !confirm('Are you sure you want to delete this restaurant? This action cannot be undone.')
-      )
-        return
-
-      try {
-        await useAdmin.deleteRestaurant(localId)
-        this.showToast('Local successfully deleted!')
-        this.fetchRestaurants()
-      } catch (error) {
-        this.showToast(error.response || 'Failed to delete restaurant.', 'error')
-      }
-    },
-    fetchRestaurants() {
-      useAdmin
-        .fetchRestaurants()
-        .then((res) => (this.restaurants = res))
-        .catch((err) => console.log(err))
-    },
-    fetchManagers() {
-      useAdmin
-        .fetchLocalMangers()
-        .then((res) => (this.managers = res))
-        .catch((err) => console.log(err))
-    },
-    fetchManagersForRestaurant(localId) {
-      useAdmin
-        .fetchManagersForRestaurant(localId)
-        .then((res) => (this.managersForLocal = res))
-        .catch((err) => console.log(err))
-    },
-
-    async assignManager(localId, manager) {
-      this.assigningManagerId = manager.id
-      try {
-        await useAdmin.assignManager(localId, manager.id)
-        this.showToast(`Assigned ${manager.firstName} successfully.`, 'success')
-        this.fetchManagers()
-        this.fetchManagersForRestaurant(localId)
-      } catch (error) {
-        this.showToast(error.response || 'Failed to assign manager.', 'error')
-      } finally {
-        this.assigningManagerId = null
-      }
-    },
-
-    async removeManager(localId, manager) {
-      this.removingManagerId = manager.id
-      try {
-        await useAdmin.removeManager(manager.id)
-        this.showToast(`Removed ${manager.firstName} successfully.`, 'success')
-        this.fetchManagersForRestaurant(localId)
-      } catch (error) {
-        this.showToast(error.response || 'Failed to remove manager.', 'error')
-      } finally {
-        this.removingManagerId = null
-      }
-    },
-
-    async addRestaurant() {
-      this.isAddingRestaurant = true
-      try {
-        await useAdmin.addRestaurant(this.name)
-        this.showToast('Local added successfully!', 'success')
-        this.fetchRestaurants()
-        this.showAddRestaurantModal = false
-        this.name = ''
-      } catch (error) {
-        this.showToast(error.response || 'Failed to add restaurant.', 'error')
-      } finally {
-        this.isAddingRestaurant = false
-      }
-    },
-
-    openAddManagerModal(localId) {
-      this.selectedLocalId = localId
-      this.fetchManagers()
-      this.showAddManagerModal = true
-    },
-    openEditManagersModal(localId) {
-      this.selectedLocalId = localId
-      this.fetchManagersForRestaurant(localId)
-      this.showEditRestaurantManagersModal = true
-    },
-
-    async sendEmailToManager() {
-      if (this.emailToManager === '') {
-        this.showToast('Fill out the email form', 'error')
-        return
-      }
-      if (!isValidEmail(this.emailToManager)) {
-        this.showToast('Please enter a valid email format', 'error')
-        return
-      }
-      this.isEmailSending = true
-      try {
-        await useAdmin.inviteManager(this.emailToManager)
-        this.showToast(`Invite sent to ${this.emailToManager}`, 'success')
-        this.emailToManager = ''
-      } catch (error) {
-        this.showToast(error.response || 'Failed to send email.', 'error')
-      } finally {
-        this.isEmailSending = false
-      }
-    },
-  },
-  mounted() {
-    this.fetchRestaurants()
-  },
-}
-</script>
-
-<template>
-  <div class="container mt-4">
-    <h4 class="mb-3">Restaurants Overview</h4>
-    <hr>
-    <!-- Add Local Modal -->
-    <div
-      v-if="showAddRestaurantModal"
-      class="modal fade show d-block"
-      tabindex="-1"
-      style="background: rgba(0, 0, 0, 0.5)"
-    >
-      <div class="modal-dialog">
-        <div class="modal-content">
-          <div class="modal-header">
-            <h5 class="modal-title">Add New Restaurant</h5>
-            <button
-              type="button"
-              class="btn-close"
-              @click="showAddRestaurantModal = false"
-            ></button>
-          </div>
-          <div class="modal-body">
-            <form @submit.prevent="addRestaurant">
-              <div class="mb-3">
-                <label for="name" class="form-label">Restaurant Name</label>
-                <input
-                  v-model="name"
-                  type="text"
-                  id="name"
-                  class="form-control"
-                  placeholder="Enter restaurant name"
-                  required
-                />
-              </div>
-              <button type="submit" class="btn btn-primary" :disabled="isAddingRestaurant">
-                <LoadingIcon v-if="isAddingRestaurant" />
-                {{ isAddingRestaurant ? 'Adding...' : 'Add' }}
-              </button>
-            </form>
-          </div>
-        </div>
-      </div>
-    </div>
-
-    <!-- Add Manager Modal -->
-    <div
-      v-if="showAddManagerModal"
-      class="modal fade show d-block"
-      tabindex="-1"
-      style="background: rgba(0, 0, 0, 0.5)"
-    >
-      <div class="modal-dialog modal-lg">
-        <div class="modal-content">
-          <div class="modal-header">
-            <h5 class="modal-title">Assign Manager</h5>
-            <button type="button" class="btn-close" @click="showAddManagerModal = false"></button>
-          </div>
-          <div class="modal-body">
-            <ul class="list-group">
-              <li
-                v-for="manager in managers"
-                :key="manager.id"
-                class="list-group-item d-flex justify-content-between align-items-center"
-              >
-                <span>{{ manager.firstName }} {{ manager.lastName }} - {{ manager.email }}</span>
-                <button
-                  class="btn btn-sm btn-success"
-                  @click="assignManager(selectedLocalId, manager)"
-                  :disabled="assigningManagerId === manager.id"
-                >
-                  <LoadingIcon v-if="assigningManagerId === manager.id" />
-                  {{ assigningManagerId === manager.id ? 'Adding...' : 'Add' }}
-                </button>
-              </li>
-            </ul>
-          </div>
-        </div>
-      </div>
-    </div>
-
-    <!-- Edit Managers Modal -->
-    <div
-      v-if="showEditRestaurantManagersModal"
-      class="modal fade show d-block"
-      tabindex="-1"
-      style="background: rgba(0, 0, 0, 0.5)"
-    >
-      <div class="modal-dialog modal-lg">
-        <div class="modal-content">
-          <div class="modal-header">
-            <h5 class="modal-title">Restaurant Managers</h5>
-            <button
-              type="button"
-              class="btn-close"
-              @click="showEditRestaurantManagersModal = false"
-            ></button>
-          </div>
-          <div class="modal-body">
-            <ul class="list-group">
-              <li
-                v-for="manager in managersForLocal"
-                :key="manager.id"
-                class="list-group-item d-flex justify-content-between align-items-center"
-              >
-                <span>{{ manager.firstName }} {{ manager.lastName }} - {{ manager.email }}</span>
-                <button
-                  class="btn btn-sm btn-danger"
-                  @click="removeManager(selectedLocalId, manager)"
-                  :disabled="removingManagerId === manager.id"
-                >
-                  <LoadingIcon v-if="removingManagerId === manager.id" />
-                  {{ removingManagerId === manager.id ? 'Removing...' : 'Remove' }}
-                </button>
-              </li>
-            </ul>
-          </div>
-        </div>
-      </div>
-    </div>
-
-    <div class="table-responsive shadow-sm table-container">
-      <table class="table table-striped table-hover align-middle">
-        <thead class="table-light">
-          <tr>
-            <th style="width: 80px">Logo</th>
-            <th style="width: 200px; cursor: pointer" @click="sortBy('localName')">
-              Name<span v-if="sortKey === 'localName'">{{ sortOrder === 'asc' ? '↑' : '↓' }}</span>
-            </th>
-            <th style="width: 180px; cursor: pointer" @click="sortBy('createdAt')">
-              Created At<span v-if="sortKey === 'createdAt'">{{
-                sortOrder === 'asc' ? '↑' : '↓'
-              }}</span>
-            </th>
-            <th style="width: 180px; cursor: pointer" @click="sortBy('modifiedAt')">
-              Modified At<span v-if="sortKey === 'modifiedAt'">{{
-                sortOrder === 'asc' ? '↑' : '↓'
-              }}</span>
-            </th>
-            <th class="text-end" style="width: 220px">Actions</th>
-          </tr>
-        </thead>
-        <tbody>
-          <tr v-for="restaurant in sortedRestaurants" :key="restaurant.localId">
-            <td>
-              <img
-                v-if="restaurant.localLogo"
-                :src="logoUrl(restaurant.localLogo)"
-                alt="Logo"
-                class="img-thumbnail"
-                style="width: 40px; height: 40px; object-fit: cover"
-                @error="onImageError"
-              /><span v-else class="text-muted">No Logo</span>
-            </td>
-            <td class="text-truncate">{{ restaurant.localName }}</td>
-            <td>{{ formatDate(restaurant.createdAt) }}</td>
-            <td>{{ formatDate(restaurant.modifiedAt) }}</td>
-            <td class="text-end">
-              <div class="d-flex justify-content-end gap-2 flex-wrap">
-                <button
-                  class="btn btn-sm btn-primary"
-                  @click="openAddManagerModal(restaurant.localId)"
-                >
-                  Add Manager</button
-                ><button
-                  class="btn btn-sm btn-primary"
-                  @click="openEditManagersModal(restaurant.localId)"
-                >
-                  Edit Managers</button
-                ><button
-                  class="btn btn-sm btn-outline-danger"
-                  @click="removeRestaurant(restaurant.localId)"
-                >
-                  <i class="fas fa-trash-alt"></i> Delete restaurant
-                </button>
-              </div>
-            </td>
-          </tr>
-        </tbody>
-      </table>
-    </div>
-
-    <button class="btn btn-success mt-3" @click="showAddRestaurantModal = true">
-      + Add Restaurant
-    </button>
-    <div id="sendMailGroup" class="mt-3">
-      <button @click="sendEmailToManager" class="btn btn-success">
-        <LoadingIcon v-if="isEmailSending" />
-        <span v-else>+ </span>
-        Send Manager register mail
-      </button>
-      <input
-        v-model="emailToManager"
-        class="form-control"
-        type="text"
-        placeholder="Enter manager's email"
-      />
-    </div>
-  </div>
-</template>
-
-<style scoped>
-html,
-body {
-  margin: 0;
-  padding: 0;
-  height: 100vh;
-  overflow: hidden;
-}
-.container {
-  max-width: 1200px;
-  margin: 0 auto;
-  height: 100%;
-  display: flex;
-  flex-direction: column;
-  padding-bottom: 20px;
-  overflow: hidden;
-}
-.table-container {
-  flex: 1 1 auto;
-  overflow-y: auto;
-}
-table {
-  font-size: 0.95rem;
-  table-layout: fixed;
-  width: 100%;
-}
-th,
-td {
-  white-space: nowrap;
-  overflow: hidden;
-  text-overflow: ellipsis;
-}
-thead th {
-  position: sticky;
-  top: 0;
-  background-color: #f8f9fa;
-  z-index: 2;
-  user-select: none;
-}
-th span {
-  margin-left: 5px;
-  font-size: 0.8rem;
-}
-td img {
-  display: block;
-}
-.text-truncate {
-  overflow: hidden;
-  text-overflow: ellipsis;
-  white-space: nowrap;
-}
-.modal {
-  display: block;
-}
-#sendMailGroup {
-  display: flex;
-}
-#sendMailGroup > .btn {
-  flex-shrink: 0;
-  border-top-right-radius: 0;
-  border-bottom-right-radius: 0;
-}
-#sendMailGroup > .form-control {
-  flex-grow: 1;
-  border-top-left-radius: 0;
-  border-bottom-left-radius: 0;
-}
-</style>
Index: serveNGo-frontend/src/components/Project/Auth/DisabledAccountPage.vue
===================================================================
--- ReserveNGo-frontend/src/components/Project/Auth/DisabledAccountPage.vue	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,53 +1,0 @@
-<script lang="ts">
-import { defineComponent } from 'vue'
-import LoadingIcon from '@/components/Project/Utility/LoadingIcon.vue'
-
-export default defineComponent({
-  name: 'DisabledAccountPage',
-  components: { LoadingIcon },
-  emits: ['noThankYou', 'yesPlease'],
-  props: {
-    isLoading: {
-      type: Boolean,
-      required: true,
-    },
-  },
-
-  methods: {
-    noThankYou() {
-      this.$emit('noThankYou')
-    },
-    yesPlease() {
-      this.$emit('yesPlease')
-    },
-  },
-})
-</script>
-
-<template>
-  <div class="container-xxl d-flex justify-content-center mt-3">
-    <div class="card shadow p-4" style="max-width: 400px; width: 100%">
-      <h3 class="text-center mb-4">Your account was disabled</h3>
-
-      <p>
-        You have disabled your account.
-        <br />
-        In 30 days since you disabled your account the account will be deleted. If you want to
-        enable your account again please click "Yes" and you will be logged in and your account will
-        be enabled again.
-      </p>
-
-      <h4>Are you sure you want to enable your account?</h4>
-
-      <div style="display: flex; gap: 2rem">
-        <button @click="yesPlease" class="button-group btn btn-dark">
-          <span v-if="!isLoading">Yes, Please</span> <LoadingIcon v-else></LoadingIcon>
-        </button>
-
-        <button @click="noThankYou" class="button-group btn btn-dark">No, Thank you</button>
-      </div>
-    </div>
-  </div>
-</template>
-
-<style scoped></style>
Index: serveNGo-frontend/src/components/Project/Auth/login_.vue
===================================================================
--- ReserveNGo-frontend/src/components/Project/Auth/login_.vue	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,154 +1,0 @@
-<script lang="ts">
-import { userStore } from '@/PiniaStores/UserStore.js'
-import { useRouter } from 'vue-router'
-import LoadingIcon from '@/components/Project/Utility/LoadingIcon.vue'
-import { useAuth } from '@/repository/Authentication'
-import DisabledAccountPage from '@/components/Project/Auth/DisabledAccountPage.vue'
-import { useToasts } from '@/composables/useToast.js'
-import { GoogleLogin } from 'vue3-google-login'
-
-export default {
-  components: { DisabledAccountPage, LoadingIcon, GoogleLogin },
-  data() {
-    return {
-      form_info: {
-        email: '',
-        password: '',
-      },
-      userStore_: userStore(),
-      router: useRouter(),
-      managerLocalId: '',
-
-      isLoading: false,
-      isEnablingAccountLoading: false,
-      errorMessage: '',
-
-      disabledAccountPage: false,
-      showToast: useToasts().showToast,
-    }
-  },
-  computed: {
-    userDisabledAccountString() {
-      /*User with email: customer@gmail.com not found.*/
-      return `User is disabled`
-    },
-  },
-  methods: {
-    async makeLogin(isGoogleLogin = false, googleToken) {
-      this.isLoading = true
-
-      try {
-        const json = isGoogleLogin
-          ? await useAuth.makeGoogleLogin(googleToken)
-          : await useAuth.makeLogin(this.form_info.email, this.form_info.password)
-
-        console.log('Printing the json object to help me with profile picture.', json)
-
-        this.userStore_.setLocalStorage(json)
-
-        if (this.userStore_ && this.userStore_.data.role === 'ROLE_ADMIN') {
-          await this.router.push('/admin-dashboard')
-        } else if (this.userStore_ && this.userStore_.data.role === 'ROLE_LOCAL_MANAGER') {
-          await this.router.push('/manager-dashboard')
-        } else if (this.userStore_ && this.userStore_.data.role === 'ROLE_LOCAL_WORKER') {
-          await this.router.push('/worker-reservations-dashboard')
-        } else {
-          await this.router.push('/')
-        }
-      } catch (error) {
-        if (error.status === 401) {
-          this.errorMessage = 'Oops! That password seems to be incorrect.'
-        }
-        if (error.status === 500 && this.userDisabledAccountString === error.response) {
-          this.disabledAccountPage = true
-        } else {
-          console.log('am i getting here')
-          console.error(error)
-          this.errorMessage = error.response || 'Something went wrong'
-        }
-      } finally {
-        this.isLoading = false
-      }
-    },
-    async googleLoginCallback(response) {
-      try {
-        const googleToken = response?.credential
-        if (!googleToken) {
-          this.errorMessage = 'Google login failed to provide a token.'
-          this.showToast(this.errorMessage, 'error')
-          return
-        }
-        await this.makeLogin(true, googleToken)
-      } catch (err) {
-        console.error('Google login error', err)
-        const message = err?.response || 'Google login failed.'
-        this.errorMessage = message
-        this.showToast(message, 'error')
-      }
-    },
-    async reEnableAccount() {
-      this.isEnablingAccountLoading = true
-      try {
-        await useAuth.reEnableAccount(this.form_info.email, this.form_info.password)
-        await this.makeLogin()
-        this.showToast('Your account was successfully enabled.')
-      } catch (error) {
-        this.disabledAccountPage = false
-        this.showToast(error.response || 'Something went wrong, try again later', 'error')
-      } finally {
-        this.isEnablingAccountLoading = false
-      }
-    },
-  },
-}
-</script>
-
-<template>
-  <div class="container-xxl d-flex justify-content-center mt-3">
-    <div v-if="!disabledAccountPage" class="card shadow p-4" style="max-width: 400px; width: 100%">
-      <h3 class="text-center mb-4">Login</h3>
-      <form @submit.prevent="makeLogin(false, null)">
-        <div class="mb-3">
-          <label for="email" class="form-label">Email address</label>
-          <input
-            v-model="form_info.email"
-            type="text"
-            class="form-control"
-            id="email"
-            placeholder="Enter your email"
-            required
-          />
-        </div>
-
-        <div class="mb-3">
-          <label for="password" class="form-label">Password</label>
-          <input
-            v-model="form_info.password"
-            type="password"
-            class="form-control"
-            id="password"
-            placeholder="Enter your password"
-            required
-          />
-        </div>
-        <div style="color: red; margin-bottom: 1rem">{{ errorMessage }}</div>
-
-        <button :disabled="isLoading" type="submit" class="btn btn-dark w-100">
-          <span v-if="!isLoading">Login</span>
-          <LoadingIcon v-else></LoadingIcon>
-        </button>
-      </form>
-      <div class="mt-3 d-grid">
-        <GoogleLogin :callback="googleLoginCallback" />
-      </div>
-    </div>
-    <DisabledAccountPage
-      :is-loading="isEnablingAccountLoading"
-      @yesPlease="reEnableAccount"
-      @noThankYou="disabledAccountPage = false"
-      v-else
-    ></DisabledAccountPage>
-  </div>
-</template>
-
-<style scoped></style>
Index: serveNGo-frontend/src/components/Project/Auth/logout_.vue
===================================================================
--- ReserveNGo-frontend/src/components/Project/Auth/logout_.vue	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,30 +1,0 @@
-<script>
-import { userStore } from '@/PiniaStores/UserStore.js'
-import { useRouter } from 'vue-router'
-import { restaurantStore } from '@/PiniaStores/restaurantStore.js'
-
-export default {
-  data() {
-    return {
-      userStore_: userStore(),
-      router: useRouter(),
-      restaurantStore_: restaurantStore(),
-    }
-  },
-}
-</script>
-
-<template>
-  <a
-    v-on:click="
-      userStore_.clearLocalStorage();
-      restaurantStore_.clearRestaurant();
-    "
-    @click="router.push('/')"
-    v-if="userStore_.data.role !== 'UN_AUTHENTICATED'"
-    class="btn btn-dark"
-    >Logout</a
-  >
-</template>
-
-<style scoped></style>
Index: serveNGo-frontend/src/components/Project/Auth/register_.vue
===================================================================
--- ReserveNGo-frontend/src/components/Project/Auth/register_.vue	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,297 +1,0 @@
-<script>
-import { userStore } from '@/PiniaStores/UserStore.js'
-import { useRouter } from 'vue-router'
-import router from '@/router/index.js'
-import LoadingIcon from '@/components/Project/Utility/LoadingIcon.vue'
-import { useAuth } from '@/repository/Authentication.ts'
-import { useToasts } from '@/composables/useToast.js'
-import OtpInput from 'vue3-otp-input'
-import { GoogleLogin } from 'vue3-google-login'
-
-export default {
-  components: { LoadingIcon, OtpInput, GoogleLogin },
-  data() {
-    return {
-      path: '',
-      form_info: {
-        firstName: '',
-        lastName: '',
-        email: '',
-        password: '',
-        phoneNumber: '',
-      },
-      userStore_: userStore(),
-      router: useRouter(),
-
-      isLoading: false,
-      errorMessage: '',
-      showToast: useToasts().showToast,
-      // verification flow
-      registrationSucceeded: false,
-      otpCode: '',
-    }
-  },
-  methods: {
-    async register() {
-      localStorage.setItem('userEmail', this.form_info.email)
-      this.isLoading = true
-      await useAuth
-        .makeRegister(
-          this.form_info.firstName,
-          this.form_info.lastName,
-          this.form_info.email,
-          this.form_info.phoneNumber,
-          this.form_info.password,
-          this.roleType,
-          this.tokenRegister,
-        )
-        .then(() => {
-          if (this.roleType === 'local-manager' || this.roleType === 'local-worker') {
-            router.push('/login')
-            this.showToast('Successfully registered business account')
-          } else {
-            this.showToast(
-              'Successfully registered user account. Please check your email for the 6-digit verification code.',
-            )
-            // Show verification UI instead of redirecting
-            this.registrationSucceeded = true
-          }
-        })
-        .catch((err) => {
-          if (err.status === 409) {
-            this.errorMessage =
-              'It looks like an account already exists with that email address. Do you want to log in instead?'
-          } else {
-            this.errorMessage = err.response || 'Something Went wrong'
-          }
-        })
-        .finally(() => {
-          this.isLoading = false
-        })
-    },
-    async verifyAccount() {
-      if (!this.otpCode || this.otpCode.length !== 6) {
-        this.errorMessage = 'Please enter the 6-digit verification code sent to your email.'
-        return
-      }
-      this.isLoading = true
-      this.errorMessage = ''
-      try {
-        await useAuth.verifyAccount(this.form_info.email, this.otpCode)
-        localStorage.removeItem('userEmail')
-        this.showToast('Your account has been verified. You can now log in.')
-        await router.push('/login')
-      } catch (err) {
-        if (err?.response?.status === 400 || err?.response?.status === 404) {
-          this.errorMessage = 'Invalid or expired verification code. Please try again.'
-        } else {
-          this.errorMessage =
-            err?.response?.data?.message || 'Verification failed. Please try again.'
-        }
-      } finally {
-        this.isLoading = false
-      }
-    },
-    async googleRegisterCallback(response) {
-      console.log('Google login response', response.credential)
-      try {
-        const googleToken = response?.credential
-        if (!googleToken) {
-          this.errorMessage = 'Google login failed to provide a token.'
-          const { showToast } = useToasts()
-          showToast(this.errorMessage, 'error')
-          return
-        }
-        this.isLoading = true
-        this.errorMessage = ''
-        await useAuth.googleRegister(this.roleType, googleToken, this.tokenRegister)
-        this.showToast('Successfully registered with Google. You can now log in.', 'success')
-        await router.push('/login')
-      } catch (err) {
-        console.error('Google register error', err)
-        const message =
-          err?.response || err?.response?.data?.message || 'Google registration failed.'
-        this.errorMessage = message
-        const { showToast } = useToasts()
-        showToast(message, 'error')
-      } finally {
-        this.isLoading = false
-      }
-    },
-  },
-  computed: {
-    tokenRegister() {
-      return this.$route.query.token || null
-    },
-    roleType() {
-      if (this.$route.params.userType) return `local-${this.$route.params.userType}`
-      //local-manager
-      else {
-        return 'customer'
-      }
-    },
-  },
-  beforeMount() {
-    const otpcode = this.$route.query.code
-    if (otpcode) {
-      this.registrationSucceeded = true
-      this.otpCode = otpcode
-      this.isLoading = true
-      this.form_info.email = localStorage.getItem('userEmail')
-      setTimeout(() => {
-        this.isLoading = false
-        this.verifyAccount()
-      }, 2000)
-    }
-  },
-}
-</script>
-
-<template>
-  <div class="register-page-wrapper d-flex flex-column h-100">
-    <div class="flex-grow-1 overflow-auto">
-      <div class="container py-4">
-        <div class="row justify-content-center">
-          <div class="col-md-6 col-lg-5">
-            <div class="card shadow-sm border-0">
-              <div class="card-body p-4">
-                <h3 class="mb-4 text-center">Register {{ roleType }}</h3>
-                <form v-if="!registrationSucceeded" @submit.prevent="register" method="POST">
-                  <div class="mb-3">
-                    <label for="name" class="form-label">First Name</label>
-                    <input
-                      v-model="form_info.firstName"
-                      type="text"
-                      id="name"
-                      name="firstName"
-                      class="form-control"
-                      placeholder="Enter your first name"
-                      required
-                    />
-                  </div>
-
-                  <div class="mb-3">
-                    <label for="surname" class="form-label">Last Name</label>
-                    <input
-                      v-model="form_info.lastName"
-                      type="text"
-                      id="surname"
-                      name="lastName"
-                      class="form-control"
-                      placeholder="Enter your last name"
-                      required
-                    />
-                  </div>
-
-                  <div class="mb-3">
-                    <label for="phone_number" class="form-label">Phone Number</label>
-                    <input
-                      v-model="form_info.phoneNumber"
-                      type="text"
-                      id="phone_number"
-                      name="phoneNumber"
-                      class="form-control"
-                      placeholder="e.g., +38912345678"
-                      required
-                    />
-                  </div>
-
-                  <div class="mb-3">
-                    <label for="email" class="form-label">Email Address</label>
-                    <input
-                      v-model="form_info.email"
-                      type="email"
-                      id="email"
-                      name="email"
-                      class="form-control"
-                      placeholder="someone@example.com"
-                      required
-                    />
-                  </div>
-
-                  <div class="mb-3">
-                    <label for="password" class="form-label">Password</label>
-                    <input
-                      v-model="form_info.password"
-                      type="password"
-                      id="password"
-                      name="password"
-                      class="form-control"
-                      placeholder="Enter a strong password"
-                      required
-                    />
-                  </div>
-                  <div style="color: red">{{ errorMessage }}</div>
-                  <div class="d-grid">
-                    <button :disabled="isLoading" type="submit" class="btn btn-dark">
-                      <span v-if="!isLoading">Register</span>
-                      <LoadingIcon v-else></LoadingIcon>
-                    </button>
-                  </div>
-                  <div class="mt-3 d-grid">
-                    <GoogleLogin :callback="googleRegisterCallback"></GoogleLogin>
-                  </div>
-                </form>
-                <div v-else>
-                  <div class="alert alert-info" role="alert">
-                    We have sent a 6-digit verification code to
-                    <strong>{{ form_info.email }}</strong
-                    >. Enter it below to verify your account.
-                  </div>
-                  <div class="mb-3 d-flex justify-content-center">
-                    <OtpInput
-                      v-model:value="otpCode"
-                      :num-inputs="6"
-                      input-classes="otp-input"
-                      :should-auto-focus="true"
-                      :is-input-num="true"
-                    />
-                  </div>
-                  <div style="color: red" class="mb-2">{{ errorMessage }}</div>
-                  <div class="d-grid">
-                    <button
-                      :disabled="isLoading || otpCode.length !== 6"
-                      @click="verifyAccount"
-                      class="btn btn-success"
-                    >
-                      <span v-if="!isLoading">Verify</span>
-                      <LoadingIcon v-else></LoadingIcon>
-                    </button>
-                  </div>
-                  <div class="text-center mt-3">
-                    <router-link to="/login">Back to Login</router-link>
-                  </div>
-                </div>
-              </div>
-            </div>
-          </div>
-        </div>
-      </div>
-    </div>
-  </div>
-</template>
-
-<style scoped>
-html,
-body,
-.register-page-wrapper {
-  height: 100%;
-  overflow: hidden;
-}
-
-.flex-grow-1 {
-  min-height: 0; /* Necessary for flexbox scroll containers */
-}
-</style>
-
-<style>
-.otp-input {
-  width: 42px;
-  height: 48px;
-  margin: 0 4px;
-  text-align: center;
-  font-size: 20px;
-  border: 1px solid #ced4da;
-  border-radius: 6px;
-}
-</style>
Index: serveNGo-frontend/src/components/Project/Bars/FooterBar.vue
===================================================================
--- ReserveNGo-frontend/src/components/Project/Bars/FooterBar.vue	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,87 +1,0 @@
-<script setup lang="ts">
-const year = new Date().getFullYear()
-</script>
-
-<template>
-  <footer class="footer">
-    <div class="container py-4">
-      <div class="row align-items-center">
-        <!-- Brand -->
-        <div
-          class="col-md-4 d-flex align-items-center justify-content-center justify-content-md-start mb-3 mb-md-0"
-        >
-          <img
-            src="/src/assets/rng_logo.png"
-            alt="ReserveNGo logo"
-            class="me-3"
-            style="height: 48px"
-          />
-          <div>
-            <div class="brand-name">Reserve<span class="brand-n">N</span>Go</div>
-            <small class="brand-tagline"> Reservations made simple </small>
-          </div>
-        </div>
-
-        <!-- Center links -->
-        <div class="col-md-4 text-center mb-3 mb-md-0">
-          <router-link to="/about-us" class="footer-link"> About us </router-link>
-          <span class="separator">·</span>
-          <router-link to="/contact" class="footer-link"> Contact </router-link>
-          <span class="separator">·</span>
-          <router-link to="/privacy-policy" class="footer-link"> Privacy policy </router-link>
-        </div>
-
-        <!-- Copyright -->
-        <div class="col-md-4 text-center text-md-end">
-          <small class="copyright"> © {{ year }} ReserveNGo. All rights reserved.</small>
-        </div>
-      </div>
-    </div>
-  </footer>
-</template>
-
-<style scoped>
-.footer {
-  background-color: #4c8fa3;
-}
-
-/* Brand */
-.brand-name {
-  font-weight: 700;
-  font-size: 1.25rem;
-  color: #ffffff;
-  letter-spacing: 1px;
-}
-
-.brand-n {
-  color: #f55845;
-}
-
-.brand-tagline {
-  color: rgba(255, 255, 255, 0.75);
-  font-size: 0.85rem;
-}
-
-/* Links */
-.footer-link {
-  color: #ffffff;
-  font-weight: 500;
-  text-decoration: none;
-}
-
-.footer-link:hover {
-  text-decoration: underline;
-  opacity: 0.85;
-}
-
-.separator {
-  margin: 0 10px;
-  color: rgba(255, 255, 255, 0.6);
-}
-
-/* Copyright */
-.copyright {
-  font-size: 0.8rem;
-  color: rgba(255, 255, 255, 0.6);
-}
-</style>
Index: serveNGo-frontend/src/components/Project/Bars/HeaderNavigationBar.vue
===================================================================
--- ReserveNGo-frontend/src/components/Project/Bars/HeaderNavigationBar.vue	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,239 +1,0 @@
-<script>
-import { userStore } from '@/PiniaStores/UserStore.js'
-import logout_ from '@/components/Project/Auth/logout_.vue'
-import { useLocalManager } from '@/repository/LocalManager.ts'
-
-export default {
-  components: {
-    logout_,
-  },
-  data() {
-    return {
-      user: userStore(),
-      managerLocalId: '',
-    }
-  },
-  methods: {
-    fetchLocalForManager() {
-      useLocalManager
-        .getMyLocal()
-        .then((data) => {
-          this.managerLocalId = data.id
-        })
-        .catch(() => {
-          this.managerLocalId = ''
-        })
-    },
-  },
-  mounted() {
-    if (this.user?.data?.role === 'ROLE_LOCAL_MANAGER') {
-      this.fetchLocalForManager()
-    }
-  },
-  watch: {
-    '$route.path'() {
-      if (this.user?.data?.role === 'ROLE_LOCAL_MANAGER') {
-        this.fetchLocalForManager()
-      }
-    },
-  },
-  computed: {
-    isFavouritesActive() {
-      return this.$route.path === '/' && this.$route.query.mode === 'favourites'
-    },
-    isReservationsActive() {
-      return this.$route.path === '/my_reservations'
-    },
-    isAdminDashboardActive() {
-      return this.$route.path === '/admin-dashboard'
-    },
-    isManagerDashboardActive() {
-      return this.$route.path === '/manager-dashboard'
-    },
-    isMyLocalActive() {
-      return this.$route.path === `/more_details/${this.managerLocalId}`
-    },
-    isWorkerDashboardActive() {
-      return this.$route.path === '/worker-reservations-dashboard'
-    },
-  },
-}
-</script>
-
-<template>
-  <nav class="navbar navbar-expand-lg navbar-dark custom-background-nav py-1 px-5">
-    <div class="container-fluid">
-      <router-link
-        v-if="user.data.role !== 'ROLE_LOCAL_MANAGER' && user.data.role !== 'ROLE_LOCAL_WORKER'"
-        to="/"
-        class="navbar-brand d-flex align-items-center"
-      >
-        <img src="/src/assets/rng_logo.png" alt="Logo" class="me-2" style="height: 60px" />
-        <span class="navbar-brand fw-bold fs-3 brand-accent">
-          Reserve<span class="brand-n fs-3">N</span>Go
-        </span>
-      </router-link>
-
-      <div v-else class="navbar-brand d-flex align-items-center">
-        <img src="/src/assets/rng_logo.png" alt="Logo" class="me-2" style="height: 60px" />
-        <span class="navbar-brand fw-bold fs-3 brand-accent">
-          Reserve<span class="brand-n fs-3">N</span>Go
-        </span>
-      </div>
-
-      <button
-        class="navbar-toggler"
-        type="button"
-        data-bs-toggle="collapse"
-        data-bs-target="#navbarContent"
-        aria-controls="navbarContent"
-        aria-expanded="false"
-        aria-label="Toggle navigation"
-      >
-        <span class="navbar-toggler-icon"></span>
-      </button>
-
-      <div class="collapse navbar-collapse justify-content-end" id="navbarContent">
-        <ul class="navbar-nav align-items-center">
-          <li class="nav-item pe-3" v-if="user.data.role === 'ROLE_CUSTOMER'">
-            <router-link
-              :to="{ path: '/', query: { mode: 'favourites' } }"
-              class="nav-link"
-              :class="{
-                'text-white': !isFavouritesActive,
-                'link-active': isFavouritesActive,
-                'fw-bold': true,
-              }"
-            >
-              Favourites
-            </router-link>
-          </li>
-
-          <li class="nav-item pe-3" v-if="user.data.role === 'ROLE_CUSTOMER'">
-            <router-link
-              to="/my_reservations"
-              class="nav-link"
-              :class="{
-                'text-white': !isReservationsActive,
-                'link-active': isReservationsActive,
-                'fw-bold': true,
-              }"
-            >
-              Reservations
-            </router-link>
-          </li>
-
-          <li class="nav-item pe-3" v-if="user.data.role === 'ROLE_ADMIN'">
-            <router-link
-              to="/admin-dashboard"
-              class="nav-link"
-              :class="{
-                'text-white': !isAdminDashboardActive,
-                'link-active': isAdminDashboardActive,
-                'fw-bold': true,
-              }"
-            >
-              Dashboard</router-link
-            >
-          </li>
-
-          <li class="nav-item pe-3" v-if="user.data.role === 'ROLE_LOCAL_MANAGER'">
-            <router-link
-              :to="managerLocalId ? `/more_details/${managerLocalId}` : '/local-not-assigned'"
-              class="nav-link"
-              :class="{
-                'text-white': !isMyLocalActive,
-                'link-active': isMyLocalActive,
-                'fw-bold': true,
-              }"
-            >
-              My Local
-            </router-link>
-          </li>
-
-          <li class="nav-item pe-3" v-if="user.data.role === 'ROLE_LOCAL_MANAGER'">
-            <router-link
-              to="/manager-dashboard"
-              class="nav-link"
-              :class="{
-                'text-white': !isManagerDashboardActive,
-                'link-active': isManagerDashboardActive,
-                'fw-bold': true,
-              }"
-            >
-              Dashboard</router-link
-            >
-          </li>
-
-          <li class="nav-item pe-3" v-if="user.data.role === 'ROLE_LOCAL_WORKER'">
-            <router-link
-              to="/worker-reservations-dashboard"
-              class="nav-link"
-              :class="{
-                'text-white': !isWorkerDashboardActive,
-                'link-active': isWorkerDashboardActive,
-                'fw-bold': true,
-              }"
-            >
-              Dashboard</router-link
-            >
-          </li>
-
-          <li
-            class="nav-item"
-            v-if="user.data.role !== 'ROLE_ADMIN' && user.data.role !== 'UN_AUTHENTICATED'"
-          >
-            <router-link to="/profilePage" class="nav-link text-white">
-              <i class="fa-solid fa-user"></i>
-              {{ user.data.firstName }} {{ user.data.lastName }}
-            </router-link>
-          </li>
-
-          <li class="nav-item" v-if="user.data.role === 'UN_AUTHENTICATED'">
-            <router-link to="/login" class="btn btn-dark me-2">Login</router-link>
-          </li>
-
-          <li class="nav-item" v-if="user.data.role === 'UN_AUTHENTICATED'">
-            <router-link to="/register" class="btn btn-dark me-2">Register</router-link>
-          </li>
-
-          <li class="nav-item">
-            <logout_ />
-          </li>
-        </ul>
-      </div>
-    </div>
-  </nav>
-</template>
-
-<style scoped>
-.navbar-brand span {
-  font-size: 1.25rem;
-}
-
-.custom-background-nav {
-  background-color: #5ea5bc;
-}
-
-.navbar-nav .nav-link:hover {
-  color: rgba(255, 255, 255, 0.6) !important;
-}
-
-.brand-accent {
-  letter-spacing: 1px;
-  padding-left: 5px;
-  color: #fff;
-}
-
-.brand-n {
-  color: #f55845;
-}
-
-.link-active {
-  color: #f55845 !important;
-}
-
-.nav-item {
-  margin-bottom: 2px;
-}
-</style>
Index: serveNGo-frontend/src/components/Project/Customer/EditReservationModal.vue
===================================================================
--- ReserveNGo-frontend/src/components/Project/Customer/EditReservationModal.vue	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,154 +1,0 @@
-<script setup>
-import { ref, computed, onBeforeMount } from 'vue'
-import BaseModal from '@/components/Project/Utility/GeneralModal.vue'
-import { useReservations } from '@/repository/Reservations.ts'
-import { useToasts } from '@/composables/useToast.js'
-
-/** @typedef {import('@/repository/Reservations.ts').DisplayReservationDTO} DisplayReservationDTO */
-
-const props = defineProps({
-  showModal: Boolean,
-  /** @type {DisplayReservationDTO|null} */
-  reservation: {
-    type: Object,
-    default: null,
-  },
-})
-
-const emit = defineEmits(['closeModal', 'edited'])
-
-const { showToast } = useToasts()
-
-const timeOfReservation = ref('')
-const capacity = ref(null)
-const description = ref('')
-const loading = ref(false)
-const submitting = ref(false)
-
-function normalizeDateTime(dt) {
-  if (!dt) return ''
-  return dt.length === 16 ? dt + ':00' : dt
-}
-
-const canSubmit = computed(() => {
-  return !!props.reservation.id && !!timeOfReservation.value
-})
-
-async function submitEdit() {
-  if (!canSubmit.value || submitting.value) return
-  try {
-    submitting.value = true
-    const payload = {
-      timeOfReservation: normalizeDateTime(timeOfReservation.value),
-      capacity: capacity.value,
-      description: description.value,
-    }
-    const res = await useReservations.editReservation(props.reservation.id, payload)
-    showToast('Reservation updated successfully.', 'success')
-    emit('edited', res)
-    emit('closeModal')
-  } catch (err) {
-    console.error(err)
-    const message = err?.response?.message || 'Failed to update reservation.'
-    showToast(message, 'error')
-  } finally {
-    submitting.value = false
-  }
-}
-onBeforeMount(async () => {
-  if (!props.reservation?.id) return
-
-  try {
-    loading.value = true
-
-    const data = await useReservations.getReservationDetails(props.reservation.id)
-
-    timeOfReservation.value = data.timeOfReservation
-      ? data.timeOfReservation.slice(0, 16) // required for datetime-local
-      : ''
-
-    capacity.value = data.capacity ?? null
-    description.value = data.description ?? ''
-  } catch (err) {
-    console.error(err)
-    showToast('Failed to load reservation details.', 'error')
-  } finally {
-    loading.value = false
-  }
-})
-</script>
-
-<template>
-  <BaseModal :show="props.showModal" @close="emit('closeModal')">
-    <h2 style="margin-bottom: 1rem">Edit reservation</h2>
-
-    <div v-if="loading">Loading...</div>
-    <div v-else class="form-grid">
-      <label class="form-row">
-        <span>Date and time</span>
-        <input type="datetime-local" v-model="timeOfReservation" />
-      </label>
-      <label class="form-row">
-        <span>Reservation for how many people?</span>
-        <input type="number" min="1" placeholder="eg. 4" v-model="capacity" />
-      </label>
-      <label class="form-row">
-        <span>Additional comments (optional)</span>
-        <input type="text" placeholder="eg. Outside table" v-model="description" />
-      </label>
-    </div>
-
-    <div class="actions">
-      <button class="btn-outline" @click="emit('closeModal')">Close</button>
-      <button class="btn-primary" :disabled="!canSubmit || submitting" @click="submitEdit">
-        {{ submitting ? 'Saving...' : 'Save changes' }}
-      </button>
-    </div>
-  </BaseModal>
-</template>
-
-<style scoped>
-.form-grid {
-  display: grid;
-  grid-template-columns: 1fr;
-  gap: 1rem;
-}
-.form-row {
-  display: flex;
-  flex-direction: column;
-  gap: 0.35rem;
-}
-.actions {
-  display: flex;
-  justify-content: flex-end;
-  gap: 0.75rem;
-  margin-top: 1rem;
-}
-.btn-primary {
-  background: #2b6cb0;
-  color: #fff;
-  border: none;
-  padding: 0.5rem 1rem;
-  border-radius: 6px;
-  cursor: pointer;
-}
-.btn-primary:disabled {
-  opacity: 0.6;
-  cursor: not-allowed;
-}
-.btn-outline {
-  background: transparent;
-  color: #333;
-  border: 1px solid #ccc;
-  padding: 0.5rem 1rem;
-  border-radius: 6px;
-  cursor: pointer;
-}
-
-select,
-input[type='datetime-local'] {
-  padding: 0.45rem 0.5rem;
-  border: 1px solid #cbd5e1;
-  border-radius: 6px;
-}
-</style>
Index: serveNGo-frontend/src/components/Project/Customer/Profile_Page.vue
===================================================================
--- ReserveNGo-frontend/src/components/Project/Customer/Profile_Page.vue	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,454 +1,0 @@
-<script>
-import { userStore } from '@/PiniaStores/UserStore.js'
-import blankProfile from '@/components/ectd/blank-profile.webp'
-import { useToasts } from '@/composables/useToast.js'
-import { isValidEmail } from '@/utils/utilFunctions.js'
-import LoadingIcon from '@/components/Project/Utility/LoadingIcon.vue'
-import { useUser } from '@/repository/user.ts'
-import PopUpAlertIcon from '@/components/Project/Utility/PopUpAlertIcon.vue'
-import PopUpWindow from '@/components/Project/Utility/PopUpWindow.vue'
-import { config } from '@/constants/Api_config.js'
-
-export default {
-  components: { PopUpWindow, PopUpAlertIcon, LoadingIcon },
-  data() {
-    return {
-      userStore_: userStore(),
-      newPassword: '',
-      currentPassword: '',
-      profileData: {},
-      isProfileImageButtonDisabled: true,
-      profileImageSrc: null,
-      blankProfile: blankProfile,
-      showToast: useToasts().showToast,
-
-      isSavingDetails: false,
-      isUpdatingEmail: false,
-      isUpdatingPassword: false,
-      isUpdatingPicture: false,
-      isDisablingAccount: false,
-      disableAccountAreYouSurePrompt: false,
-
-      isHoveringAlert: false,
-      config: config,
-    }
-  },
-  methods: {
-    async updateProfileSettings() {
-      this.isSavingDetails = true
-      try {
-        const payload = {
-          firstName: this.profileData.firstName,
-          lastName: this.profileData.lastName,
-          phoneNumber: this.profileData.phoneNumber,
-        }
-        const updatedUser = await useUser.updateProfile(payload)
-        this.userStore_.setNewEditedDataToLocalStorage(updatedUser)
-        this.showToast('Profile details saved successfully!', 'success')
-      } catch (err) {
-        this.showToast(err.response || 'Failed to save details.', 'error')
-      } finally {
-        this.isSavingDetails = false
-      }
-    },
-    async updateEmail() {
-      if (!isValidEmail(this.profileData.email)) {
-        this.showToast('Please enter a valid email address.', 'error')
-        return
-      }
-      this.isUpdatingEmail = true
-      try {
-        const payload = { newEmail: this.profileData.email }
-        const updatedTokenData = await useUser.changeEmail(payload)
-        this.userStore_.setNewEmailToLocalStorage(updatedTokenData) // Assumes this updates the token with new email info
-        this.showToast(
-          'Email updated successfully! Please check your old email for confirmation.',
-          'success',
-        )
-      } catch (err) {
-        this.showToast(err.response || 'Failed to update email.', 'error')
-      } finally {
-        this.isUpdatingEmail = false
-      }
-    },
-    async updatePassword() {
-      this.isUpdatingPassword = true
-      try {
-        const payload = {
-          currentPassword: this.currentPassword,
-          newPassword: this.newPassword,
-        }
-        await useUser.changePassword(payload)
-        this.showToast('Password changed successfully.', 'success')
-        this.currentPassword = ''
-        this.newPassword = ''
-      } catch (err) {
-        this.showToast(err.response || 'Failed to change password.', 'error')
-      } finally {
-        this.isUpdatingPassword = false
-      }
-    },
-    async updateProfilePicture() {
-      const profilePictureFile = document.getElementById('profilePhotoInput').files[0]
-      if (!profilePictureFile) return
-
-      this.isUpdatingPicture = true
-      const formData = new FormData()
-      formData.append('avatar', profilePictureFile)
-
-      try {
-        const profileAvatarStringPath = await useUser.uploadAvatar(formData)
-        this.userStore_.setProfilePicturePathToLocalStorage(profileAvatarStringPath)
-        this.showToast('Profile picture updated!', 'success')
-      } catch (err) {
-        this.showToast(err.response || 'Profile picture upload failed.', 'error')
-      } finally {
-        this.isUpdatingPicture = false
-        this.isProfileImageButtonDisabled = true
-      }
-    },
-    async deleteProfilePicture() {
-      this.isUpdatingPicture = true
-      try {
-        await useUser.deleteAvatar()
-        this.userStore_.removeProfilePictureFromLocaleStorage()
-        this.showToast('Profile picture removed.', 'success')
-      } catch (err) {
-        this.showToast(err.response || 'Failed to remove profile picture.', 'error')
-      } finally {
-        this.isUpdatingPicture = false
-      }
-    },
-    async disableAccount() {
-      this.isDisablingAccount = true
-      try {
-        await useUser.disableUserAccount()
-        this.showToast(
-          'Account disabled successfully! You have 30 days to log in before its deletion.',
-          'success',
-        )
-        this.userStore_.clearLocalStorage()
-        this.$router.push('/login')
-      } catch (error) {
-        console.log(error)
-        this.showToast(error.response || 'Failed to disable account.', 'error')
-      } finally {
-        this.isDisablingAccount = false
-      }
-    },
-  },
-  async beforeMount() {
-    try {
-      this.profileData = await useUser.getProfile()
-    } catch (error) {
-      console.log('Error fetching profile settings', error)
-      this.showToast('Could not load your profile data.', 'error')
-    }
-  },
-  mounted() {
-    this.isProfileImageButtonDisabled = true
-    const profilePictureImage = document.getElementById('profilePictureModal')
-    const inputProfilePicture = document.getElementById('profilePhotoInput')
-
-    inputProfilePicture.addEventListener('change', (event) => {
-      this.isProfileImageButtonDisabled = false
-      const file = event.target.files[0]
-      if (file && file.type.startsWith('image/')) {
-        const reader = new FileReader()
-        reader.onload = (e) => {
-          profilePictureImage.src = e.target.result
-        }
-        reader.readAsDataURL(file)
-      }
-    })
-  },
-  computed: {
-    avatarURL() {
-      if (this.userStore_.data.logoUrl === null) {
-        return blankProfile
-      }
-      return this.config.API_BASE_URL + this.userStore_.data.logoUrl
-    },
-  },
-}
-</script>
-
-<template>
-  <div class="container my-5">
-    <div class="row justify-content-center">
-      <div class="col-md-8 col-lg-6">
-        <div class="card shadow-sm p-4">
-          <div class="d-flex align-items-center justify-content-center mb-4">
-            <div class="d-flex align-items-center justify-content-center">
-              <img
-                class="rounded-circle border me-3"
-                :src="avatarURL"
-                alt="Profile Picture"
-                width="100"
-                height="100"
-              />
-            </div>
-          </div>
-          <h4>{{ profileData.firstName }} {{ profileData.lastName }}</h4>
-          <p><strong>Email:</strong> {{ profileData.email }}</p>
-          <p><strong>Phone Number:</strong> {{ profileData.phoneNumber }}</p>
-          <button
-            type="button"
-            class="btn btn-dark btn-sm"
-            data-bs-toggle="modal"
-            data-bs-target="#editProfileModal"
-          >
-            Edit Profile
-          </button>
-        </div>
-      </div>
-    </div>
-
-    <!-- Modal -->
-    <div
-      class="modal fade"
-      id="editProfileModal"
-      tabindex="-1"
-      aria-labelledby="editProfileModalLabel"
-      aria-hidden="true"
-    >
-      <div class="modal-dialog modal-dialog-centered">
-        <div class="modal-content">
-          <div class="modal-header">
-            <h5 class="modal-title" id="editProfileModalLabel">Edit Profile</h5>
-            <button
-              type="button"
-              class="btn-close"
-              data-bs-dismiss="modal"
-              aria-label="Close"
-            ></button>
-          </div>
-          <div class="modal-body">
-            <!-- Profile Picture Section -->
-            <div class="d-flex justify-content-center">
-              <div class="position-relative">
-                <img
-                  id="profilePictureModal"
-                  class="rounded-circle border"
-                  :src="avatarURL"
-                  alt="Profile Picture"
-                  width="100"
-                  height="100"
-                />
-                <input
-                  type="file"
-                  id="profilePhotoInput"
-                  class="visually-hidden"
-                  accept="image/*"
-                />
-                <label
-                  for="profilePhotoInput"
-                  style="bottom: 0; right: 0.4rem; cursor: pointer"
-                  class="position-absolute rounded-full"
-                >
-                  <i style="font-size: 1.7rem" class="fa-solid fa-square-plus"></i>
-                </label>
-              </div>
-            </div>
-            <div class="d-flex justify-content-center">
-              <button
-                v-if="!userStore_.data.logoUrl"
-                @click="updateProfilePicture"
-                :disabled="isProfileImageButtonDisabled || isUpdatingPicture"
-                class="text-center btn btn-dark mb-3 mt-2"
-              >
-                <LoadingIcon v-if="isUpdatingPicture" />
-                Save Picture
-              </button>
-              <button
-                v-if="userStore_.data.logoUrl"
-                @click="deleteProfilePicture"
-                :disabled="isUpdatingPicture"
-                class="text-center btn btn-dark mb-3 mt-2"
-              >
-                <LoadingIcon v-if="isUpdatingPicture" />
-                Remove Picture
-              </button>
-            </div>
-
-            <!-- Personal Details Section -->
-            <h6>Personal Details</h6>
-            <div class="mb-3">
-              <label for="firstName" class="form-label">First Name</label>
-              <input
-                v-model="profileData.firstName"
-                type="text"
-                id="firstName"
-                class="form-control"
-                :placeholder="profileData.firstName"
-                :disabled="isSavingDetails"
-              />
-            </div>
-            <div class="mb-3">
-              <label for="lastName" class="form-label">Last Name</label>
-              <input
-                v-model="profileData.lastName"
-                type="text"
-                id="lastName"
-                class="form-control"
-                :placeholder="profileData.lastName"
-                :disabled="isSavingDetails"
-              />
-            </div>
-            <div class="mb-3">
-              <label for="phoneNumber" class="form-label">Phone Number</label>
-              <input
-                v-model="profileData.phoneNumber"
-                type="text"
-                id="phoneNumber"
-                class="form-control"
-                :placeholder="profileData.phoneNumber"
-                :disabled="isSavingDetails"
-              />
-            </div>
-            <button
-              @click="updateProfileSettings()"
-              type="button"
-              class="btn btn-dark w-100 mb-4"
-              :disabled="isSavingDetails"
-            >
-              <LoadingIcon v-if="isSavingDetails" />
-              {{ isSavingDetails ? 'Saving...' : 'Save Changes' }}
-            </button>
-
-            <!-- Change Email Section -->
-            <h6>Change Email</h6>
-            <div class="input-group mb-3">
-              <input
-                v-model="profileData.email"
-                type="text"
-                class="form-control"
-                placeholder="New Email"
-                :disabled="isUpdatingEmail"
-              />
-              <button
-                @click="updateEmail()"
-                type="button"
-                class="btn btn-secondary"
-                :disabled="isUpdatingEmail"
-              >
-                <LoadingIcon v-if="isUpdatingEmail" />
-                {{ isUpdatingEmail ? 'Updating...' : 'Update Email' }}
-              </button>
-            </div>
-
-            <!-- Change Password Section -->
-            <h6>Change Password</h6>
-            <div class="mb-2">
-              <label for="currentPassword" class="form-label">Current Password</label>
-              <input
-                v-model="currentPassword"
-                type="password"
-                id="currentPassword"
-                class="form-control"
-                :disabled="isUpdatingPassword"
-              />
-            </div>
-            <div class="mb-3">
-              <label for="newPassword" class="form-label">New Password</label>
-              <input
-                v-model="newPassword"
-                type="password"
-                id="newPassword"
-                class="form-control"
-                :disabled="isUpdatingPassword"
-              />
-            </div>
-            <button
-              @click="updatePassword()"
-              type="button"
-              class="btn btn-secondary w-100"
-              :disabled="isUpdatingPassword"
-            >
-              <LoadingIcon v-if="isUpdatingPassword" />
-              {{ isUpdatingPassword ? 'Changing...' : 'Change Password' }}
-            </button>
-
-            <h1 style="color: red">Danger Zone</h1>
-
-            <div
-              style="
-                font-weight: bold;
-                display: flex;
-                justify-content: space-between;
-                align-items: center;
-              "
-            >
-              <span
-                >Disable Account
-                <span
-                  @mouseleave="isHoveringAlert = false"
-                  @mouseenter="isHoveringAlert = true"
-                  style="position: relative"
-                >
-                  <PopUpAlertIcon></PopUpAlertIcon>
-                  <PopUpWindow :isHoveringAlert="isHoveringAlert"
-                    >Account will be disabled, it can be re-enabled after 30 days of disablement.
-                    After the 30 day period the account will be permanently deleted. You can
-                    re-enable your account by logging in again before the 30 day period expires.
-                  </PopUpWindow>
-                </span>
-              </span>
-
-              <button
-                v-if="!disableAccountAreYouSurePrompt"
-                @click="disableAccountAreYouSurePrompt = true"
-                class="custom-secondary-button"
-              >
-                Disable Account
-              </button>
-
-              <div v-else>
-                <p>Are you absolutely sure you want to disable your account ?</p>
-                <div style="display: flex; gap: 2rem">
-                  <button
-                    data-bs-dismiss="modal"
-                    @click="
-                      () => {
-                        disableAccount()
-                        disableAccountAreYouSurePrompt = false
-                      }
-                    "
-                    class="custom-secondary-button"
-                  >
-                    Yes
-                  </button>
-                  <button
-                    @click="disableAccountAreYouSurePrompt = false"
-                    class="custom-secondary-button"
-                  >
-                    No
-                  </button>
-                </div>
-              </div>
-            </div>
-            <p>
-              Account will be disabled, it can be re-enabled after 30 days of disablement. After the
-              30 day period the account will be permanently deleted. You can re-enable your account
-              by logging in again before the 30 day period expires.
-            </p>
-          </div>
-        </div>
-      </div>
-    </div>
-  </div>
-</template>
-
-<style scoped>
-.custom-secondary-button {
-  color: white;
-  background-color: #6c757d;
-  border: none;
-  padding: 8px 14px;
-  border-radius: 4px;
-}
-
-.custom-secondary-button:hover {
-  background-color: #5c636a;
-}
-</style>
Index: serveNGo-frontend/src/components/Project/Customer/RatingsForLocal.vue
===================================================================
--- ReserveNGo-frontend/src/components/Project/Customer/RatingsForLocal.vue	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,93 +1,0 @@
-<script>
-import { userStore } from '@/PiniaStores/UserStore.js'
-import { useCustomer } from '@/repository/Customer.ts'
-
-export default {
-  props: {
-    localId: String,
-  },
-  emits: ['rating-updated'],
-  data() {
-    return {
-      user: userStore(),
-      givenRating: 0,
-      rating: 0,
-      hoverRating: 0,
-    }
-  },
-  methods: {
-    rateLocal(rating) {
-      this.givenRating = rating
-      useCustomer
-        .rateLocal(this.localId, this.givenRating)
-        .then(() => {
-          this.customerRating()
-          this.$emit('rating-updated')
-        })
-        .catch((error) => console.log(error))
-    },
-    customerRating() {
-      useCustomer
-        .getRatingForLocal(this.localId)
-        .then((data) => {
-          this.rating = data.rating
-        })
-        .catch((error) => {
-          console.log(error)
-        })
-    },
-    removeRating() {
-      useCustomer
-        .removeRating(this.localId)
-        .then(() => {
-          this.rating = 0
-          this.givenRating = 0
-          this.$emit('rating-updated')
-        })
-        .catch((err) => console.log(err))
-    },
-  },
-  mounted() {
-    console.log('getting rating after mount')
-    this.customerRating()
-    console.log('rating is:' + this.rating)
-  },
-}
-</script>
-
-<template>
-  <div class="container">
-    <div v-if="rating === 0" class="d-flex align-items-center">
-      <h5 class="me-3 mb-0">Rate your experience:</h5>
-      <div @mouseleave="hoverRating = 0">
-        <span
-          v-for="index in 5"
-          :key="index"
-          @mouseover="hoverRating = index"
-          @click="rateLocal(index)"
-          class="fs-4"
-          style="cursor: pointer"
-        >
-          <i :class="['far', 'fa-star', { 'fas text-warning': hoverRating >= index }]"></i>
-        </span>
-      </div>
-    </div>
-    <div v-else class="d-flex align-items-center">
-      <h5 class="me-3 mb-0">Your Rating:</h5>
-      <div class="fs-4 text-warning">
-        <span v-for="index in 5" :key="index">
-          <i :class="['fa-star', { fas: index <= rating, far: index > rating }]"></i>
-        </span>
-      </div>
-      <button @click="removeRating" class="btn btn-danger btn-sm ms-3">
-        <i class="fas fa-times"></i> Remove Rating
-      </button>
-    </div>
-  </div>
-</template>
-
-<style scoped>
-.fs-4 {
-  font-size: 1.5rem;
-}
-</style>
Index: serveNGo-frontend/src/components/Project/Customer/makeReservationModal.vue
===================================================================
--- ReserveNGo-frontend/src/components/Project/Customer/makeReservationModal.vue	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,139 +1,0 @@
-<script setup>
-import { ref, computed } from 'vue'
-import BaseModal from '@/components/Project/Utility/GeneralModal.vue'
-import { useReservations } from '@/repository/Reservations.ts'
-import { useToasts } from '@/composables/useToast.js'
-
-const props = defineProps({
-  showModal: Boolean,
-  localId: [Number, String, Object],
-})
-
-const emit = defineEmits(['closeModal', 'openModal', 'reservationMade'])
-
-// Toasts
-const { showToast } = useToasts()
-
-// Form state
-const reservationDateTime = ref('')
-const capacity = ref(null)
-const description = ref('')
-const submitting = ref(false)
-const loadError = ref(null)
-
-function normalizeDateTime(dt) {
-  if (!dt) return ''
-  // if a format is YYYY-MM-DDTHH:mm, append :00 seconds
-  return dt.length === 16 ? dt + ':00' : dt
-}
-
-const canSubmit = computed(() => {
-  return !!props.localId && !!reservationDateTime.value
-})
-
-async function submitReservation() {
-  if (!canSubmit.value || submitting.value) return
-  try {
-    submitting.value = true
-    const payload = {
-      timeOfReservation: normalizeDateTime(reservationDateTime.value),
-      capacity: capacity.value,
-      description: description.value,
-    }
-    const res = await useReservations.makeReservation(payload, props.localId)
-    showToast('Reservation created successfully.', 'success')
-    emit('reservationMade', res)
-    emit('closeModal')
-    resetForm()
-  } catch (err) {
-    console.error(err)
-    const message = err?.response?.message || 'Failed to create reservation.'
-    showToast(message, 'error')
-  } finally {
-    submitting.value = false
-  }
-}
-
-function resetForm() {
-  reservationDateTime.value = ''
-  capacity.value = null
-  loadError.value = null
-}
-</script>
-
-<template>
-  <BaseModal :show="props.showModal" @close="emit('closeModal')">
-    <h2 style="margin-bottom: 1rem">Make a Reservation</h2>
-
-    <div class="form-grid">
-      <label class="form-row">
-        <span>Date and time</span>
-        <input type="datetime-local" v-model="reservationDateTime" :max="''" required />
-      </label>
-
-      <label class="form-row">
-        <span>Reservation for how many people?</span>
-        <input type="number" min="1" v-model.number="capacity" placeholder="eg. 4" />
-      </label>
-
-      <label class="form-row">
-        <span>Additional comments (optional)</span>
-        <input type="text" v-model.number="description" placeholder="eg. Outside table" />
-      </label>
-    </div>
-
-    <div class="actions">
-      <button class="btn-outline" @click="emit('closeModal')">Cancel</button>
-      <button class="btn-primary" :disabled="!canSubmit || submitting" @click="submitReservation">
-        {{ submitting ? 'Submitting...' : 'Reserve' }}
-      </button>
-    </div>
-  </BaseModal>
-</template>
-
-<style scoped>
-.form-grid {
-  display: grid;
-  grid-template-columns: 1fr;
-  gap: 1rem;
-}
-.form-row {
-  display: flex;
-  flex-direction: column;
-  gap: 0.35rem;
-}
-.actions {
-  display: flex;
-  justify-content: flex-end;
-  gap: 0.75rem;
-  margin-top: 1rem;
-}
-.btn-primary {
-  background: #2b6cb0;
-  color: #fff;
-  border: none;
-  padding: 0.5rem 1rem;
-  border-radius: 6px;
-  cursor: pointer;
-}
-.btn-primary:disabled {
-  opacity: 0.6;
-  cursor: not-allowed;
-}
-.btn-outline {
-  background: transparent;
-  color: #333;
-  border: 1px solid #ccc;
-  padding: 0.5rem 1rem;
-  border-radius: 6px;
-  cursor: pointer;
-}
-
-select,
-input[type='datetime-local'],
-input[type='number'] {
-  padding: 0.45rem 0.5rem;
-  border: 1px solid #cbd5e1;
-  border-radius: 6px;
-}
-</style>
Index: serveNGo-frontend/src/components/Project/Event/AddEventModal.vue
===================================================================
--- ReserveNGo-frontend/src/components/Project/Event/AddEventModal.vue	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,170 +1,0 @@
-<script>
-import { userStore } from '@/PiniaStores/UserStore.js'
-import { useLocalManager } from '@/repository/LocalManager.ts'
-import { useToasts } from '@/composables/useToast.js'
-import { getEnumOptions } from '@/utils/enumLabels' // enum helper
-
-export default {
-  props: {
-    show: {
-      type: Boolean,
-      required: true,
-    },
-  },
-  emits: ['close', 'event-added'],
-  data() {
-    return {
-      event: {
-        name: '',
-        description: '',
-        eventType: '', // sensible default (enum key)
-        eventStart: '',
-        eventEnd: '',
-      },
-      user: userStore(),
-      isLoading: false,
-      showToast: useToasts().showToast,
-    }
-  },
-  computed: {
-    eventTypeOptions() {
-      return getEnumOptions('EventType')
-    },
-  },
-  methods: {
-    close() {
-      this.$emit('close')
-    },
-    async addEvent() {
-      if (this.isLoading) return
-      this.isLoading = true
-
-      if (!this.event.name || !this.event.eventStart || !this.event.eventEnd) {
-        alert('Please fill in all required fields (Name, Start Date, End Date).')
-        this.isLoading = false
-        return
-      }
-
-      useLocalManager
-        .addEvent(this.event)
-        .then(() => {
-          this.$emit('event-added')
-          this.event = {
-            name: '',
-            description: '',
-            eventType: '',
-            eventStart: '',
-            eventEnd: '',
-          }
-          this.close()
-          this.showToast('Successfully added the event')
-        })
-        .catch((err) => {
-          this.showToast(err.response, 'error')
-        })
-        .finally(() => {
-          this.isLoading = false
-        })
-    },
-  },
-}
-</script>
-
-<template>
-  <!-- Modal Backdrop -->
-  <div v-if="show" class="modal-backdrop fade show"></div>
-
-  <!-- Modal -->
-  <div
-    v-if="show"
-    class="modal fade show"
-    style="display: block"
-    tabindex="-1"
-    aria-labelledby="addEventModalLabel"
-    aria-modal="true"
-    role="dialog"
-  >
-    <div class="modal-dialog modal-dialog-centered">
-      <div class="modal-content">
-        <form @submit.prevent="addEvent">
-          <div class="modal-header">
-            <h5 class="modal-title" id="addEventModalLabel">Add New Event</h5>
-            <button type="button" class="btn-close" @click="close" aria-label="Close"></button>
-          </div>
-          <div class="modal-body">
-            <!-- Event Name -->
-            <div class="mb-3">
-              <label for="eventName" class="form-label">Event Name</label>
-              <input
-                type="text"
-                class="form-control"
-                id="eventName"
-                v-model="event.name"
-                required
-              />
-            </div>
-
-            <!-- Event Description -->
-            <div class="mb-3">
-              <label for="eventDescription" class="form-label">Description</label>
-              <textarea
-                class="form-control"
-                id="eventDescription"
-                rows="3"
-                v-model="event.description"
-              ></textarea>
-            </div>
-
-            <!-- Event Type -->
-            <div class="mb-3">
-              <label for="eventType" class="form-label">Event Type</label>
-              <select class="form-select" id="eventType" v-model="event.eventType">
-                <option v-for="opt in eventTypeOptions" :key="opt.value" :value="opt.value">
-                  {{ opt.label }}
-                </option>
-              </select>
-            </div>
-
-            <!-- Event Start/End -->
-            <div class="row">
-              <div class="col-md-6 mb-3">
-                <label for="eventStart" class="form-label">Start Date & Time</label>
-                <input
-                  type="datetime-local"
-                  class="form-control"
-                  id="eventStart"
-                  v-model="event.eventStart"
-                  required
-                />
-              </div>
-              <div class="col-md-6 mb-3">
-                <label for="eventEnd" class="form-label">End Date & Time</label>
-                <input
-                  type="datetime-local"
-                  class="form-control"
-                  id="eventEnd"
-                  v-model="event.eventEnd"
-                  required
-                />
-              </div>
-            </div>
-          </div>
-          <div class="modal-footer">
-            <button type="button" class="btn btn-secondary" @click="close">Close</button>
-            <button type="submit" class="btn btn-primary" :disabled="isLoading">
-              <span
-                v-if="isLoading"
-                class="spinner-border spinner-border-sm"
-                role="status"
-                aria-hidden="true"
-              ></span>
-              {{ isLoading ? 'Saving...' : 'Save Event' }}
-            </button>
-          </div>
-        </form>
-      </div>
-    </div>
-  </div>
-</template>
-
-<style scoped></style>
Index: serveNGo-frontend/src/components/Project/Event/EditEventModal.vue
===================================================================
--- ReserveNGo-frontend/src/components/Project/Event/EditEventModal.vue	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,227 +1,0 @@
-<script>
-import { userStore } from '@/PiniaStores/UserStore.js'
-import { useLocalManager } from '@/repository/LocalManager.ts'
-import { useToasts } from '@/composables/useToast.js'
-import { getEnumOptions } from '@/utils/enumLabels' // enum helper
-
-export default {
-  props: {
-    show: {
-      type: Boolean,
-      required: true,
-    },
-    // Optional prop for the event to edit
-    eventToEdit: {
-      type: Object,
-      default: null,
-    },
-  },
-  emits: ['close', 'event-added', 'event-updated'],
-
-  data() {
-    return {
-      // local copy for the form
-      eventData: {},
-      user: userStore(),
-      isLoading: false,
-      showToast: useToasts().showToast,
-    }
-  },
-
-  computed: {
-    isEditMode() {
-      return !!this.eventToEdit
-    },
-    modalTitle() {
-      return this.isEditMode ? 'Edit Event' : 'Add New Event'
-    },
-    saveButtonText() {
-      if (this.isLoading) {
-        return this.isEditMode ? 'Updating...' : 'Saving...'
-      }
-      return this.isEditMode ? 'Update Event' : 'Save Event'
-    },
-    eventTypeOptions() {
-      return getEnumOptions('EventType')
-    },
-  },
-
-  watch: {
-    show(newVal) {
-      if (newVal) {
-        this.initializeForm()
-      }
-    },
-  },
-
-  methods: {
-    close() {
-      this.$emit('close')
-    },
-
-    initializeForm() {
-      if (this.isEditMode) {
-        this.eventData = JSON.parse(JSON.stringify(this.eventToEdit))
-        // ensure eventType has a sane default if missing
-        if (!this.eventData.eventType) {
-          this.eventData.eventType = ''
-        }
-      } else {
-        this.eventData = {
-          name: '',
-          description: '',
-          eventType: '',
-          eventStart: '',
-          eventEnd: '',
-        }
-      }
-    },
-
-    async handleSubmit() {
-      if (this.isEditMode) {
-        await this.updateEvent()
-      } else {
-        await this.addEvent()
-      }
-    },
-
-    async addEvent() {
-      if (this.isLoading) return
-      this.isLoading = true
-
-      if (!this.eventData.name || !this.eventData.eventStart || !this.eventData.eventEnd) {
-        alert('Please fill in all required fields (Name, Start Date, End Date).')
-        this.isLoading = false
-        return
-      }
-
-      try {
-        await useLocalManager.addEvent(this.eventData)
-        this.$emit('event-added')
-        this.close()
-        this.showToast('Successfully added the event', 'success')
-      } catch (err) {
-        this.showToast(err.response?.data?.message || 'Failed to add event', 'error')
-      } finally {
-        this.isLoading = false
-      }
-    },
-
-    async updateEvent() {
-      if (this.isLoading) return
-      this.isLoading = true
-
-      try {
-        await useLocalManager.updateEvent(this.eventData, this.eventData.id)
-        this.$emit('event-updated', this.eventData)
-        this.close()
-        this.showToast('Successfully updated the event', 'success')
-      } catch (err) {
-        this.showToast(err.response?.data?.message || 'Failed to update event', 'error')
-      } finally {
-        this.isLoading = false
-      }
-    },
-  },
-}
-</script>
-
-<template>
-  <!-- Modal Backdrop -->
-  <div v-if="show" class="modal-backdrop fade show"></div>
-
-  <!-- Modal -->
-  <div
-    v-if="show"
-    class="modal fade show"
-    style="display: block"
-    tabindex="-1"
-    aria-labelledby="eventFormModalLabel"
-    aria-modal="true"
-    role="dialog"
-  >
-    <div class="modal-dialog modal-dialog-centered">
-      <div class="modal-content">
-        <form @submit.prevent="handleSubmit">
-          <div class="modal-header">
-            <h5 class="modal-title" id="eventFormModalLabel">{{ modalTitle }}</h5>
-            <button type="button" class="btn-close" @click="close" aria-label="Close"></button>
-          </div>
-          <div class="modal-body">
-            <!-- Event Name -->
-            <div class="mb-3">
-              <label for="eventName" class="form-label">Event Name</label>
-              <input
-                type="text"
-                class="form-control"
-                id="eventName"
-                v-model="eventData.name"
-                required
-              />
-            </div>
-
-            <!-- Event Description -->
-            <div class="mb-3">
-              <label for="eventDescription" class="form-label">Description</label>
-              <textarea
-                class="form-control"
-                id="eventDescription"
-                rows="3"
-                v-model="eventData.description"
-              ></textarea>
-            </div>
-
-            <!-- Event Type -->
-            <div class="mb-3">
-              <label for="eventType" class="form-label">Event Type</label>
-              <select class="form-select" id="eventType" v-model="eventData.eventType">
-                <option v-for="opt in eventTypeOptions" :key="opt.value" :value="opt.value">
-                  {{ opt.label }}
-                </option>
-              </select>
-            </div>
-
-            <!-- Event Start/End -->
-            <div class="row">
-              <div class="col-md-6 mb-3">
-                <label for="eventStart" class="form-label">Start Date & Time</label>
-                <input
-                  type="datetime-local"
-                  class="form-control"
-                  id="eventStart"
-                  v-model="eventData.eventStart"
-                  required
-                />
-              </div>
-              <div class="col-md-6 mb-3">
-                <label for="eventEnd" class="form-label">End Date & Time</label>
-                <input
-                  type="datetime-local"
-                  class="form-control"
-                  id="eventEnd"
-                  v-model="eventData.eventEnd"
-                  required
-                />
-              </div>
-            </div>
-          </div>
-
-          <div class="modal-footer">
-            <button type="button" class="btn btn-secondary" @click="close">Close</button>
-            <button type="submit" class="btn btn-primary" :disabled="isLoading">
-              <span
-                v-if="isLoading"
-                class="spinner-border spinner-border-sm"
-                role="status"
-                aria-hidden="true"
-              ></span>
-              {{ saveButtonText }}
-            </button>
-          </div>
-        </form>
-      </div>
-    </div>
-  </div>
-</template>
-
-<style scoped></style>
Index: serveNGo-frontend/src/components/Project/Event/event_in_event_listing.vue
===================================================================
--- ReserveNGo-frontend/src/components/Project/Event/event_in_event_listing.vue	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,236 +1,0 @@
-<script>
-import { userStore } from '@/PiniaStores/UserStore.js'
-import noImg from '@/assets/no-img.png'
-import { config } from '@/constants/Api_config.js'
-import { getEnumLabel } from '@/utils/enumLabels.ts'
-
-export default {
-  props: {
-    event: { type: Object, required: true },
-    isFavoured: { type: Boolean, default: false },
-    mode: { type: String, default: 'all' },
-    isSelected: { type: Boolean, default: false },
-  },
-
-  data() {
-    return {
-      userStore_: userStore(),
-      isHovered: false,
-    }
-  },
-
-  computed: {
-    eventImageSrc() {
-      if (!this.event.localLogo) return noImg
-
-      try {
-        return new URL(this.event.localLogo, config.API_BASE_URL).toString()
-      } catch {
-        return config.API_BASE_URL + this.event.localLogo
-      }
-    },
-
-    formattedStart() {
-      return this.formatDateTime(this.event.eventStart)
-    },
-
-    formattedEnd() {
-      return this.formatDateTime(this.event.eventEnd)
-    },
-  },
-
-  methods: {
-    handleClick() {
-      this.$emit('select', this.event.id)
-    },
-
-    addToFavourites(e) {
-      e.stopPropagation()
-      this.$emit('toggle-favourite', this.event.id)
-    },
-
-    onImageError(event) {
-      event.target.src = noImg
-    },
-
-    handleMouseEnter() {
-      this.isHovered = true
-    },
-
-    handleMouseLeave() {
-      this.isHovered = false
-    },
-
-    formatDateTime(dateTime) {
-      if (!dateTime) return ''
-      const d = new Date(dateTime)
-      return d.toLocaleString(undefined, {
-        day: '2-digit',
-        month: 'short',
-        year: 'numeric',
-        hour: '2-digit',
-        minute: '2-digit',
-      })
-    },
-    eventTypeLabel(event) {
-      return getEnumLabel(event?.eventType, 'EventType')
-    },
-  },
-}
-</script>
-
-<template>
-  <div
-    id="container"
-    class="row align-items-center my-3 p-3 rounded shadow-sm"
-    :class="{ selected: isSelected }"
-    @click="handleClick"
-    @mouseenter="handleMouseEnter"
-    @mouseleave="handleMouseLeave"
-  >
-    <!-- Local Logo -->
-    <div class="col-auto pe-0">
-      <img
-        :src="eventImageSrc"
-        alt="Local logo"
-        class="rounded"
-        style="width: 60px; height: 60px; object-fit: cover"
-        @error="onImageError"
-      />
-    </div>
-
-    <!-- Info -->
-    <div class="col info ps-3">
-      <div class="d-flex align-items-center gap-2">
-        <h5 class="mb-0 fw-bold">{{ event.name }}</h5>
-        <!-- Event Type Badge -->
-        <span class="event-type-badge">
-          {{ eventTypeLabel(event) }}
-        </span>
-      </div>
-
-      <p class="mb-1 text-muted mt-1">
-        <i class="fas fa-calendar-alt me-1"></i>
-        {{ formattedStart }}
-        <span class="mx-1">→</span>
-        {{ formattedEnd }}
-      </p>
-    </div>
-
-    <!-- Buttons (ON HOVER) -->
-    <div class="col-auto d-flex align-items-center">
-      <transition name="fade">
-        <div class="action-buttons d-flex align-items-center gap-2" v-if="isHovered || isSelected">
-          <button
-            v-if="userStore_.isCustomer"
-            class="btn btn-favourite"
-            :class="{ active: isFavoured }"
-            @click.stop="addToFavourites"
-          >
-            <i class="fas fa-heart me-1"></i>
-            {{ isFavoured ? 'Remove from Favourites' : 'Add to Favourites' }}
-          </button>
-
-          <router-link :to="`/more_details/${event.localId}`">
-            <button class="btn btn-outline-dark">
-              <i class="fas fa-info-circle me-1"></i> View Details
-            </button>
-          </router-link>
-        </div>
-      </transition>
-    </div>
-  </div>
-</template>
-
-<style scoped>
-#container {
-  border-left: 3px solid transparent;
-  background: #fff;
-  transition: all 0.2s ease;
-  cursor: pointer;
-  position: relative;
-}
-
-#container:not(.selected) {
-  border-left-color: #5ea5bc;
-}
-
-#container:hover {
-  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.2);
-  background-color: #f9f9f9;
-}
-
-#container.selected::before {
-  content: '';
-  position: absolute;
-  inset: 0;
-  border: 3px solid #5ea5bc;
-  border-radius: 8px;
-  pointer-events: none;
-  animation: drawBorder 0.3s linear forwards;
-}
-
-.btn-favourite {
-  background-color: #fff;
-  border: 2px solid #5ea5bc;
-  color: #5ea5bc;
-  padding: 0.375rem 0.75rem;
-  transition: all 0.2s ease;
-  white-space: nowrap;
-}
-
-.btn-favourite:hover {
-  background-color: #5ea5bc;
-  border-color: #5ea5bc;
-  color: #fff;
-}
-
-.btn-favourite.active {
-  background-color: #e74c3c;
-  border-color: #e74c3c;
-  color: #fff;
-}
-
-.btn-favourite.active:hover {
-  background-color: #c0392b;
-  border-color: #c0392b;
-}
-
-.btn-favourite:disabled {
-  opacity: 0.6;
-  cursor: not-allowed;
-}
-
-.action-buttons {
-  gap: 0.5rem;
-}
-
-.event-type-badge {
-  background-color: #eef5f8;
-  color: #f55845;
-  border: 1px solid #f55845;
-  border-radius: 999px;
-  padding: 2px 10px;
-  font-size: 0.85rem;
-  font-weight: 600;
-  white-space: nowrap;
-}
-
-@keyframes drawBorder {
-  0% {
-    clip-path: polygon(0 0, 0 0, 0 0, 0 0);
-  }
-  25% {
-    clip-path: polygon(0 0, 100% 0, 100% 0, 0 0);
-  }
-  50% {
-    clip-path: polygon(0 0, 100% 0, 100% 100%, 0 0);
-  }
-  75% {
-    clip-path: polygon(0 0, 100% 0, 100% 100%, 0 100%);
-  }
-  100% {
-    clip-path: polygon(0 0, 100% 0, 100% 100%, 0 100%);
-  }
-}
-</style>
Index: serveNGo-frontend/src/components/Project/Event/event_listing_container.vue
===================================================================
--- ReserveNGo-frontend/src/components/Project/Event/event_listing_container.vue	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,77 +1,0 @@
-<script>
-import EventInEventListing from '@/components/Project/Event/event_in_event_listing.vue'
-import { defineComponent } from 'vue'
-
-export default defineComponent({
-  components: { EventInEventListing },
-
-  data() {
-    return {
-      selectedEventId: null,
-    }
-  },
-
-  props: {
-    mode: String,
-    events: {
-      type: Array,
-      default: () => [],
-    },
-    favouriteEvents: {
-      type: Array,
-      default: () => [],
-    },
-  },
-
-  computed: {
-    displayedEvents() {
-      return this.mode === 'favourites' ? this.favouriteEvents : this.events
-    },
-  },
-
-  methods: {
-    toggleFavourite(id) {
-      this.$emit('toggle-favourite', id)
-    },
-  },
-})
-</script>
-
-<template>
-  <div id="container" class="container">
-    <h5>Events</h5>
-
-    <!-- EMPTY STATES -->
-    <div v-if="mode === 'favourites'">
-      <div v-if="favouriteEvents.length === 0" class="text-center text-muted py-5">
-        <i class="fas fa-calendar-times fa-3x mb-3"></i>
-        <p>You don't have any favourite events yet.</p>
-      </div>
-    </div>
-
-    <div v-else>
-      <div v-if="events.length === 0" class="text-center text-muted py-5">
-        <i class="fas fa-calendar-times fa-3x mb-3"></i>
-        <p>No events available at the moment.</p>
-      </div>
-    </div>
-
-    <!-- LIST -->
-    <div v-for="event in displayedEvents" :key="event.id">
-      <EventInEventListing
-        :event="event"
-        :isFavoured="favouriteEvents.map((fav) => fav.id).includes(event.id)"
-        :isSelected="selectedEventId === event.id"
-        :mode="mode"
-        @select="selectedEventId = event.id"
-        @toggle-favourite="toggleFavourite"
-      />
-    </div>
-  </div>
-</template>
-
-<style scoped>
-#container {
-  margin: 15px auto 30px auto
-}
-</style>
Index: serveNGo-frontend/src/components/Project/Event/events_carousel.vue
===================================================================
--- ReserveNGo-frontend/src/components/Project/Event/events_carousel.vue	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,415 +1,0 @@
-<script lang="ts">
-import { userStore } from '@/PiniaStores/UserStore.js'
-import { config } from '@/constants/Api_config'
-import { transformArray, ensureEventDateTime } from '@/utils/utilFunctions'
-import noImg from '@/assets/no-img.png'
-
-export default {
-  data() {
-    return {
-      userStore_: userStore(),
-      itemsPerSlide: 3,
-    }
-  },
-  props: ['allEvents'],
-
-  computed: {
-    chunkedEvents() {
-      if (!this.allEvents || this.allEvents.length === 0) {
-        return []
-      }
-
-      const flatEvents = this.allEvents.flat()
-
-      // First, chunk the events without altering original date fields
-      const chunks = transformArray(flatEvents, this.itemsPerSlide, false)
-
-      // Enrich each event in-place using shared util
-      chunks.forEach((chunk) => {
-        chunk.forEach((ev) => ensureEventDateTime(ev))
-      })
-
-      return chunks
-    },
-  },
-
-  methods: {
-    onImageError(event) {
-      event.target.src = noImg
-    },
-    formatDateTime(dateTime) {
-      if (!dateTime) return ''
-      const d = new Date(dateTime)
-      return d.toLocaleString(undefined, {
-        day: '2-digit',
-        month: 'short',
-        year: 'numeric',
-        hour: '2-digit',
-        minute: '2-digit',
-      })
-    },
-    /**
-     * Checks the window width and updates the `itemsPerSlide` data property.
-     * This will trigger the `chunkedEvents` computed property to recalculate.
-     */
-    updateItemsPerSlide() {
-      const width = window.innerWidth
-      // Using standard Bootstrap breakpoints
-      if (width < 768) {
-        // Small devices (phones)
-        this.itemsPerSlide = 1
-      } else if (width < 992) {
-        // Medium devices (tablets/laptops)
-        this.itemsPerSlide = 2
-      } else {
-        // Large devices (desktops)
-        this.itemsPerSlide = 3
-      }
-    },
-
-    getImageLogo(imageLogo) {
-      if (!imageLogo) return noImg
-
-      try {
-        return new URL(imageLogo, config.API_BASE_URL).toString()
-      } catch {
-        return config.API_BASE_URL + imageLogo
-      }
-    },
-  },
-
-  mounted() {
-    this.updateItemsPerSlide()
-    window.addEventListener('resize', this.updateItemsPerSlide)
-  },
-
-  beforeUnmount() {
-    window.removeEventListener('resize', this.updateItemsPerSlide)
-  },
-}
-</script>
-
-<template>
-  <div class="events-section">
-    <div class="events-header">
-      <h5 class="events-title">Newest Events</h5>
-    </div>
-
-    <div
-      v-if="chunkedEvents && chunkedEvents.length > 0"
-      id="carouselMulti3"
-      class="carousel slide events-carousel-wrapper"
-      data-bs-ride="carousel"
-    >
-      <div class="carousel-inner">
-        <div
-          class="carousel-item"
-          v-for="(eventGroup, index) in chunkedEvents"
-          :key="index"
-          :class="{ active: index === 0 }"
-        >
-          <div class="d-flex justify-content-center gap-2 px-4">
-            <div v-for="event in eventGroup" :key="event.id" class="event-card-container">
-              <div class="card event-card h-100">
-                <div class="d-flex flex-row">
-                  <div class="event-image-wrapper">
-                    <img
-                      :src="getImageLogo(event.localLogo)"
-                      class="event-image"
-                      alt="Event image"
-                      @error="onImageError"
-                    />
-<!--                    <div class="event-type-badge">-->
-<!--                      <span class="event-type-pill">-->
-<!--                        {{ event.eventType }}-->
-<!--                      </span>-->
-<!--                    </div>-->
-                  </div>
-
-                  <div class="card-body d-flex flex-column p-2">
-                    <div class="d-flex align-items-center gap-1">
-                      <h6 class="card-title fw-bold mb-0">{{ event.name }}</h6>
-                    </div>
-
-                    <div class="event-details">
-                      <div class="d-flex align-items-center text-muted">
-                        <i class="fas fa-play me-1 text-success"></i>
-                        <span class="text-truncate">
-                          {{ formatDateTime(event.eventStart) }}
-                        </span>
-                      </div>
-
-                      <div class="d-flex align-items-center text-muted">
-                        <i class="fas fa-stop me-1 text-danger"></i>
-                        <span class="text-truncate">
-                          {{ formatDateTime(event.eventEnd) }}
-                        </span>
-                      </div>
-                    </div>
-
-                    <router-link :to="`/more_details/${event.localId}`" class="details-btn-wrapper">
-                      <button class="btn btn-outline-dark btn-sm details-btn">
-                        <i class="fas fa-info-circle"></i>
-                        Details
-                      </button>
-                    </router-link>
-                  </div>
-                </div>
-              </div>
-            </div>
-          </div>
-        </div>
-      </div>
-
-      <button
-        v-if="chunkedEvents.length > 1"
-        class="carousel-control-prev carousel-control-custom"
-        type="button"
-        data-bs-target="#carouselMulti3"
-        data-bs-slide="prev"
-      >
-        <span class="carousel-control-prev-icon"></span>
-      </button>
-
-      <button
-        v-if="chunkedEvents.length > 1"
-        class="carousel-control-next carousel-control-custom"
-        type="button"
-        data-bs-target="#carouselMulti3"
-        data-bs-slide="next"
-      >
-        <span class="carousel-control-next-icon"></span>
-      </button>
-    </div>
-
-    <div v-else class="empty-events-state">
-      <div class="text-center py-2">
-        <p class="text-muted small mb-0">No events available</p>
-      </div>
-    </div>
-  </div>
-</template>
-
-<style scoped>
-.events-carousel-wrapper {
-  position: relative;
-  padding: 0 2.5rem;
-}
-
-.event-card-container {
-  flex: 0 0 auto;
-}
-
-.event-card {
-  width: 300px;
-  height: 90px;
-  border-left: 3px solid #5ea5bc;
-  border-radius: 0.375rem;
-  overflow: hidden;
-  transition: all 0.2s ease;
-  background: #fff;
-  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
-}
-
-.event-card:hover {
-  transform: translateY(-1px);
-  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.2) !important;
-  background-color: #f9f9f9;
-}
-
-.event-image-wrapper {
-  position: relative;
-  overflow: hidden;
-  width: 90px;
-  height: 90px;
-  flex-shrink: 0;
-}
-
-.event-image {
-  width: 100%;
-  height: 100%;
-  object-fit: cover;
-}
-
-.event-type-badge {
-  position: absolute;
-  top: 0.25rem;
-  right: 0.25rem;
-  z-index: 2;
-}
-
-.event-type-badge .badge {
-  font-size: 0.6rem;
-  padding: 0.2rem 0.4rem;
-  font-weight: 500;
-  text-transform: uppercase;
-  letter-spacing: 1px;
-  background-color: #5ea5bc !important;
-  border: none;
-  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2);
-}
-
-.event-card .card-body {
-  padding: 0.5rem;
-  flex: 1;
-  min-width: 0;
-}
-
-.event-card .card-title {
-  font-size: 0.85rem;
-  color: #212529;
-  line-height: 1.2;
-  margin-bottom: 0.25rem;
-  font-weight: 600;
-  white-space: nowrap;
-  overflow: hidden;
-  text-overflow: ellipsis;
-}
-
-.event-details {
-  font-size: 0.7rem;
-  flex-grow: 1;
-}
-
-.event-details i {
-  font-size: 0.65rem;
-  width: 12px;
-}
-
-.carousel-control-custom {
-  width: auto;
-  height: auto;
-  background: none;
-  border: none;
-  top: 50%;
-  transform: translateY(-50%);
-  opacity: 0.7;
-  transition: opacity 0.2s ease;
-  z-index: 10;
-}
-
-.carousel-control-custom:hover {
-  opacity: 1;
-  background: none;
-  box-shadow: none;
-}
-
-.carousel-control-prev {
-  left: 0;
-}
-
-.carousel-control-next {
-  right: 0;
-}
-
-.carousel-control-prev-icon,
-.carousel-control-next-icon {
-  width: 30px;
-  height: 40px;
-  background-size: 100% 100%;
-  background-color: transparent;
-  opacity: 1;
-  filter: none;
-}
-
-.carousel-control-prev-icon {
-  background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23000'%3e%3cpath d='M11.354 1.646a.5.5 0 0 1 0 .708L5.707 8l5.647 5.646a.5.5 0 0 1-.708.708l-6-6a.5.5 0 0 1 0-.708l6-6a.5.5 0 0 1 .708 0z'/%3e%3c/svg%3e");
-}
-
-.carousel-control-next-icon {
-  background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23000'%3e%3cpath d='M4.646 1.646a.5.5 0 0 1 .708 0l6 6a.5.5 0 0 1 0 .708l-6 6a.5.5 0 0 1-.708-.708L10.293 8 4.646 2.354a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e");
-}
-
-.empty-events-state {
-  padding: 0.5rem;
-  text-align: center;
-}
-
-.empty-events-state p {
-  font-size: 0.75rem;
-  margin: 0;
-}
-
-@media (max-width: 992px) {
-  .event-card {
-    width: 240px;
-  }
-
-  .events-carousel-wrapper {
-    padding: 0 2rem;
-  }
-}
-
-@media (max-width: 768px) {
-  .event-card {
-    width: 200px;
-    height: 80px;
-  }
-
-  .event-image-wrapper {
-    width: 80px;
-    height: 80px;
-  }
-
-  .events-carousel-wrapper {
-    padding: 0 1.5rem;
-  }
-
-  .carousel-control-prev-icon,
-  .carousel-control-next-icon {
-    width: 24px;
-    height: 32px;
-    background-size: 100% 100%;
-  }
-
-  .events-section {
-    margin-bottom: 0.5rem;
-  }
-}
-.events-header {
-  display: flex;
-  flex-direction: row;
-  align-items: center;
-  justify-content: center;
-  padding: 0 2.5rem;
-  margin-bottom: 0.5rem;
-}
-
-.events-title {
-  font-size: 0.9rem;
-  font-weight: 600;
-  color: #212529;
-  text-transform: uppercase;
-  letter-spacing: 1px;
-  margin: 0;
-}
-
-.event-type-pill {
-  background-color: #eef5f8;
-  color: #5ea5bc;
-  border: 1px solid #5ea5bc;
-  border-radius: 999px;
-  padding: 2px 8px;
-  font-size: 0.6rem;
-  font-weight: 600;
-  white-space: nowrap;
-}
-
-.details-btn-wrapper {
-  position: absolute;
-  bottom: 6px;
-  left: 50%;
-  opacity: 0;
-  transition: opacity 0.2s ease;
-}
-
-.event-card:hover .details-btn-wrapper {
-  opacity: 1;
-}
-
-.details-btn {
-  font-size: 0.75rem;
-  padding: 0.2rem 0.35rem;
-  line-height: 1;
-}
-</style>
Index: serveNGo-frontend/src/components/Project/Event/events_carousel_in_locale.vue
===================================================================
--- ReserveNGo-frontend/src/components/Project/Event/events_carousel_in_locale.vue	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,266 +1,0 @@
-<script lang="ts">
-import { userStore } from '@/PiniaStores/UserStore.js'
-import { useLocalManager } from '@/repository/LocalManager'
-import { useToasts } from '@/composables/useToast.js'
-import { transformArray, ensureEventDateTime } from '@/utils/utilFunctions'
-import { getEnumLabel } from '@/utils/enumLabels'
-
-export default {
-  data() {
-    return {
-      userStore_: userStore(),
-      itemsPerSlide: 2,
-      showEditModal: false,
-      showToast: useToasts().showToast,
-    }
-  },
-  props: ['allEvents'],
-  emits: ['event-deleted', 'edit-started'],
-
-  computed: {
-    chunkedEvents() {
-      if (!this.allEvents || this.allEvents.length === 0) {
-        return []
-      }
-
-      const flatEvents = this.allEvents.flat()
-      flatEvents.forEach((ev) => ensureEventDateTime(ev))
-      return transformArray(flatEvents, this.itemsPerSlide, false)
-    },
-  },
-
-  methods: {
-    updateItemsPerSlide() {
-      const width = window.innerWidth
-      if (width < 768) {
-        this.itemsPerSlide = 1
-      } else {
-        this.itemsPerSlide = 2
-      }
-    },
-
-    deleteEvent(eventId) {
-      useLocalManager
-        .deleteEvent(eventId)
-        .then(() => {
-          this.$emit('event-deleted', eventId)
-          this.showToast('Successfully deleted event')
-        })
-        .catch((err) => {
-          this.showToast(err.response, 'error')
-        })
-    },
-    formatDateTime(dateTime) {
-      if (!dateTime) return ''
-      if (dateTime.date && dateTime.time) {
-        dateTime = `${dateTime.date}T${dateTime.time}`
-      }
-      const d = new Date(dateTime)
-      if (isNaN(d.getTime())) return ''
-      return d.toLocaleString(undefined, {
-        day: '2-digit',
-        month: 'short',
-        year: 'numeric',
-        hour: '2-digit',
-        minute: '2-digit',
-      })
-    },
-    eventTypeLabel(event) {
-      return getEnumLabel(event?.eventType, 'EventType')
-    },
-  },
-
-  mounted() {
-    this.updateItemsPerSlide()
-    window.addEventListener('resize', this.updateItemsPerSlide)
-  },
-
-  beforeUnmount() {
-    window.removeEventListener('resize', this.updateItemsPerSlide)
-  },
-}
-</script>
-
-<template>
-  <div id="carouselMulti3" class="carousel slide col-12" data-bs-ride="carousel">
-    <div class="carousel-inner">
-      <div
-        class="carousel-item"
-        v-for="(eventGroup, index) in chunkedEvents"
-        :key="index"
-        :class="{ active: index === 0 }"
-      >
-        <div class="d-flex justify-content-center gap-3 px-2">
-          <div v-for="event in eventGroup" :key="event.id" class="event-card-wrapper">
-            <div class="card shadow-sm h-100 event-card">
-              <div class="card-body d-flex flex-column">
-                <h5 class="card-title fw-bold mb-2">{{ event.name }}</h5>
-                <p class="card-text text-muted small mb-3 flex-grow-1">{{ event.description }}</p>
-                <div class="mb-3">
-                  <div class="d-flex flex-wrap gap-2 mb-2">
-                    <span class="event-type-pill">
-                      {{ eventTypeLabel(event) }}
-                    </span>
-                    <span
-                      class="event-status-pill"
-                      :class="`status-${event.status?.toLowerCase()}`"
-                    >
-                      {{ event.status }}
-                    </span>
-                  </div>
-                  <div class="text-muted small">
-                    <div class="mb-1 d-flex align-items-center">
-                      <i class="fas fa-play me-2 text-success"></i>
-                      {{ formatDateTime(event.eventStart) }}
-                    </div>
-                    <div class="d-flex align-items-center">
-                      <i class="fas fa-stop me-2 text-danger"></i>
-                      {{ formatDateTime(event.eventEnd) }}
-                    </div>
-                  </div>
-                </div>
-
-                <div v-if="userStore_.isLocaleManager" class="d-flex gap-2 mt-auto">
-                  <button
-                    class="btn btn-dark btn-sm flex-fill"
-                    @click="$emit('edit-started', event.id)"
-                  >
-                    <i class="fas fa-edit me-1"></i>Edit
-                  </button>
-                  <button class="btn btn-danger btn-sm flex-fill" @click="deleteEvent(event.id)">
-                    <i class="fas fa-trash me-1"></i>Delete
-                  </button>
-                </div>
-              </div>
-            </div>
-          </div>
-        </div>
-      </div>
-    </div>
-
-    <button
-      class="carousel-control-prev"
-      type="button"
-      data-bs-target="#carouselMulti3"
-      data-bs-slide="prev"
-    >
-      <span class="carousel-control-prev-icon"></span>
-    </button>
-    <button
-      class="carousel-control-next"
-      type="button"
-      data-bs-target="#carouselMulti3"
-      data-bs-slide="next"
-    >
-      <span class="carousel-control-next-icon"></span>
-    </button>
-  </div>
-</template>
-
-<style scoped>
-.carousel-control-prev,
-.carousel-control-next {
-  width: 3.25rem;
-  z-index: 6;
-}
-
-.carousel-control-prev-icon,
-.carousel-control-next-icon {
-  filter: invert(1);
-  opacity: 1;
-  background-size: 1.5rem 1.5rem;
-}
-
-.carousel-inner {
-  padding: 0 3.25rem;
-  box-sizing: border-box;
-}
-
-.event-card-wrapper {
-  flex: 0 0 calc(50% - 1.5rem);
-  max-width: calc(50% - 1.5rem);
-  box-sizing: border-box;
-}
-
-.event-card {
-  width: 100%;
-  min-height: 280px;
-  transition:
-    transform 0.2s ease,
-    box-shadow 0.2s ease;
-  border: 1px solid #e9ecef;
-}
-
-.event-card:hover {
-  transform: translateY(-2px);
-  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15) !important;
-}
-
-.event-card .card-body {
-  padding: 1.25rem;
-}
-
-.event-card .card-title {
-  font-size: 1.1rem;
-  color: #212529;
-}
-
-.event-card .card-text {
-  font-size: 0.9rem;
-  line-height: 1.5;
-}
-
-.event-type-pill {
-  background-color: #eef5f8;
-  color: #f55845;
-  border: 1px solid #f55845;
-  border-radius: 999px;
-  padding: 4px 10px;
-  font-size: 0.7rem;
-  font-weight: 600;
-  white-space: nowrap;
-}
-
-.event-status-pill {
-  border-radius: 999px;
-  padding: 4px 10px;
-  font-size: 0.7rem;
-  font-weight: 600;
-  white-space: nowrap;
-  text-transform: uppercase;
-}
-
-.status-upcoming {
-  background-color: #fff3cd;
-  color: #856404;
-  border: 1px solid #ffeeba;
-}
-
-.status-active {
-  background-color: #d4edda;
-  color: #155724;
-  border: 1px solid #c3e6cb;
-}
-
-.status-finished {
-  background-color: #e2e3e5;
-  color: #383d41;
-  border: 1px solid #d6d8db;
-}
-
-/* on small screens, revert to single-column card layout and reduce inner padding so mobile uses full width */
-@media (max-width: 768px) {
-  .carousel-inner {
-    padding: 0 1rem;
-  }
-  .event-card-wrapper {
-    flex: 0 0 100%;
-    max-width: 100%;
-  }
-
-  .event-card {
-    width: 100%;
-    max-width: none;
-  }
-}
-</style>
Index: serveNGo-frontend/src/components/Project/Local/LocalNotAssigned.vue
===================================================================
--- ReserveNGo-frontend/src/components/Project/Local/LocalNotAssigned.vue	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,16 +1,0 @@
-<script setup lang="ts"></script>
-
-<template>
-  <div class="h-100 d-flex justify-content-center align-items-center">
-    <div class="text-center p-4">
-      <i class="fa-solid fa-store-slash fa-3x text-muted mb-3"></i>
-
-      <h3 class="fw-semibold mb-2 text-danger">No Local Assigned</h3>
-
-      <p class="text-muted mb-0">You are currently not assigned to any local.</p>
-    </div>
-  </div>
-</template>
-
-<style scoped>
-</style>
Index: serveNGo-frontend/src/components/Project/Local/Locale_.vue
===================================================================
--- ReserveNGo-frontend/src/components/Project/Local/Locale_.vue	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,866 +1,0 @@
-<script>
-import { userStore } from '@/PiniaStores/UserStore.js'
-import { useRouter } from 'vue-router'
-import { transformArray } from '@/utils/utilFunctions.js'
-import events_carousel from '@/components/Project/Event/events_carousel_in_locale.vue'
-import WorkingHoursTable from '@/components/Project/Local/working-hours-table.vue'
-import { useLocalManager } from '@/repository/LocalManager.ts'
-import PhotosGridSystem from '@/components/Project/Utility/PhotosGridSystem.vue'
-import ImageModalLocale from '@/components/Project/Utility/ImageModalLocale.vue'
-import RatingsForLocal from '@/components/Project/Customer/RatingsForLocal.vue'
-import { config } from '@/constants/Api_config.js'
-import ManagerFileInput from '@/components/Project/Utility/ManagerFileInput.vue'
-import AddEventModal from '@/components/Project/Event/EditEventModal.vue'
-import { useToasts } from '@/composables/useToast.js'
-import LoadingIcon from '@/components/Project/Utility/LoadingIcon.vue'
-import { useLocales } from '@/repository/Locale'
-import { useCustomer } from '@/repository/Customer.ts'
-import makeReservationModal from '@/components/Project/Customer/makeReservationModal.vue'
-import noImg from '@/assets/no-img.png'
-import { getEnumLabel, getEnumOptions } from '@/utils/enumLabels.ts'
-
-export default {
-  components: {
-    makeReservationModal,
-    LoadingIcon,
-    events_carousel,
-    WorkingHoursTable,
-    PhotosGridSystem,
-    ImageModalLocale,
-    RatingsForLocal,
-    ManagerFileInput,
-    AddEventModal,
-  },
-  data() {
-    return {
-      locale: {
-        id: '',
-        name: '',
-        description: '',
-        address: '',
-        workingHours: '',
-        services: [],
-        ratingAvg: '',
-        events: [],
-        localPhotos: [],
-        menuPhoto: '',
-        menuLink: '',
-        contact: {
-          phone: '',
-          email: '',
-          socialLinks: {},
-        },
-        logo: '',
-      },
-
-      eventsForCarousel: [],
-      local_id: this.$route.params['id'],
-      userStore: userStore(),
-      router: useRouter(),
-      isEditing: false,
-      cachedLocale: null,
-
-      //MODAL
-      isModalVisible: false,
-      selectedImageIndex: 0,
-      //MODAL END
-
-      //UPLOADing files state
-      isLogoUploading: false,
-      isPhotoUploading: false,
-      //END UPLOADING files state
-
-      //loading details
-      isSaveChangesLoading: false,
-      //END loading details
-
-      isAddEventModalVisible: false,
-
-      //Edit Event
-      isEventModalVisible: false,
-      targetEditEvent: null,
-      //End Edit event
-
-      //Toast
-      showToast: useToasts().showToast,
-      //Toast end
-
-      // Working hours edit helpers
-      daysOfWeek: ['MONDAY', 'TUESDAY', 'WEDNESDAY', 'THURSDAY', 'FRIDAY', 'SATURDAY', 'SUNDAY'],
-      // Holds text inputs per day during edit mode, e.g. "09:00:00-17:00:00" or "Closed"
-      workingHoursInputs: {},
-
-      modalOpen: false,
-      // favourites
-      favouriteLocals: [],
-    }
-  },
-  computed: {
-    localTypeLabel() {
-      return getEnumLabel(this.locale.localType, 'LocalType')
-    },
-    servicesLabels() {
-      return Array.isArray(this.locale.services)
-        ? this.locale.services.map((s) => getEnumLabel(s, 'ProvidedService'))
-        : []
-    },
-    localTypeOptions() {
-      return getEnumOptions('LocalType')
-    },
-    providedServiceOptions() {
-      return getEnumOptions('ProvidedService')
-    },
-    roundedRating() {
-      const rating = parseFloat(this.locale.ratingAvg)
-      if (isNaN(rating)) return 0
-      return Math.round(rating * 2) / 2
-    },
-    servicesAsString: {
-      get() {
-        return Array.isArray(this.locale.services) ? this.locale.services.join(', ') : ''
-      },
-      set(newValue) {
-        this.locale.services = newValue
-          .split(',')
-          .map((s) => s.trim())
-          .filter(Boolean)
-      },
-    },
-    fullPicturesUrls() {
-      return this.locale.localPhotos.map((path) => `${config.API_BASE_URL}${path}`)
-    },
-    logoPicture() {
-      if (!this.locale.logo) {
-        return 'https://cdn.vuetifyjs.com/images/profiles/default-avatar.png'
-      }
-      try {
-        const url = new URL(this.locale.logo, config.API_BASE_URL)
-        return url.toString()
-      } catch {
-        return config.API_BASE_URL + this.locale.logo
-      }
-    },
-    // Check if the current locale is in customer's favourites
-    isCurrentLocaleFavourite() {
-      const ids = this.favouriteLocals.map((l) => l.id)
-      return ids.includes(this.locale.id)
-    },
-    logoImgElementId() {
-      return 'logoLocalePicture'
-    },
-  },
-
-  mounted() {
-    this.fetchLocaleData()
-    // If the user is a customer, load favourite locals for toggle state
-    if (this.userStore?.data?.role === 'ROLE_CUSTOMER') {
-      this.loadFavouriteLocals()
-    }
-  },
-  methods: {
-    onImageError(event) {
-      event.target.src = noImg
-    },
-    handleRemoveImage(image, index) {
-      this.locale.localPhotos.splice(index, 1)
-      let url = new URL(image)
-      console.log('PHOTO-URL', url.pathname)
-      const localPhotosUrls = [url.pathname]
-      useLocalManager
-        .deletePhoto({ localPhotosUrls })
-        .then(() => {
-          this.showToast('Successfully deleted a local image')
-        })
-        .catch((error) => {
-          this.showToast(error.response, 'error')
-          this.locale.localPhotos.push(image)
-        })
-    },
-
-    openImageModal(index, secondRow = false) {
-      if (secondRow) {
-        index += 2
-      }
-      this.selectedImageIndex = index
-      this.isModalVisible = true
-    },
-    closeImageModal() {
-      this.isModalVisible = false
-    },
-
-    fetchLocaleData() {
-      useLocales
-        .getSpecificLocale(this.local_id)
-        .then((data) => {
-          this.locale = data
-          console.log('LOCAL::: WORKING HOURS DATA', this.locale.workingHours)
-          if (!this.locale.contact) {
-            this.locale.contact = { phone: '', email: '' }
-          }
-          if (!this.locale.services) {
-            this.locale.services = []
-          }
-          this.eventsForCarousel = transformArray(this.locale.events, 2)
-        })
-        .catch((err) => console.log('Error fetching local data:', err))
-    },
-    addToFavourites() {
-      useCustomer.addFavourite(this.locale.id).catch((error) => console.log(error))
-    },
-    // ====== FAVOURITES (Customer) ======
-    async loadFavouriteLocals() {
-      try {
-        const data = await useCustomer.getFavouriteLocals()
-        this.favouriteLocals = data || []
-      } catch (err) {
-        console.log('Failed to fetch favourite locals', err)
-        this.favouriteLocals = []
-      }
-    },
-    toggleFavouriteLocal(id) {
-      const isFav = this.favouriteLocals.map((item) => item.id).includes(id)
-      const action = isFav ? useCustomer.removeFavourite(id) : useCustomer.addFavourite(id)
-
-      Promise.resolve(action)
-        .then(() => {
-          if (isFav) {
-            this.favouriteLocals = this.favouriteLocals.filter((fav) => fav.id !== id)
-          } else {
-            // If we have current locale data, push it; otherwise reload favourites
-            if (this.locale && this.locale.id === id) {
-              this.favouriteLocals.push({ ...this.locale })
-            } else {
-              this.loadFavouriteLocals()
-            }
-          }
-        })
-        .catch((err) => console.log('Error toggling favourite local:', err))
-    },
-    uploadLogo(fileInput) {
-      this.isLogoUploading = true
-      const picture = fileInput
-      if (!picture) {
-        console.warn('No logo file selected')
-        return
-      }
-      const formData = new FormData()
-      formData.append('logo', picture)
-      useLocalManager
-        .uploadLogo(formData)
-        .then((data) => {
-          this.locale.logo = data
-          this.$refs.uploadLogoInputRef.reset()
-          this.showToast('Successfully uploaded the logo')
-        })
-        .catch((error) => {
-          if (error.status === 409) {
-            this.showToast(error.response, 'error')
-          } else {
-            this.showToast('You do not have permission to make this request', 'error')
-          }
-        })
-        .finally(() => {
-          this.isLogoUploading = false
-        })
-    },
-    uploadPhoto(fileInput) {
-      this.isPhotoUploading = true
-      const picture = fileInput
-      if (!picture) {
-        console.warn('No photo file selected')
-        return
-      }
-      const formData = new FormData()
-      formData.append('photo', picture)
-      useLocalManager
-        .uploadImage(formData)
-        .then(() => {
-          this.fetchLocaleData()
-          this.$refs.uploadPhotoInputRef.reset()
-          this.showToast('Successfully uploaded the photo')
-        })
-        .catch((error) => {
-          if (error.status === 409) {
-            this.showToast(error.response, 'error')
-          } else {
-            this.showToast('You do not have permission to make this request', 'error')
-          }
-        })
-        .finally(() => {
-          this.isPhotoUploading = false
-        })
-    },
-    startEditing() {
-      // Create a deep copy of the current state to allow for cancellation
-      this.cachedLocale = JSON.parse(JSON.stringify(this.locale))
-      this.isEditing = true
-      // Initialize working hours inputs for edit mode
-      this.initWorkingHoursInputs()
-    },
-    cancelEditing() {
-      // Restore the original data from the cached copy
-      this.locale = this.cachedLocale
-      this.isEditing = false
-      this.cachedLocale = null
-    },
-    saveLocalChanges() {
-      this.isSaveChangesLoading = true
-      const payload = { ...this.locale }
-      if (this.isEditing) {
-        const { list, error } = this.validateAndBuildWorkingHours()
-        if (error) {
-          this.showToast(error, 'error')
-          this.isSaveChangesLoading = false
-          return
-        }
-        payload.workingHours = list
-      }
-      delete payload.eventsForCarousel
-
-      useLocalManager
-        .saveDetailChanges(payload)
-        .then(() => {
-          this.cachedLocale = null
-          this.showToast('Successfully updated')
-          this.fetchLocaleData()
-        })
-        .catch((error) => {
-          this.locale = this.cachedLocale
-          this.showToast(error.response, 'error')
-        })
-        .finally(() => {
-          this.isSaveChangesLoading = false
-          this.isEditing = false
-        })
-    },
-    initWorkingHoursInputs() {
-      const inputs = {}
-      const source = Array.isArray(this.locale.workingHours) ? this.locale.workingHours : []
-      const map = {}
-      source.forEach((wh) => {
-        if (wh && wh.dayOfWeek) {
-          const day = String(wh.dayOfWeek).toUpperCase()
-          map[day] = wh
-        }
-      })
-      this.daysOfWeek.forEach((day) => {
-        const wh = map[day]
-        if (wh && wh.openTime && wh.closeTime) {
-          inputs[day] = `${wh.openTime}-${wh.closeTime}`
-        } else {
-          inputs[day] = ''
-        }
-      })
-      this.workingHoursInputs = inputs
-    },
-    parseWorkingHourInput(text) {
-      if (text == null) return { type: 'empty' }
-      const trimmed = String(text).trim()
-      if (trimmed.length === 0) return { type: 'empty' }
-      if (/^closed$/i.test(trimmed)) return { type: 'closed' }
-      const parts = trimmed.split('-')
-      if (parts.length !== 2)
-        return { type: 'invalid', reason: 'Expected format HH:MM:SS-HH:MM:SS' }
-      const [from, to] = parts
-      const timeRegex = /^(\d{2}):(\d{2}):(\d{2})$/
-      const mFrom = from.match(timeRegex)
-      const mTo = to.match(timeRegex)
-      if (!mFrom || !mTo) return { type: 'invalid', reason: 'Time must be HH:MM:SS' }
-      const h1 = parseInt(mFrom[1], 10),
-        m1 = parseInt(mFrom[2], 10),
-        s1 = parseInt(mFrom[3], 10)
-      const h2 = parseInt(mTo[1], 10),
-        m2 = parseInt(mTo[2], 10),
-        s2 = parseInt(mTo[3], 10)
-      const inRange = (h, m, s) => h >= 0 && h <= 23 && m >= 0 && m <= 59 && s >= 0 && s <= 59
-      if (!inRange(h1, m1, s1) || !inRange(h2, m2, s2))
-        return { type: 'invalid', reason: 'Time values out of range' }
-      const sec1 = h1 * 3600 + m1 * 60 + s1
-      const sec2 = h2 * 3600 + m2 * 60 + s2
-      if (sec1 >= sec2) return { type: 'invalid', reason: 'Open time must be before close time' }
-      return { type: 'range', openTime: `${from}`, closeTime: `${to}` }
-    },
-    validateAndBuildWorkingHours() {
-      const list = []
-      for (const day of this.daysOfWeek) {
-        const value = this.workingHoursInputs[day]
-        const res = this.parseWorkingHourInput(value)
-        if (res.type === 'invalid') {
-          return { list: null, error: `${day}: ${res.reason}` }
-        }
-        if (res.type === 'range') {
-          list.push({
-            dayOfWeek: day,
-            openTime: res.openTime,
-            closeTime: res.closeTime,
-          })
-        }
-      }
-      return { list, error: null }
-    },
-    onWorkingHourBlur(day) {
-      const value = this.workingHoursInputs[day]
-      const res = this.parseWorkingHourInput(value)
-      if (res.type === 'invalid') {
-        this.showToast(`${day}: ${res.reason}`, 'error')
-      }
-    },
-    deleteEvent(eventId) {
-      this.locale.events = this.locale.events.filter((event) => event.id !== eventId)
-      this.fetchLocaleData()
-    },
-    addEvent() {
-      this.fetchLocaleData()
-      this.isModalVisible = false
-    },
-    startEditingEvent(eventId) {
-      this.targetEditEvent = this.locale.events.find((event) => event.id === eventId)
-      console.log('TARGET EDIT EVENT', this.targetEditEvent)
-      this.isEventModalVisible = true
-    },
-    getEnumLabel,
-  },
-}
-</script>
-
-<template>
-  <div class="locale-details-wrapper py-4 px-3">
-    <div class="container">
-      <div class="row g-4">
-        <!-- Left: Logo -->
-        <div class="col-12 col-md-4">
-          <div class="card position-relative shadow-sm">
-            <img
-              :id="logoImgElementId"
-              :src="logoPicture"
-              class="card-img-top object-fit-cover rounded"
-              style="aspect-ratio: 1 / 1; object-fit: cover"
-              alt="Restaurant Logo"
-              @error="onImageError"
-            />
-            <ManagerFileInput
-              v-if="userStore.isLocaleManager"
-              ref="uploadLogoInputRef"
-              @file-sent="uploadLogo"
-              input-id="localeLogoInput"
-              left-button-text="Choose Logo"
-              right-button-text="Save"
-              :is-loading="isLogoUploading"
-              :previewElementId="logoImgElementId"
-            ></ManagerFileInput>
-          </div>
-
-          <PhotosGridSystem
-            :openImageModal="openImageModal"
-            :images="fullPicturesUrls.slice(0, 5)"
-          ></PhotosGridSystem>
-          <ManagerFileInput
-            v-if="userStore.isLocaleManager"
-            ref="uploadPhotoInputRef"
-            style="margin-top: 1rem"
-            @file-sent="uploadPhoto"
-            input-id="localePhotoInput"
-            left-button-text="Choose Photo"
-            right-button-text="Save"
-            :is-loading="isPhotoUploading"
-          ></ManagerFileInput>
-
-          <ImageModalLocale
-            :show="isModalVisible"
-            :images="locale.localPhotos.length === 0 ? galleryImages : fullPicturesUrls"
-            :start-index="selectedImageIndex"
-            @close="closeImageModal"
-            @delete-photo="handleRemoveImage"
-          />
-        </div>
-
-        <!-- Right: Details -->
-        <div class="col-12 col-md-8">
-          <!-- Header Section -->
-          <div class="card p-4 shadow-sm mb-4">
-            <div class="d-flex justify-content-between align-items-start mb-3">
-              <div class="flex-grow-1">
-                <!-- Name + LocalType pill / editor -->
-                <div class="d-flex align-items-center gap-2 mb-2">
-                  <!-- Name (view / edit) -->
-                  <div class="flex-grow-1">
-                    <h2 v-if="!isEditing" class="mb-0 fw-bold">{{ locale.name }}</h2>
-                    <div v-else class="mb-0">
-                      <label for="nameInput" class="form-label fw-bold">Name</label>
-                      <input
-                        type="text"
-                        id="nameInput"
-                        class="form-control"
-                        v-model="locale.name"
-                      />
-                    </div>
-                  </div>
-
-                  <!-- LocalType pill in view -->
-                  <span
-                    v-if="!isEditing && locale.localType"
-                    class="badge rounded-pill local-type-pill"
-                  >
-                    {{ localTypeLabel }}
-                  </span>
-
-                  <!-- LocalType dropdown in edit -->
-                  <div v-if="isEditing" style="min-width: 180px">
-                    <label for="localTypeSelect" class="form-label small mb-1">Type</label>
-                    <select
-                      id="localTypeSelect"
-                      class="form-select form-select-sm"
-                      v-model="locale.localType"
-                    >
-                      <option value="" disabled>Select type</option>
-                      <option v-for="opt in localTypeOptions" :key="opt.value" :value="opt.value">
-                        {{ opt.label }}
-                      </option>
-                    </select>
-                  </div>
-                </div>
-
-                <!-- Address -->
-                <div v-if="!isEditing" class="text-muted mb-2">
-                  <i class="fas fa-map-marker-alt me-2"></i> {{ locale.address }}
-                </div>
-                <div v-else class="mb-3">
-                  <label for="addressInput" class="form-label fw-bold">Address</label>
-                  <input
-                    type="text"
-                    id="addressInput"
-                    class="form-control"
-                    v-model="locale.address"
-                  />
-                </div>
-
-                <!-- Star Rating (Not Editable) -->
-                <div class="d-flex align-items-center">
-                  <div class="text-warning me-2">
-                    <i
-                      v-for="n in 5"
-                      :key="n"
-                      :class="[
-                        roundedRating >= n
-                          ? 'fas fa-star'
-                          : roundedRating >= n - 0.5
-                            ? 'fas fa-star-half-alt'
-                            : 'far fa-star',
-                      ]"
-                    ></i>
-                  </div>
-                  <small class="text-muted">({{ locale.ratingAvg }})</small>
-                </div>
-              </div>
-            </div>
-
-            <!-- Description -->
-            <div class="mb-0">
-              <h6 class="fw-bold mb-2">About</h6>
-              <p v-if="!isEditing" class="text-muted mb-0">{{ locale.description }}</p>
-              <textarea
-                v-else
-                id="descriptionInput"
-                class="form-control"
-                rows="4"
-                v-model="locale.description"
-              ></textarea>
-            </div>
-          </div>
-
-          <!-- Information Grid -->
-          <div class="row g-4 mb-4">
-            <!-- Working Hours -->
-            <div class="col-12 col-lg-6">
-              <div class="card p-3 shadow-sm h-100">
-                <h6 class="fw-bold mb-3">
-                  <i class="fas fa-clock me-2 text-primary"></i>Working Hours
-                </h6>
-                <!-- View mode -->
-                <div v-if="!isEditing">
-                  <WorkingHoursTable :workingHours="locale.workingHours"></WorkingHoursTable>
-                </div>
-                <!-- Edit mode -->
-                <div v-else>
-                  <p class="text-muted small mb-2">
-                    Enter time as HH:MM:SS-HH:MM:SS (e.g., 09:00:00-17:30:00). Type "Closed" or
-                    leave blank for closed days.
-                  </p>
-                  <div class="row g-2">
-                    <div class="col-12" v-for="day in daysOfWeek" :key="day">
-                      <label class="form-label small mb-1">{{
-                        day.charAt(0) + day.slice(1).toLowerCase()
-                      }}</label>
-                      <input
-                        type="text"
-                        class="form-control form-control-sm"
-                        v-model="workingHoursInputs[day]"
-                        placeholder="HH:MM:SS-HH:MM:SS or Closed"
-                        @blur="onWorkingHourBlur(day)"
-                      />
-                    </div>
-                  </div>
-                </div>
-              </div>
-            </div>
-
-            <!-- Contact & Menu -->
-            <div class="col-12 col-lg-6">
-              <div class="card p-3 shadow-sm h-100">
-                <h6 class="fw-bold mb-3">
-                  <i class="fas fa-phone me-2 text-primary"></i>Contact & Menu
-                </h6>
-                <div v-if="!isEditing">
-                  <div v-if="locale.contact.phone" class="mb-2">
-                    <i class="fas fa-phone-alt me-2 text-muted"></i>
-                    <span class="text-dark">{{ locale.contact.phone }}</span>
-                  </div>
-                  <div v-if="locale.contact.email" class="mb-3">
-                    <i class="fas fa-envelope me-2 text-muted"></i>
-                    <span class="text-dark">{{ locale.contact.email }}</span>
-                  </div>
-                  <div class="pt-2 border-top">
-                    <strong class="d-block mb-1">Menu</strong>
-                    <a
-                      v-if="locale.menuLink"
-                      :href="locale.menuLink"
-                      target="_blank"
-                      class="text-decoration-none"
-                    >
-                      <i class="fas fa-external-link-alt me-1"></i>View Menu
-                    </a>
-                    <span v-else class="text-muted small">Not available</span>
-                  </div>
-                </div>
-                <div v-else>
-                  <div class="mb-2">
-                    <label for="phoneInput" class="form-label small">Phone</label>
-                    <input
-                      type="text"
-                      id="phoneInput"
-                      class="form-control form-control-sm"
-                      v-model="locale.contact.phone"
-                    />
-                  </div>
-                  <div class="mb-2">
-                    <label for="emailInput" class="form-label small">Email</label>
-                    <input
-                      type="email"
-                      id="emailInput"
-                      class="form-control form-control-sm"
-                      v-model="locale.contact.email"
-                    />
-                  </div>
-                  <div>
-                    <label for="menuLinkInput" class="form-label small">Menu Link</label>
-                    <input
-                      type="url"
-                      id="menuLinkInput"
-                      class="form-control form-control-sm"
-                      v-model="locale.menuLink"
-                      placeholder="https://example.com/menu"
-                    />
-                  </div>
-                </div>
-              </div>
-            </div>
-          </div>
-
-          <!-- Services Section -->
-          <div class="card p-3 shadow-sm mb-4">
-            <h6 class="fw-bold mb-3">
-              <i class="fas fa-concierge-bell me-2 text-primary"></i>Services & Amenities
-            </h6>
-
-            <!-- View mode -->
-            <div v-if="!isEditing">
-              <div v-if="locale.services && locale.services.length > 0" class="services-grid">
-                <span
-                  v-for="(service, idx) in locale.services"
-                  :key="service + idx"
-                  class="service-badge"
-                  :title="getEnumLabel(service, 'ProvidedService')"
-                >
-                  {{ getEnumLabel(service, 'ProvidedService') }}
-                </span>
-              </div>
-              <p v-else class="text-muted small mb-0">No services listed</p>
-            </div>
-
-            <!-- Edit mode -->
-            <div v-else>
-              <label for="servicesSelect" class="form-label small">Services</label>
-              <select
-                id="servicesSelect"
-                class="form-select form-select-sm"
-                v-model="locale.services"
-                multiple
-                size="5"
-              >
-                <option v-for="opt in providedServiceOptions" :key="opt.value" :value="opt.value">
-                  {{ opt.label }}
-                </option>
-              </select>
-              <small class="text-muted d-block mt-1">
-                Hold Ctrl/Cmd (or use Shift) to multi-select.
-              </small>
-            </div>
-          </div>
-
-          <!--Rating component-->
-          <div class="card p-3 shadow-sm mb-4" v-if="userStore.data.role === 'ROLE_CUSTOMER'">
-            <RatingsForLocal :local-id="this.local_id" @rating-updated="fetchLocaleData" />
-          </div>
-
-          <!-- Events Section -->
-          <div class="card p-4 shadow-sm mb-4">
-            <div class="d-flex justify-content-between align-items-center mb-3">
-              <h6 class="fw-bold mb-0">
-                <i class="fas fa-calendar-alt me-2 text-primary"></i>Upcoming Events
-              </h6>
-              <button
-                v-if="userStore.isLocaleManager"
-                class="btn btn-primary btn-sm"
-                @click="isEventModalVisible = true"
-              >
-                <i class="fas fa-plus me-1"></i> Add Event
-              </button>
-            </div>
-            <div v-if="locale.events && locale.events.length > 0">
-              <events_carousel
-                @edit-started="startEditingEvent"
-                :all-events="eventsForCarousel"
-                @event-deleted="deleteEvent"
-              />
-            </div>
-            <div v-else class="text-center py-4">
-              <i class="fas fa-calendar-times fa-2x text-muted mb-2"></i>
-              <p class="text-muted mb-0">No events scheduled</p>
-            </div>
-          </div>
-
-          <!-- Main Action Buttons -->
-          <div class="card p-3 shadow-sm">
-            <div class="d-flex flex-wrap gap-2">
-              <template v-if="userStore.data.role === 'ROLE_CUSTOMER'">
-                <button @click="modalOpen = true" class="btn btn-dark">
-                  <i class="fas fa-calendar-check me-1"></i> Reserve
-                </button>
-
-                <make-reservation-modal
-                  :localId="locale.id"
-                  :show-modal="modalOpen"
-                  @open-modal="modalOpen = true"
-                  @close-modal="modalOpen = false"
-                ></make-reservation-modal>
-
-                <button
-                  :class="['btn', isCurrentLocaleFavourite ? 'btn-danger' : 'btn-outline-danger']"
-                  @click="toggleFavouriteLocal(locale.id)"
-                >
-                  <i :class="[isCurrentLocaleFavourite ? 'fas' : 'far', 'fa-heart', 'me-1']"></i>
-                  {{ isCurrentLocaleFavourite ? 'Remove from Favourites' : 'Add to Favourites' }}
-                </button>
-              </template>
-
-              <template v-if="userStore.data.role === 'ROLE_LOCAL_MANAGER'">
-                <button v-if="!isEditing" class="btn btn-dark" @click="startEditing">
-                  <i class="fas fa-edit me-1"></i> Edit Details
-                </button>
-                <template v-else>
-                  <button class="btn btn-success" @click="saveLocalChanges">
-                    <i v-if="!isSaveChangesLoading" class="fas fa-save me-1"></i>
-                    <span v-else><LoadingIcon></LoadingIcon></span>
-                    Save
-                  </button>
-                  <button class="btn btn-secondary" @click="cancelEditing">
-                    <i class="fas fa-times me-1"></i> Cancel
-                  </button>
-                </template>
-              </template>
-
-              <router-link
-                to="/"
-                class="btn btn-outline-secondary"
-                v-if="userStore.data.role !== 'ROLE_LOCAL_MANAGER'"
-                ><i class="fas fa-arrow-left me-1"></i> Back</router-link
-              >
-            </div>
-          </div>
-        </div>
-      </div>
-    </div>
-  </div>
-  <AddEventModal
-    :show="isEventModalVisible"
-    @close="
-      isEventModalVisible = false;
-      targetEditEvent = null;
-    "
-    @event-added="addEvent"
-    @event-updated="addEvent"
-    :event-to-edit="targetEditEvent"
-  />
-</template>
-
-<style scoped>
-.locale-details-wrapper {
-  background-color: #f3f5f8;
-}
-
-.object-fit-cover {
-  object-fit: cover;
-  width: 100%;
-  height: auto;
-}
-
-.services-grid {
-  display: flex;
-  flex-wrap: wrap;
-  gap: 0.5rem;
-}
-
-.service-badge {
-  display: inline-block;
-  padding: 0.5rem 1rem;
-  background-color: #e7f3ff;
-  color: #0d6efd;
-  border: 1px solid #b3d9ff;
-  border-radius: 0.375rem;
-  font-size: 0.875rem;
-  font-weight: 500;
-  transition: all 0.2s ease;
-}
-
-.service-badge:hover {
-  background-color: #cfe2ff;
-  border-color: #86b7fe;
-  transform: translateY(-1px);
-}
-
-.card {
-  border: none;
-  border-radius: 0.5rem;
-}
-
-.card h6 {
-  color: #212529;
-  font-size: 1rem;
-}
-
-.card h2 {
-  color: #212529;
-  font-size: 1.75rem;
-}
-
-.local-type-pill {
-  background-color: #e9f2ff;
-  color: #f55845;
-  font-size: 1rem;
-  font-weight: 600;
-  padding: 0.35rem 0.65rem;
-  border: 1px solid #f55845;
-  text-transform: none;
-  border-radius: 999px;
-}
-</style>
Index: serveNGo-frontend/src/components/Project/Local/Locale_listing_container.vue
===================================================================
--- ReserveNGo-frontend/src/components/Project/Local/Locale_listing_container.vue	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,82 +1,0 @@
-<script>
-import LocalInLocalListing from '@/components/Project/Local/local_in_local_listing.vue'
-import { defineComponent } from 'vue'
-import { userStore } from '@/PiniaStores/UserStore.js'
-
-export default defineComponent({
-  components: { LocalInLocalListing },
-  props: {
-    mode: String,
-    locals: {
-      type: Array,
-      default: () => [],
-    },
-    favouriteLocals: {
-      type: Array,
-      default: () => [],
-    },
-  },
-  data() {
-    return {
-      userStore: userStore(),
-      selectedLocalId: null,
-      hoveredLocalId: null,
-    }
-  },
-
-  computed: {
-    displayedLocals() {
-      return this.mode === 'favourites' ? this.favouriteLocals : this.locals
-    },
-  },
-
-  methods: {
-    toggleFavourite(id) {
-      // Emit to parent (Home) which is the single source of truth
-      this.$emit('toggle-favourite', id)
-    },
-  },
-
-  // NOTE: removed mounted fetch of favourites — Home controls that
-})
-</script>
-
-<template>
-  <div id="container" class="container">
-    <h5>Locals</h5>
-
-    <div v-if="mode === 'favourites'">
-      <div v-if="favouriteLocals.length === 0" class="text-center text-muted py-5">
-        <i class="fas fa-calendar-times fa-3x mb-3"></i>
-        <p>You don't have any favourite locals yet.</p>
-      </div>
-    </div>
-
-    <div v-else>
-      <div v-if="locals.length === 0" class="text-center text-muted py-5">
-        <i class="fas fa-calendar-times fa-3x mb-3"></i>
-        <p>No locals available at the moment.</p>
-      </div>
-    </div>
-
-    <div v-for="local in displayedLocals" :key="local.id">
-      <LocalInLocalListing
-        :local="local"
-        :isFavoured="favouriteLocals.map((f) => f.id).includes(local.id)"
-        :isSelected="selectedLocalId === local.id"
-        :isHovered="hoveredLocalId === local.id"
-        :mode="mode"
-        @select="selectedLocalId = local.id"
-        @hover-enter="hoveredLocalId = local.id"
-        @hover-leave="hoveredLocalId = null"
-        @toggle-favourite="toggleFavourite"
-      />
-    </div>
-  </div>
-</template>
-
-<style scoped>
-#container {
-  margin: 20px auto;
-}
-</style>
Index: serveNGo-frontend/src/components/Project/Local/local_in_local_listing.vue
===================================================================
--- ReserveNGo-frontend/src/components/Project/Local/local_in_local_listing.vue	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,263 +1,0 @@
-<script>
-import { userStore } from '@/PiniaStores/UserStore.js'
-import { restaurantStore } from '@/PiniaStores/restaurantStore.js'
-import { config } from '@/constants/Api_config.js'
-import MakeReservationModal from '@/components/Project/Customer/makeReservationModal.vue'
-import noImg from '@/assets/no-img.png'
-import { getEnumLabel } from '@/utils/enumLabels.ts'
-
-export default {
-  components: { MakeReservationModal },
-  props: {
-    local: { type: Object, required: true },
-    isFavoured: { type: Boolean, default: false },
-    isSelected: Boolean,
-    isHovered: Boolean,
-    mode: String,
-  },
-  data() {
-    return {
-      userStore_: userStore(),
-      modalOpen: false,
-    }
-  },
-  computed: {
-    locale_logo() {
-      const url = new URL(this.local.logo, config.API_BASE_URL)
-      return url.toString()
-    },
-    openStatus() {
-      if (this.local && typeof this.local.open === 'boolean') {
-        return this.local.open ? 'Open' : 'Closed'
-      }
-      return 'Status unavailable'
-    },
-  },
-  methods: {
-    onImageError(event) {
-      event.target.src = noImg
-    },
-    handleClick() {
-      const store = restaurantStore()
-      store.setRestaurant(
-        this.local.id,
-        this.local.name,
-        this.local.description,
-        this.local.address,
-        this.local.workingHours,
-        this.local.logo,
-        this.local.averageRating,
-      )
-      this.$emit('select', this.local.id)
-    },
-    addToFavorites(e) {
-      e.stopPropagation()
-      this.$emit('toggle-favourite', this.local.id)
-    },
-    handleMouseEnter() {
-      this.$emit('hover-enter')
-    },
-    handleMouseLeave() {
-      this.$emit('hover-leave')
-    },
-    localTypeLabel(local) {
-      return getEnumLabel(local?.localType, 'LocalType')
-    },
-  },
-}
-</script>
-
-<template>
-  <div
-    id="container"
-    class="row align-items-center my-3 p-3 rounded shadow-sm"
-    :class="{ selected: isSelected }"
-    @mouseenter="handleMouseEnter"
-    @mouseleave="handleMouseLeave"
-    @click="handleClick"
-  >
-    <!-- Logo -->
-    <div class="col-auto pe-0">
-      <img
-        :src="locale_logo"
-        alt="Logo"
-        class="rounded"
-        style="width: 60px; height: 60px; object-fit: cover"
-        @error="onImageError"
-      />
-    </div>
-
-    <!-- Info -->
-    <div class="col info ps-3">
-      <div class="d-flex align-items-center gap-2">
-        <h5 class="mb-0 fw-bold">{{ local.name }}</h5>
-        <!-- Local Type Badge -->
-        <span class="local-type-badge">
-          {{ localTypeLabel(local) }}
-        </span>
-      </div>
-      <p class="mb-1 text-muted"><i class="fas fa-map-marker-alt me-1"></i>{{ local.address }}</p>
-      <p class="mb-1 text-muted">
-        <i class="fas fa-clock me-2 text-secondary"></i>
-        <span
-          :class="{ 'text-danger': openStatus === 'Closed', 'text-success': openStatus === 'Open' }"
-        >
-          {{ openStatus }}
-        </span>
-      </p>
-      <p class="mb-0 text-muted">
-        <i class="fas fa-star text-warning me-1"></i>{{ local.averageRating }}
-      </p>
-    </div>
-
-    <!-- Buttons -->
-    <div class="col-auto d-flex align-items-center">
-      <transition name="fade">
-        <div class="button-group d-flex align-items-center" v-if="isHovered || isSelected">
-          <!-- Favourite button (same style/logic as events) -->
-          <button
-            class="btn btn-favourite"
-            :class="{ active: isFavoured }"
-            @click.stop="addToFavorites"
-            v-if="userStore_.isCustomer"
-          >
-            <i class="fas fa-heart me-1"></i>
-            {{ isFavoured ? 'Remove from Favourites' : 'Add to Favourites' }}
-          </button>
-
-          <div class="action-buttons ms-2 d-flex align-items-center">
-            <router-link :to="`/more_details/${local.id}`">
-              <button class="btn btn-outline-dark me-2">
-                <i class="fas fa-info-circle me-1"></i> More details
-              </button>
-            </router-link>
-
-            <button
-              @click="modalOpen = true"
-              v-if="userStore_.data.role === 'ROLE_CUSTOMER' && mode === 'all'"
-              class="btn btn-dark"
-            >
-              <i class="fas fa-calendar-check me-1"></i> Make reservation
-            </button>
-
-            <make-reservation-modal
-              :localId="local.id"
-              :show-modal="modalOpen"
-              @open-modal="modalOpen = true"
-              @close-modal="modalOpen = false"
-            ></make-reservation-modal>
-          </div>
-        </div>
-      </transition>
-    </div>
-  </div>
-</template>
-
-<style scoped>
-#container {
-  border-left: 3px solid transparent;
-  background: #fff;
-  transition: all 0.2s ease;
-  cursor: pointer;
-  position: relative;
-}
-
-#container:not(.selected) {
-  border-left-color: #5ea5bc;
-}
-
-#container:hover {
-  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.2);
-  background-color: #f9f9f9;
-}
-
-#container.selected {
-  background-color: #fff;
-}
-
-#container.selected::before {
-  content: '';
-  position: absolute;
-  top: 0;
-  left: 0;
-  width: 100%;
-  height: 100%;
-  border: 3px solid #5ea5bc;
-  border-radius: 8px;
-  animation: drawBorder 0.3s linear forwards;
-  pointer-events: none;
-  z-index: 1;
-}
-
-@keyframes drawBorder {
-  0% {
-    clip-path: polygon(0 0, 0 0, 0 0, 0 0);
-  }
-  25% {
-    clip-path: polygon(0 0, 100% 0, 100% 0, 0 0);
-  }
-  50% {
-    clip-path: polygon(0 0, 100% 0, 100% 100%, 0 0);
-  }
-  75% {
-    clip-path: polygon(0 0, 100% 0, 100% 100%, 0 100%);
-  }
-  100% {
-    clip-path: polygon(0 0, 100% 0, 100% 100%, 0 100%);
-  }
-}
-
-.button-group {
-  transition:
-    opacity 0.3s ease,
-    transform 0.3s ease;
-  height: 60px;
-  align-items: center;
-}
-
-.btn-favourite {
-  background-color: #fff;
-  border: 2px solid #5ea5bc;
-  color: #5ea5bc;
-  padding: 0.375rem 0.75rem;
-  transition: all 0.2s ease;
-  white-space: nowrap;
-}
-
-.btn-favourite:hover {
-  background-color: #5ea5bc;
-  border-color: #5ea5bc;
-  color: #fff;
-}
-
-.btn-favourite.active {
-  background-color: #e74c3c;
-  border-color: #e74c3c;
-  color: #fff;
-}
-
-.btn-favourite.active:hover {
-  background-color: #c0392b;
-  border-color: #c0392b;
-}
-
-.fade-enter-active,
-.fade-leave-active {
-  transition: opacity 0.2s ease;
-}
-.fade-enter-from,
-.fade-leave-to {
-  opacity: 0;
-}
-
-.local-type-badge {
-  background-color: #eef5f8;
-  color: #f55845;
-  border: 1px solid #f55845;
-  border-radius: 999px;
-  padding: 2px 10px;
-  font-size: 0.85rem;
-  font-weight: 600;
-  white-space: nowrap;
-}
-</style>
Index: serveNGo-frontend/src/components/Project/Local/working-hours-table.vue
===================================================================
--- ReserveNGo-frontend/src/components/Project/Local/working-hours-table.vue	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,88 +1,0 @@
-<script lang="ts">
-export default {
-  props: ['workingHours'],
-
-  computed: {
-    daysOfWeek() {
-      return ['MONDAY', 'TUESDAY', 'WEDNESDAY', 'THURSDAY', 'FRIDAY', 'SATURDAY', 'SUNDAY']
-    },
-
-    workingHoursMap() {
-      if (!this.workingHours) return {}
-      const map = {}
-      /* closeTime:"17:00:00"
-      dayOfWeek:"MONDAY"
-      openTime:"09:00:00"*/
-
-      this.workingHours.forEach((wh) => {
-        if (wh.dayOfWeek) {
-          const dayKey = wh.dayOfWeek.toUpperCase()
-          map[dayKey] = {
-            openTime: wh.openTime || '',
-            closeTime: wh.closeTime || '',
-          }
-        }
-      })
-      return map
-    },
-
-    daysWithHours() {
-      return this.daysOfWeek.map((day) => {
-        const hours = this.workingHoursMap[day]
-        return {
-          day: day,
-          hours:
-            hours && hours.openTime && hours.closeTime
-              ? `${hours.openTime} - ${hours.closeTime}`
-              : 'Closed',
-        }
-      })
-    },
-  },
-
-  methods: {
-    formatDayName(day) {
-      return day.charAt(0) + day.slice(1).toLowerCase()
-    },
-  },
-}
-</script>
-
-<template>
-  <div class="table-responsive">
-    <table class="table table-sm table-borderless mb-0">
-      <thead>
-        <tr>
-          <th class="text-muted fw-normal small">Day</th>
-          <th class="text-muted fw-normal small">Hours</th>
-        </tr>
-      </thead>
-      <tbody>
-        <tr v-for="item in daysWithHours" :key="item.day">
-          <td class="fw-medium">{{ formatDayName(item.day) }}</td>
-          <td>
-            <span v-if="item.hours" class="text-dark">{{ item.hours }}</span>
-            <span v-else class="text-muted fst-italic small">Closed</span>
-          </td>
-        </tr>
-      </tbody>
-    </table>
-  </div>
-</template>
-
-<style scoped>
-.table th {
-  padding: 0.5rem;
-  font-size: 0.875rem;
-  border-bottom: 1px solid #dee2e6;
-}
-
-.table td {
-  padding: 0.5rem;
-  vertical-align: middle;
-}
-
-.table tbody tr:not(:last-child) td {
-  border-bottom: 1px solid #f0f0f0;
-}
-</style>
Index: serveNGo-frontend/src/components/Project/Manager/ManagerDashboard.vue
===================================================================
--- ReserveNGo-frontend/src/components/Project/Manager/ManagerDashboard.vue	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,317 +1,0 @@
-<script>
-import { userStore } from '@/PiniaStores/UserStore.js'
-import LoadingIcon from '@/components/Project/Utility/LoadingIcon.vue'
-import { isValidEmail } from '@/utils/utilFunctions.js'
-import { useLocalManager } from '@/repository/LocalManager.ts'
-import { useToasts } from '@/composables/useToast.js'
-
-export default {
-  components: { LoadingIcon },
-  data() {
-    return {
-      workers: [],
-      workersForLocal: [],
-      localId: null,
-      user: userStore(),
-      showAddWorkerModal: false,
-      positions: ['CHEF', 'COOK', 'WAITER', 'BARTENDER', 'MANAGER'],
-      sortKey: '',
-      sortOrder: 'asc',
-      showToast: useToasts().showToast,
-      emailToWorker: '',
-      isEmailSending: false,
-
-      assigningWorkerId: null,
-      removingWorkerId: null,
-    }
-  },
-  computed: {
-    sortedWorkers() {
-      if (!this.sortKey) return this.workersForLocal
-      return [...this.workersForLocal].sort((a, b) => {
-        let valueA = a[this.sortKey] || ''
-        let valueB = b[this.sortKey] || ''
-        if (typeof valueA === 'string') {
-          valueA = valueA.toLowerCase()
-          valueB = valueB.toLowerCase()
-        }
-        if (valueA < valueB) return this.sortOrder === 'asc' ? -1 : 1
-        if (valueA > valueB) return this.sortOrder === 'asc' ? 1 : -1
-        return 0
-      })
-    },
-  },
-  methods: {
-    sortBy(key) {
-      if (this.sortKey === key) {
-        this.sortOrder = this.sortOrder === 'asc' ? 'desc' : 'asc'
-      } else {
-        this.sortKey = key
-        this.sortOrder = 'asc'
-      }
-    },
-
-    async fetchWorkersForLocal() {
-      try {
-        this.workersForLocal = await useLocalManager.getLocalWorkers()
-      } catch (error) {
-        console.error('Failed to fetch local workers:', error)
-        this.showToast('Could not load your workers.', 'error')
-      }
-    },
-    async fetchWorkers() {
-      try {
-        this.workers = await useLocalManager.getAvailableWorkers()
-      } catch (error) {
-        console.error('Failed to fetch available workers:', error)
-        this.showToast('Could not load available workers.', 'error')
-      }
-    },
-    async fetchLocal() {
-      try {
-        const local = await useLocalManager.getMyLocal()
-        this.localId = local.id
-      } catch (error) {
-        console.error('Failed to fetch your local:', error)
-        this.showToast('Could not load your local.', 'error')
-      }
-    },
-    async assignWorker(worker) {
-      this.assigningWorkerId = worker.id
-      try {
-        await useLocalManager.assignWorker(worker.id)
-        this.showToast(`Assigned ${worker.firstName} successfully.`, 'success')
-        await this.fetchWorkers()
-        await this.fetchWorkersForLocal()
-      } catch (error) {
-        this.showToast(error.response || 'Failed to assign worker.', 'error')
-      } finally {
-        this.assigningWorkerId = null
-      }
-    },
-    async removeWorker(worker) {
-      this.removingWorkerId = worker.id
-      try {
-        await useLocalManager.removeWorker(worker.id)
-        this.showToast(`Removed ${worker.firstName} successfully.`, 'success')
-        await this.fetchWorkersForLocal()
-      } catch (error) {
-        this.showToast(error.response || 'Failed to remove worker.', 'error')
-      } finally {
-        this.removingWorkerId = null
-      }
-    },
-    async changeWorkerPosition(workerId, position) {
-      try {
-        await useLocalManager.changeWorkerPosition(workerId, position)
-        this.showToast(`Position updated successfully.`, 'success')
-      } catch (error) {
-        this.showToast(error.response?.data?.message || 'Failed to change position.', 'error')
-        await this.fetchWorkersForLocal()
-      }
-    },
-    openAddWorkerModal() {
-      this.fetchWorkers()
-      this.showAddWorkerModal = true
-    },
-    async sendEmailToWorker() {
-      if (this.emailToWorker === '') {
-        this.showToast('Fill out the email form', 'error')
-        return
-      }
-      if (!isValidEmail(this.emailToWorker)) {
-        this.showToast('Please enter a valid email format', 'error')
-        return
-      }
-
-      this.isEmailSending = true
-      try {
-        await useLocalManager.inviteWorker(this.emailToWorker)
-        this.showToast(`Invite sent to ${this.emailToWorker}`, 'success')
-        this.emailToWorker = ''
-      } catch (error) {
-        this.showToast(error.response?.data?.message || 'Failed to send email.', 'error')
-      } finally {
-        this.isEmailSending = false
-      }
-    },
-  },
-  mounted() {
-    this.fetchLocal()
-    this.fetchWorkersForLocal()
-  },
-}
-</script>
-
-<template>
-  <div class="container mt-4">
-    <h4 class="mb-3">Workers Overview</h4>
-    <hr>
-    <!-- Add Worker Modal -->
-    <div
-      v-if="showAddWorkerModal"
-      class="modal fade show d-block"
-      tabindex="-1"
-      style="background: rgba(0, 0, 0, 0.5)"
-    >
-      <div class="modal-dialog modal-lg">
-        <div class="modal-content">
-          <div class="modal-header">
-            <h5 class="modal-title">Add Worker</h5>
-            <button type="button" class="btn-close" @click="showAddWorkerModal = false"></button>
-          </div>
-          <div class="modal-body">
-            <ul class="list-group">
-              <li
-                v-for="worker in workers"
-                :key="worker.id"
-                class="list-group-item d-flex justify-content-between align-items-center"
-              >
-                <span>{{ worker.firstName }} {{ worker.lastName }} - {{ worker.email }}</span>
-                <button
-                  class="btn btn-sm btn-success"
-                  @click="assignWorker(worker)"
-                  :disabled="assigningWorkerId === worker.id"
-                >
-                  <LoadingIcon v-if="assigningWorkerId === worker.id" />
-                  <span v-else>Add</span>
-                </button>
-              </li>
-            </ul>
-          </div>
-        </div>
-      </div>
-    </div>
-
-    <!-- Workers Table -->
-    <div class="table-responsive shadow-sm table-container">
-      <table class="table table-striped table-hover align-middle">
-        <thead class="table-light">
-          <tr>
-            <th style="cursor: pointer" @click="sortBy('firstName')">
-              First Name
-              <span v-if="sortKey === 'firstName'">{{ sortOrder === 'asc' ? '↑' : '↓' }}</span>
-            </th>
-            <th style="cursor: pointer" @click="sortBy('lastName')">
-              Last Name
-              <span v-if="sortKey === 'lastName'">{{ sortOrder === 'asc' ? '↑' : '↓' }}</span>
-            </th>
-            <th>Email</th>
-            <th>Phone Number</th>
-            <th style="cursor: pointer" @click="sortBy('position')">
-              Position
-              <span v-if="sortKey === 'position'">{{ sortOrder === 'asc' ? '↑' : '↓' }}</span>
-            </th>
-            <th class="text-end">Actions</th>
-          </tr>
-        </thead>
-        <tbody>
-          <tr v-for="worker in sortedWorkers" :key="worker.id">
-            <td>{{ worker.firstName }}</td>
-            <td>{{ worker.lastName }}</td>
-            <td>{{ worker.email }}</td>
-            <td>{{ worker.phoneNumber }}</td>
-            <td>
-              <select
-                class="form-select form-select-sm"
-                :value="worker.position"
-                @change="changeWorkerPosition(worker.id, $event.target.value)"
-              >
-                <option :value="null" selected disabled>
-                  {{ worker.position ? worker.position : 'Assign Position' }}
-                </option>
-                <option v-for="pos in positions" :key="pos" :value="pos">{{ pos }}</option>
-              </select>
-            </td>
-            <td class="text-end">
-              <button
-                class="btn btn-sm btn-outline-danger"
-                @click="removeWorker(worker)"
-                :disabled="removingWorkerId === worker.id"
-              >
-                <LoadingIcon v-if="removingWorkerId === worker.id" />
-                <span v-else>Remove</span>
-              </button>
-            </td>
-          </tr>
-        </tbody>
-      </table>
-    </div>
-
-    <button class="btn btn-success mt-3" @click="openAddWorkerModal">+ Add Worker</button>
-    <div id="sendMailGroup" class="mt-3">
-      <button @click="sendEmailToWorker" class="btn btn-success">
-        <LoadingIcon v-if="isEmailSending" />
-        <span v-else>+ </span>
-        Send worker register mail
-      </button>
-      <input
-        v-model="emailToWorker"
-        class="form-control"
-        type="text"
-        placeholder="Enter worker's email"
-      />
-    </div>
-  </div>
-</template>
-
-<style scoped>
-html,
-body {
-  margin: 0;
-  padding: 0;
-  height: 100vh;
-  overflow: hidden;
-}
-.container {
-  max-width: 1200px;
-  margin: 0 auto;
-  height: 100%;
-  display: flex;
-  flex-direction: column;
-  padding-bottom: 20px;
-  overflow: hidden;
-}
-.table-container {
-  flex: 1 1 auto;
-  overflow-y: auto;
-}
-table {
-  font-size: 0.95rem;
-  table-layout: fixed;
-  width: 100%;
-}
-th,
-td {
-  white-space: nowrap;
-  overflow: hidden;
-  text-overflow: ellipsis;
-}
-thead th {
-  position: sticky;
-  top: 0;
-  background-color: #f8f9fa;
-  z-index: 2;
-  user-select: none;
-}
-th span {
-  margin-left: 5px;
-  font-size: 0.8rem;
-}
-.modal {
-  display: block;
-}
-#sendMailGroup {
-  display: flex;
-}
-#sendMailGroup > .btn {
-  flex-shrink: 0;
-  border-bottom-right-radius: 0;
-  border-top-right-radius: 0;
-}
-#sendMailGroup > .form-control {
-  flex-grow: 1;
-  border-bottom-left-radius: 0;
-  border-top-left-radius: 0;
-}
-</style>
Index: serveNGo-frontend/src/components/Project/Reservation/My_reservations.vue
===================================================================
--- ReserveNGo-frontend/src/components/Project/Reservation/My_reservations.vue	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,185 +1,0 @@
-<script>
-import ReservationCard from '@/components/Project/Reservation/reservation_.vue'
-import EditReservationModal from '@/components/Project/Customer/EditReservationModal.vue'
-import { useReservations } from '@/repository/Reservations.ts'
-import { useToasts } from '@/composables/useToast.js'
-
-export default {
-  name: 'MyReservationsPage',
-  components: { ReservationCard, EditReservationModal },
-  data() {
-    return {
-      reservations: [],
-      loading: false,
-      error: null,
-      cancellingId: null,
-      showEditModal: false,
-      targetReservation: null,
-      selectionMode: false,
-      selectedIds: [],
-    }
-  },
-  created() {
-    this.fetchReservations()
-  },
-  methods: {
-    async fetchReservations() {
-      this.loading = true
-      this.error = null
-      try {
-        const data = await useReservations.listMyReservations()
-        this.reservations = Array.isArray(data) ? data : []
-      } catch (err) {
-        console.error(err)
-        this.error = err?.response?.message || 'Failed to load reservations.'
-      } finally {
-        this.loading = false
-      }
-    },
-    async onCancelReservation(res) {
-      console.log('WHAT IS RESERVATION HERE', res)
-      if (!res) return
-      if (!confirm('Are you sure you want to cancel this reservation?')) return
-      try {
-        const { showToast } = useToasts()
-        this.cancellingId = res.id ?? null
-        await useReservations.cancelReservation(res.id)
-        this.reservations = this.reservations.map((r) =>
-          r.id === res.id ? { ...r, status: 'CANCELLED' } : r,
-        )
-        showToast('Reservation cancelled successfully.', 'success')
-      } catch (err) {
-        console.error(err)
-        const { showToast } = useToasts()
-        const message =
-          err?.response?.message || 'Failed to cancel reservation. Please try again later.'
-        showToast(message, 'error')
-      } finally {
-        this.cancellingId = null
-      }
-    },
-    onEditReservation(res) {
-      this.targetReservation = res
-      this.showEditModal = true
-    },
-    onEditedReservation(updated) {
-      const id = updated?.id
-      if (id != null) {
-        this.reservations = this.reservations.map((r) => (r.id === id ? { ...r, ...updated } : r))
-      } else if (this.targetReservation) {
-        this.reservations = this.reservations.map((r) =>
-          r === this.targetReservation ? { ...r, ...updated } : r,
-        )
-      }
-      this.showEditModal = false
-      this.targetReservation = null
-    },
-    startSelection() {
-      this.selectionMode = true
-      this.selectedIds = []
-    },
-    cancelSelection() {
-      this.selectionMode = false
-      this.selectedIds = []
-    },
-    toggleSelect(res) {
-      const id = res?.id ?? null
-      if (id == null) return
-      const idx = this.selectedIds.indexOf(id)
-      if (idx >= 0) this.selectedIds.splice(idx, 1)
-      else this.selectedIds.push(id)
-    },
-    async confirmDeleteSelected() {
-      if (!this.selectedIds.length) return
-      if (!confirm(`Delete ${this.selectedIds.length} reservation(s)?`)) return
-      try {
-        const { showToast } = useToasts()
-        await useReservations.deleteReservations({ reservationIds: this.selectedIds })
-        // Remove deleted from a list
-        const set = new Set(this.selectedIds)
-        this.reservations = this.reservations.filter((r) => !set.has(r.id))
-        showToast('Selected reservations deleted successfully.', 'success')
-        this.cancelSelection()
-      } catch (err) {
-        console.error(err)
-        const { showToast } = useToasts()
-        const message = err?.response?.message || 'Failed to delete selected reservations.'
-        showToast(message, 'error')
-      }
-    },
-  },
-}
-</script>
-
-<template>
-  <div class="container-xxl py-4">
-    <h4 class="mb-3">My reservations</h4>
-    <hr>
-    <div v-if="loading" class="text-center py-5">
-      <div class="spinner-border text-primary" role="status">
-        <span class="visually-hidden">Loading...</span>
-      </div>
-    </div>
-
-    <div v-else>
-      <div v-if="error" class="alert alert-danger">{{ error }}</div>
-
-      <div v-if="reservations.length === 0" class="text-center text-muted py-5">
-        <i class="far fa-calendar-times fa-3x mb-3"></i>
-        <p class="mb-0">No active reservations.</p>
-      </div>
-
-      <div v-else>
-        <ReservationCard
-          v-for="r in reservations"
-          :key="r.id ?? `${r.localName}-${r.timeOfReservation}`"
-          :reservation="r"
-          :can-cancel="(r.status || '').toUpperCase() !== 'CANCELLED'"
-          :selection-mode="selectionMode"
-          :selected="selectedIds.includes(r.id)"
-          @cancel="onCancelReservation"
-          @edit="onEditReservation"
-          @toggle-select="toggleSelect"
-        />
-        <!-- Top controls: place at top right above the first card -->
-        <div class="position-sticky" style="top: 70px">
-          <div class="d-flex justify-content-end mt-2">
-            <template v-if="!selectionMode">
-              <button
-                class="btn btn-outline-danger btn-sm"
-                @click="startSelection"
-                :disabled="reservations.length === 0"
-              >
-                <i class="fas fa-trash-alt me-1"></i> Delete Reservations
-              </button>
-            </template>
-            <template v-else>
-              <div class="btn-group">
-                <button
-                  class="btn btn-danger btn-sm"
-                  :disabled="selectedIds.length === 0"
-                  @click="confirmDeleteSelected"
-                >
-                  <i class="fas fa-check me-1"></i> Confirm delete ({{ selectedIds.length }})
-                </button>
-                <button class="btn btn-secondary btn-sm" @click="cancelSelection">Cancel</button>
-              </div>
-            </template>
-          </div>
-        </div>
-      </div>
-    </div>
-
-    <EditReservationModal
-      :show-modal="showEditModal"
-      :reservation="targetReservation"
-      @close-modal="
-        showEditModal = false;
-        targetReservation = null;
-      "
-      @edited="onEditedReservation"
-    />
-  </div>
-</template>
-
-<style scoped></style>
Index: serveNGo-frontend/src/components/Project/Reservation/reservation_.vue
===================================================================
--- ReserveNGo-frontend/src/components/Project/Reservation/reservation_.vue	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,129 +1,0 @@
-<script>
-import { config } from '@/constants/Api_config'
-import noImg from '@/assets/no-img.png'
-
-export default {
-  name: 'ReservationCard',
-  props: {
-    reservation: {
-      type: Object,
-      required: true,
-    },
-    canCancel: {
-      type: Boolean,
-      default: true,
-    },
-    canEdit: {
-      type: Boolean,
-      default: true,
-    },
-    selectionMode: {
-      type: Boolean,
-      default: false,
-    },
-    selected: {
-      type: Boolean,
-      default: false,
-    },
-  },
-  emits: ['cancel', 'edit', 'toggle-select'],
-  computed: {
-    logoUrl() {
-      const path = this.reservation.localLogo
-      if (!path) return noImg
-      try {
-        const url = new URL(path, config.API_BASE_URL)
-        return url.toString()
-      } catch {
-        return config.API_BASE_URL + path
-      }
-    },
-    isCancelled() {
-      const status = (this.reservation.status || '').toString().toUpperCase()
-      // Support both British and American spellings
-      return status === 'CANCELLED' || status === 'CANCELED'
-    },
-    isActive() {
-      return !this.isCancelled
-    },
-    formattedDateTime() {
-      try {
-        const d = new Date(this.reservation.timeOfReservation)
-        return d.toLocaleString()
-      } catch {
-        return this.reservation.timeOfReservation
-      }
-    },
-    statusBadgeClass() {
-      const status = (this.reservation.status || '').toString().toUpperCase()
-      if (status === 'CONFIRMED') return 'bg-success'
-      if (status === 'PENDING') return 'bg-warning text-dark'
-      if (status === 'CANCELLED' || status === 'CANCELED') return 'bg-danger'
-      if (status === 'EXPIRED') return 'bg-secondary'
-      return 'bg-info'
-    },
-  },
-  methods: {
-    onImageError(event) {
-      event.target.src = noImg
-    },
-  },
-}
-</script>
-
-<template>
-  <div class="card shadow-sm mb-3">
-    <div class="card-body d-flex align-items-center gap-3">
-      <img
-        :src="logoUrl"
-        alt="logo"
-        class="rounded"
-        style="width: 64px; height: 64px; object-fit: cover"
-        @error="onImageError"
-      />
-      <div class="flex-grow-1">
-        <div class="d-flex align-items-center justify-content-between flex-wrap gap-2">
-          <h5 class="mb-0">{{ reservation.localName }}</h5>
-        </div>
-        <div class="text-muted small mt-1">
-          <span class="me-3"><i class="far fa-clock me-1"></i>{{ formattedDateTime }}</span>
-          <span><i class="fas fa-users me-1"></i>For {{ reservation.capacity }} people</span>
-        </div>
-      </div>
-      <div class="ms-auto d-flex align-items-center gap-2">
-        <span class="badge" :class="statusBadgeClass">{{ reservation.status }}</span>
-        <template v-if="selectionMode && isActive">
-          <div class="form-check m-0">
-            <input
-              class="form-check-input"
-              type="checkbox"
-              :checked="selected"
-              @change="$emit('toggle-select', reservation)"
-              :aria-label="`Select reservation ${reservation.id}`"
-            />
-          </div>
-        </template>
-        <template v-else>
-          <button
-            v-if="canEdit && isActive"
-            class="btn btn-outline-primary btn-sm"
-            @click="$emit('edit', reservation)"
-          >
-            <i class="fas fa-edit me-1"></i> Edit
-          </button>
-          <button
-            v-if="canCancel && isActive"
-            class="btn btn-outline-danger btn-sm"
-            @click="$emit('cancel', reservation)"
-          >
-            <i class="fas fa-ban me-1"></i> Cancel
-          </button>
-        </template>
-      </div>
-    </div>
-  </div>
-</template>
-
-<style scoped>
-/* No additional scoped styles needed; leveraging Bootstrap */
-</style>
Index: serveNGo-frontend/src/components/Project/StaticPages/AboutUs.vue
===================================================================
--- ReserveNGo-frontend/src/components/Project/StaticPages/AboutUs.vue	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,292 +1,0 @@
-<script setup lang="ts">
-import { ref } from 'vue'
-
-const lastUpdated = ref(new Date().toLocaleDateString())
-</script>
-
-<template>
-  <div class="about-page container py-5">
-    <!-- HERO -->
-    <header class="hero card shadow-sm mb-4">
-      <div class="card-body d-flex flex-column flex-md-row gap-3 align-items-center">
-        <div class="hero-left d-flex gap-3 align-items-start">
-          <div class="brand-mark d-flex align-items-center justify-content-center">
-            <!-- SVG mark (neutral) -->
-            <svg width="46" height="46" viewBox="0 0 24 24" fill="none" aria-hidden="true">
-              <rect x="0" y="0" width="24" height="24" rx="6" fill="#5ea5bc" />
-              <path
-                d="M7 12h10M7 8h10M7 16h6"
-                stroke="white"
-                stroke-width="1.6"
-                stroke-linecap="round"
-              />
-            </svg>
-          </div>
-
-          <div>
-            <h1 class="h4 mb-1">About ReserveNGo</h1>
-            <p class="mb-0 text-muted small">
-              A simple, fast reservation platform that helps customers find and book experiences,
-              and helps local venues manage bookings without the phone-tag.
-            </p>
-          </div>
-        </div>
-      </div>
-    </header>
-
-    <!-- INTRO + FEATURES -->
-    <section class="row gx-4 gy-4 mb-4">
-      <div class="col-12 col-lg-7">
-        <div class="card h-100 p-3 shadow-sm">
-          <h2 class="h6 mb-2">What we do</h2>
-          <p class="text-muted mb-2">
-            ReserveNGo makes table reservations easy for customers and straightforward for local
-            staff. We focus on speed, clarity and practical features — search, favorites, events,
-            reservation management and simple subscription billing for businesses.
-          </p>
-
-          <h3 class="h6 mt-3 mb-2">Why choose us</h3>
-          <ul class="list-unstyled features-list mb-0">
-            <li>
-              <i class="fas fa-check-circle me-2 text-success"></i>Fast booking flow (no calls
-              required)
-            </li>
-            <li>
-              <i class="fas fa-cog me-2 text-primary"></i>Practical tools for managers and workers
-            </li>
-            <li>
-              <i class="fas fa-star me-2 text-warning"></i>Ratings & favorites to surface top places
-            </li>
-            <li><i class="fas fa-calendar-alt me-2 text-info"></i>Events-first discovery</li>
-          </ul>
-        </div>
-      </div>
-
-      <div class="col-12 col-lg-5">
-        <div class="card h-100 p-3 shadow-sm">
-          <h2 class="h6 mb-2">Roles & responsibilities</h2>
-          <br />
-          <div class="role d-flex gap-3 align-items-start mb-3">
-            <div class="role-icon rounded">
-              <i class="fas fa-user-friends"></i>
-            </div>
-            <div>
-              <strong>Customers</strong>
-              <div class="text-muted small">
-                Search, reserve, manage bookings and rate experiences.
-              </div>
-            </div>
-          </div>
-
-          <div class="role d-flex gap-3 align-items-start mb-3">
-            <div class="role-icon rounded">
-              <i class="fas fa-user-tie"></i>
-            </div>
-            <div>
-              <strong>Local Managers</strong>
-              <div class="text-muted small">Full venue control: info, events, subscriptions.</div>
-            </div>
-          </div>
-
-          <div class="role d-flex gap-3 align-items-start">
-            <div class="role-icon rounded">
-              <i class="fas fa-user-cog"></i>
-            </div>
-            <div>
-              <strong>Local Workers</strong>
-              <div class="text-muted small">Handle day-to-day reservations and customer flow.</div>
-            </div>
-          </div>
-        </div>
-      </div>
-    </section>
-
-    <!-- MISSION / VISION -->
-    <section class="mb-4">
-      <div class="card p-3 shadow-sm">
-        <div class="row g-4 align-items-start">
-          <div class="col-12 col-md-6">
-            <h2 class="h6 mb-2">Our mission</h2>
-            <p class="text-muted mb-0">
-              To make reservations frictionless — for customers and for venues — by providing a
-              focused, reliable tool that replaces unnecessary phone calls and improves table
-              utilization.
-            </p>
-          </div>
-
-          <div class="col-12 col-md-6">
-            <h3 class="h6 mb-2">Our vision</h3>
-            <p class="text-muted mb-0">
-              To become a go-to reservation platform that empowers local businesses and improves how
-              people discover and book experiences.
-            </p>
-          </div>
-        </div>
-      </div>
-    </section>
-
-    <!-- TEAM (static) -->
-    <section class="mb-4">
-      <h2 class="h6 mb-3" style="color: #5ea5bc">The TEAM</h2>
-
-      <div class="row g-3">
-        <!-- Nikola -->
-        <div class="col-12 col-sm-6 col-lg-3">
-          <div class="card team-card text-center p-3 shadow-sm h-100">
-            <div class="avatar mx-auto mb-2">
-              <svg width="72" height="72" viewBox="0 0 24 24" fill="none" aria-hidden="true">
-                <rect width="24" height="24" rx="6" fill="#e9eef0" />
-                <circle cx="12" cy="9" r="3.2" fill="#c0d6d9" />
-                <path
-                  d="M6 18c1.6-2.5 4-3 6-3s4.4.5 6 3"
-                  stroke="#c0d6d9"
-                  stroke-width="1.4"
-                  stroke-linecap="round"
-                />
-              </svg>
-            </div>
-
-            <h3 class="h6 mb-1">Nikola Jordanoski</h3>
-            <div class="text-muted small mb-2">
-              Backend & Frontend · Team Lead · Project Manager
-            </div>
-            <p class="small text-muted mb-0">
-              System architecture, backend services, frontend integration and overall project
-              direction.
-            </p>
-          </div>
-        </div>
-
-        <!-- Zharko -->
-        <div class="col-12 col-sm-6 col-lg-3">
-          <div class="card team-card text-center p-3 shadow-sm h-100">
-            <div class="avatar mx-auto mb-2">
-              <svg width="72" height="72" viewBox="0 0 24 24" fill="none" aria-hidden="true">
-                <rect width="24" height="24" rx="6" fill="#e9eef0" />
-                <circle cx="12" cy="9" r="3.2" fill="#c0d6d9" />
-                <path
-                  d="M6 18c1.6-2.5 4-3 6-3s4.4.5 6 3"
-                  stroke="#c0d6d9"
-                  stroke-width="1.4"
-                  stroke-linecap="round"
-                />
-              </svg>
-            </div>
-
-            <h3 class="h6 mb-1">Zharko Ivanov</h3>
-            <div class="text-muted small mb-2">Backend Developer</div>
-            <p class="small text-muted mb-0">
-              API design, database logic and server-side business rules.
-            </p>
-          </div>
-        </div>
-
-        <!-- Ljubomir -->
-        <div class="col-12 col-sm-6 col-lg-3">
-          <div class="card team-card text-center p-3 shadow-sm h-100">
-            <div class="avatar mx-auto mb-2">
-              <svg width="72" height="72" viewBox="0 0 24 24" fill="none" aria-hidden="true">
-                <rect width="24" height="24" rx="6" fill="#e9eef0" />
-                <circle cx="12" cy="9" r="3.2" fill="#c0d6d9" />
-                <path
-                  d="M6 18c1.6-2.5 4-3 6-3s4.4.5 6 3"
-                  stroke="#c0d6d9"
-                  stroke-width="1.4"
-                  stroke-linecap="round"
-                />
-              </svg>
-            </div>
-
-            <h3 class="h6 mb-1">Ljubomir Ilievski</h3>
-            <div class="text-muted small mb-2">Frontend Developer</div>
-            <p class="small text-muted mb-0">
-              UI components, layouts and frontend interaction logic.
-            </p>
-          </div>
-        </div>
-
-        <!-- Aleksandar -->
-        <div class="col-12 col-sm-6 col-lg-3">
-          <div class="card team-card text-center p-3 shadow-sm h-100">
-            <div class="avatar mx-auto mb-2">
-              <svg width="72" height="72" viewBox="0 0 24 24" fill="none" aria-hidden="true">
-                <rect width="24" height="24" rx="6" fill="#e9eef0" />
-                <circle cx="12" cy="9" r="3.2" fill="#c0d6d9" />
-                <path
-                  d="M6 18c1.6-2.5 4-3 6-3s4.4.5 6 3"
-                  stroke="#c0d6d9"
-                  stroke-width="1.4"
-                  stroke-linecap="round"
-                />
-              </svg>
-            </div>
-
-            <h3 class="h6 mb-1">Aleksandar Jovanovski</h3>
-            <div class="text-muted small mb-2">Frontend Developer</div>
-            <p class="small text-muted mb-0">Frontend features, responsiveness and UX polish.</p>
-          </div>
-        </div>
-      </div>
-    </section>
-
-    <footer class="text-muted small mt-4">
-      <p class="mb-0">Last updated: {{ lastUpdated }}</p>
-    </footer>
-  </div>
-</template>
-
-<style scoped>
-.about-page {
-  max-width: 1100px;
-}
-
-/* HERO */
-.hero {
-  border: 1px solid rgba(0, 0, 0, 0.04);
-  background: linear-gradient(180deg, #ffffff 0%, #fbfdfe 100%);
-}
-.brand-mark {
-  width: 46px;
-  height: 46px;
-  border-radius: 8px;
-  display: inline-flex;
-  align-items: center;
-  justify-content: center;
-}
-
-/* stats */
-
-/* features / roles */
-.features-list li {
-  margin-bottom: 0.6rem;
-}
-.role-icon {
-  width: 44px;
-  height: 44px;
-  border-radius: 8px;
-  background: #f1f7f8;
-  display: inline-flex;
-  align-items: center;
-  justify-content: center;
-  color: #5ea5bc;
-  font-size: 1.1rem;
-}
-
-/* team */
-.team-card .avatar {
-  width: 72px;
-  height: 72px;
-  display: flex;
-  align-items: center;
-  justify-content: center;
-  border-radius: 12px;
-  background: #fff;
-}
-
-/* small responsiveness */
-@media (max-width: 768px) {
-  .hero .card-body {
-    gap: 1rem;
-  }
-}
-</style>
Index: serveNGo-frontend/src/components/Project/StaticPages/ContactComp.vue
===================================================================
--- ReserveNGo-frontend/src/components/Project/StaticPages/ContactComp.vue	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,128 +1,0 @@
-<template>
-  <div class="contact-page container py-5">
-    <!-- HERO -->
-    <header class="card shadow-sm mb-4 hero">
-      <div class="card-body d-flex align-items-center gap-3">
-        <div class="hero-icon">
-          <i class="fas fa-envelope"></i>
-        </div>
-
-        <div>
-          <h1 class="h5 mb-1">Contact</h1>
-          <p class="mb-0 text-muted small">
-            Questions, feedback, or interested in using ReserveNGo for your business? We’d love to
-            hear from you.
-          </p>
-        </div>
-      </div>
-    </header>
-
-    <div class="row g-4">
-      <!-- Contact Info -->
-      <div class="col-md-5">
-        <div class="card shadow-sm h-100">
-          <div class="card-body">
-            <h5 class="h6 mb-3">Contact Information</h5>
-
-            <p class="mb-2 small">
-              <strong>Email:</strong><br />
-              <a href="mailto:reservengo2025@gmail.com">reservengo2025@gmail.com</a>
-            </p>
-
-            <p class="mb-2 small">
-              <strong>Phone:</strong><br />
-              +123 456 789
-            </p>
-
-            <p class="mb-0 small">
-              <strong>Location:</strong><br />
-              Faculty of Computer Science & Engineering (FINKI), Skopje
-            </p>
-          </div>
-        </div>
-      </div>
-
-      <!-- Contact Form -->
-      <div class="col-md-7">
-        <div class="card shadow-sm">
-          <div class="card-body">
-            <h5 class="h6 mb-3">Send a message</h5>
-
-            <form>
-              <div class="mb-3">
-                <label class="form-label small">Your name</label>
-                <input type="text" class="form-control form-control-sm" placeholder="John Doe" />
-              </div>
-
-              <div class="mb-3">
-                <label class="form-label small">Email</label>
-                <input
-                  type="email"
-                  class="form-control form-control-sm"
-                  placeholder="you@example.com"
-                />
-              </div>
-
-              <div class="mb-3">
-                <label class="form-label small">Message</label>
-                <textarea
-                  class="form-control form-control-sm"
-                  rows="4"
-                  placeholder="Write your message here..."
-                ></textarea>
-              </div>
-
-              <button type="button" class="btn btn-sm">Send message</button>
-            </form>
-          </div>
-        </div>
-      </div>
-    </div>
-
-    <!-- Map -->
-    <section class="mt-4">
-      <h5 class="h6 mb-2">Find us</h5>
-      <div class="ratio ratio-16x9 map-wrapper rounded overflow-hidden shadow-sm">
-        <iframe
-          src="https://www.google.com/maps?q=FINKI%20Skopje&output=embed"
-          loading="lazy"
-          referrerpolicy="no-referrer-when-downgrade"
-        ></iframe>
-      </div>
-    </section>
-  </div>
-</template>
-
-<style scoped>
-.contact-page {
-  max-width: 1000px;
-}
-
-/* HERO */
-.hero {
-  border: 1px solid rgba(0, 0, 0, 0.04);
-  background: linear-gradient(180deg, #ffffff 0%, #fbfdfe 100%);
-}
-
-.hero-icon {
-  width: 44px;
-  height: 44px;
-  border-radius: 10px;
-  background: rgba(94, 165, 188, 0.15);
-  color: #5ea5bc;
-  display: flex;
-  align-items: center;
-  justify-content: center;
-  font-size: 1.2rem;
-}
-
-/* Map smaller */
-.map-wrapper {
-  max-height: 300px;
-}
-
-button {
-  background-color: #5ea5bc;
-  color: white;
-}
-</style>
Index: serveNGo-frontend/src/components/Project/StaticPages/PrivacyPolicy.vue
===================================================================
--- ReserveNGo-frontend/src/components/Project/StaticPages/PrivacyPolicy.vue	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,190 +1,0 @@
-<script setup lang="ts">
-import { ref } from 'vue'
-import { useRouter } from 'vue-router'
-
-const lastUpdated = ref(new Date().toLocaleDateString())
-const router = useRouter()
-
-function goToContact() {
-  router.push({ path: '/contact' })
-}
-
-function printPolicy() {
-  window.print()
-}
-</script>
-
-<template>
-  <div class="privacy-page container py-5">
-    <!-- HERO (hidden when printing) -->
-    <div class="card mb-4 shadow-sm hero-card no-print">
-      <div class="card-body d-flex align-items-center justify-content-between flex-wrap gap-3">
-        <div class="d-flex align-items-center gap-3">
-          <div class="hero-icon">
-            <i class="fas fa-shield-alt"></i>
-          </div>
-
-          <div>
-            <h1 class="h5 mb-1">Privacy Policy</h1>
-            <p class="mb-0 text-muted small">
-              How ReserveNGo collects, uses and protects your personal data.
-            </p>
-          </div>
-        </div>
-
-        <div class="text-end">
-          <div class="small text-muted">Last updated</div>
-          <div class="fw-medium">{{ lastUpdated }}</div>
-
-          <div class="mt-2 d-flex gap-2 justify-content-end">
-            <button class="btn btn-outline-secondary btn-sm" @click="printPolicy">
-              <i class="fas fa-print me-1"></i> Print
-            </button>
-
-            <button class="btn btn-contact btn-sm" @click="goToContact">
-              <i class="fas fa-envelope me-1"></i> Contact Us
-            </button>
-          </div>
-        </div>
-      </div>
-    </div>
-
-    <!-- CONTENT -->
-    <article class="privacy-content mx-auto">
-      <section class="mb-4">
-        <p class="mb-1">
-          At <strong>ReserveNGo</strong> we respect your privacy. This page explains what personal
-          information we collect, why we collect it, and how you can manage it.
-        </p>
-        <p class="text-muted small mb-0">
-          Short version: we only collect what we need to run reservations and improve the service.
-          We never sell personal data.
-        </p>
-      </section>
-
-      <section class="mb-4">
-        <h2 class="h5">What we collect</h2>
-        <ul>
-          <li><strong>Account info:</strong> name, email, phone.</li>
-          <li><strong>Reservation data:</strong> date, time, people, requests.</li>
-          <li><strong>Venue data:</strong> favorites, ratings, event attendance.</li>
-          <li><strong>Usage data:</strong> IP, browser, device, logs.</li>
-          <li><strong>Billing:</strong> subscription references (no card storage).</li>
-        </ul>
-      </section>
-
-      <section class="mb-4">
-        <h2 class="h5">How we use your information</h2>
-        <ul>
-          <li>Provide and manage reservations.</li>
-          <li>Send confirmations and important notifications.</li>
-          <li>Improve search, UX and platform features.</li>
-          <li>Handle subscriptions and billing.</li>
-          <li>Prevent abuse and fraud.</li>
-        </ul>
-
-        <details class="mt-2">
-          <summary class="fw-semibold">Marketing & emails</summary>
-          <p class="text-muted mt-2">
-            Promotional emails are optional and can be unsubscribed anytime. Transactional emails
-            are mandatory.
-          </p>
-        </details>
-      </section>
-
-      <section class="mb-4">
-        <h2 class="h5">Cookies & tracking</h2>
-        <ul>
-          <li><strong>Essential:</strong> login, sessions, reservations.</li>
-          <li><strong>Functional:</strong> preferences and UI state.</li>
-          <li><strong>Analytics:</strong> anonymous usage statistics.</li>
-        </ul>
-      </section>
-
-      <section class="mb-4">
-        <h2 class="h5">Data security</h2>
-        <ul>
-          <li>HTTPS encryption</li>
-          <li>Access control and least privilege</li>
-          <li>Regular security updates</li>
-          <li>Vetted third-party providers</li>
-        </ul>
-      </section>
-
-      <section class="mb-4">
-        <h2 class="h5">Your rights</h2>
-        <ul>
-          <li>Access your data</li>
-          <li>Correct inaccurate data</li>
-          <li>Request deletion</li>
-          <li>Object or restrict processing</li>
-          <li>Request data portability</li>
-        </ul>
-        <p class="text-muted">
-          Contact us at
-          <a href="mailto:reservengo2025@gmail.com">reservengo2025@gmail.com</a>
-          to exercise these rights.
-        </p>
-      </section>
-
-      <section class="mb-4">
-        <h2 class="h5">Changes to this policy</h2>
-        <p class="text-muted">
-          We may update this policy occasionally. Updates will be reflected on this page.
-        </p>
-      </section>
-
-      <footer class="text-muted small mt-4">
-        <p class="mb-0">
-          This Privacy Policy is suitable for student projects and MVPs. Legal review is recommended
-          for production use.
-        </p>
-      </footer>
-    </article>
-  </div>
-</template>
-
-<style scoped>
-.privacy-page {
-  max-width: 1200px;
-}
-
-/* Content width */
-.privacy-content {
-  max-width: 900px;
-}
-
-/* HERO */
-.hero-card {
-  background: linear-gradient(135deg, #f8fbfc 0%, #ffffff 100%);
-  border: 1px solid rgba(0, 0, 0, 0.04);
-}
-
-.hero-icon {
-  width: 48px;
-  height: 48px;
-  border-radius: 10px;
-  background: rgba(94, 165, 188, 0.15);
-  color: #5ea5bc;
-  display: flex;
-  align-items: center;
-  justify-content: center;
-  font-size: 1.3rem;
-}
-
-/* Contact button */
-.btn-contact {
-  background-color: #f55845;
-  border-color: #f55845;
-  color: #fff;
-}
-.btn-contact:hover {
-  background-color: #e14a3a;
-  border-color: #e14a3a;
-}
-
-/* details */
-details summary {
-  cursor: pointer;
-}
-</style>
Index: serveNGo-frontend/src/components/Project/Utility/GeneralModal.vue
===================================================================
--- ReserveNGo-frontend/src/components/Project/Utility/GeneralModal.vue	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,105 +1,0 @@
-<!-- components/BaseModal.vue -->
-<script lang="ts">
-export default {
-  name: 'BaseModal',
-  props: {
-    show: {
-      type: Boolean,
-      required: true,
-    },
-    closeOnBackdrop: {
-      type: Boolean,
-      default: true,
-    },
-  },
-  emits: ['close'],
-  methods: {
-    close() {
-      this.$emit('close')
-    },
-    onBackdropClick() {
-      if (this.closeOnBackdrop) {
-        this.close()
-      }
-    },
-  },
-}
-</script>
-
-<template>
-  <Transition name="modal-fade">
-    <div v-if="show" class="modal-backdrop" @click="onBackdropClick">
-      <div class="modal-container" @click.stop>
-        <!-- Close Button -->
-        <button class="close-btn" @click="close">×</button>
-
-        <!-- Slot for ANY content -->
-        <div class="modal-content">
-          <slot />
-        </div>
-      </div>
-    </div>
-  </Transition>
-</template>
-
-<style scoped>
-.modal-backdrop {
-  position: fixed;
-  inset: 0;
-  background-color: rgba(0, 0, 0, 0.6);
-  display: flex;
-  align-items: center;
-  justify-content: center;
-  z-index: 1000;
-}
-
-.modal-container {
-  background: white;
-  border-radius: 12px;
-  width: 80%;
-  max-width: 900px;
-  max-height: 80%;
-  position: relative;
-  box-shadow: 0 10px 25px rgba(0, 0, 0, 0.2);
-  overflow: hidden;
-  display: flex;
-  flex-direction: column;
-}
-
-.modal-content {
-  padding: 1.5rem;
-  overflow: auto;
-}
-
-.close-btn {
-  position: absolute;
-  top: 10px;
-  right: 15px;
-  font-size: 2.5rem;
-  font-weight: bold;
-  background: none;
-  border: none;
-  cursor: pointer;
-  line-height: 1;
-  z-index: 10;
-}
-
-@media (max-width: 1000px) {
-  .modal-container {
-    width: 100%;
-    height: 100%;
-    max-height: 100%;
-    border-radius: 0;
-  }
-}
-
-.modal-fade-enter-active,
-.modal-fade-leave-active {
-  transition: opacity 0.3s ease;
-}
-
-.modal-fade-enter-from,
-.modal-fade-leave-to {
-  opacity: 0;
-}
-</style>
Index: serveNGo-frontend/src/components/Project/Utility/HorizontalScroller.vue
===================================================================
--- ReserveNGo-frontend/src/components/Project/Utility/HorizontalScroller.vue	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,242 +1,0 @@
-<!-- components/HorizontalScroller.vue -->
-<template>
-  <div class="scroller-wrapper">
-    <!-- Left Navigation Arrow -->
-    <button
-      v-if="canScrollLeft"
-      class="nav-arrow prev"
-      @click="scrollLeft"
-      aria-label="Scroll left"
-    >
-      <LeftArrow></LeftArrow>
-    </button>
-
-    <!-- The container that hides the scrollbar and captures events -->
-    <div class="scroll-container" ref="scrollContainer" @scroll.passive="handleScroll">
-      <!-- The flex wrapper for your content -->
-      <div class="content-wrapper" ref="contentWrapper">
-        <slot></slot>
-      </div>
-    </div>
-
-    <!-- Right Navigation Arrow -->
-    <button
-      v-if="canScrollRight"
-      class="nav-arrow next"
-      @click="scrollRight"
-      aria-label="Scroll right"
-    >
-      <RightArrow></RightArrow>
-    </button>
-  </div>
-</template>
-
-<script>
-import LeftArrow from '@/components/Project/Utility/LeftArrow.vue'
-import RightArrow from '@/components/Project/Utility/RightArrow.vue'
-
-export default {
-  name: 'HorizontalScroller',
-  components: { RightArrow, LeftArrow },
-  data() {
-    return {
-      // These booleans control the visibility of the arrows
-      canScrollLeft: false,
-      canScrollRight: false,
-      // A ResizeObserver to detect when the container or content size changes
-      resizeObserver: null,
-      // Add a new property for debugging
-      thirdChildOffsetLeft: 'N/A',
-      scrollContainerScrollLeftValue: 'N/A',
-    }
-  },
-  mounted() {
-    // Wait for the DOM to be ready before doing calculations
-    this.$nextTick(() => {
-      this.checkForOverflow()
-
-      this.resizeObserver = new ResizeObserver(() => this.checkForOverflow())
-      this.resizeObserver.observe(this.$refs.contentWrapper)
-      this.resizeObserver.observe(this.$refs.scrollContainer)
-    })
-  },
-  methods: {
-    /**
-     * This is the master method that checks if scrolling is possible
-     * and updates the visibility of the navigation arrows.
-     */
-    checkForOverflow() {
-      const container = this.$refs.scrollContainer
-      if (!container) return
-      const content = this.$refs.contentWrapper
-
-      // --- START: Debugging Logic ---
-      // Check if the third child exists (arrays are 0-indexed)
-      if (content.children && content.children.length > 2) {
-        const thirdChild = content.children[6]
-        /*  console.log("child", thirdChild)*/
-        // Get the element's offset relative to its parent.
-        // This value only changes on window resize or layout change.
-        this.thirdChildOffsetLeft = thirdChild.offsetLeft
-        this.scrollContainerScrollLeftValue = container.scrollLeft + container.clientWidth
-        /*console.log("ThirdChildOffSetLEft", this.thirdChildOffsetLeft)*/
-      } else {
-        this.thirdChildOffsetLeft = 'N/A'
-      }
-      // --- END: Debugging Logic ---
-
-      const hasOverflow = container.scrollWidth > container.clientWidth
-
-      this.canScrollLeft = hasOverflow && container.scrollLeft > 0
-      this.canScrollRight =
-        hasOverflow && container.scrollLeft + 1 < container.scrollWidth - container.clientWidth
-    },
-
-    /**
-     * This method is called whenever the user scrolls the container,
-     * either with the arrows or manually (e.g., trackpad).
-     */
-    handleScroll() {
-      // We just need to re-run the check to update the arrow states.
-      this.checkForOverflow()
-    },
-
-    /**
-     * The core logic for scrolling to the right.
-     * It finds the first item currently clipped on the right
-     * and scrolls just enough to make it fully visible.
-     */
-    scrollRight() {
-      const container = this.$refs.scrollContainer
-      const items = this.$refs.contentWrapper.children
-      if (!container || items.length === 0) return
-
-      const containerRightEdge = container.scrollLeft + container.clientWidth
-
-      // Find the first item whose left edge is past the visible area
-      let targetItem = null
-      for (const item of items) {
-        if (item.offsetLeft >= containerRightEdge) {
-          targetItem = item
-          break
-        }
-      }
-
-      // If no item is found (we might be at the end), we don't scroll
-      if (targetItem) {
-        /*        console.log("TargetItem", targetItem)*/
-        container.scrollTo({
-          left: targetItem.offsetLeft + targetItem.clientWidth - container.clientWidth,
-          behavior: 'smooth',
-        })
-      }
-    },
-
-    /**
-     * The core logic for scrolling to the left.
-     * It finds the first fully visible item and scrolls to make the
-     * item *before* it the new first visible item.
-     */
-    scrollLeft() {
-      const container = this.$refs.scrollContainer
-      const items = this.$refs.contentWrapper.children
-      if (!container || items.length === 0) return
-
-      const containerLeftEdge = container.scrollLeft
-
-      // Find the last item that starts before the visible area
-      let targetItem = null
-      for (const item of items) {
-        if (item.offsetLeft < containerLeftEdge - 1) {
-          targetItem = item
-        } else {
-          // As soon as we find an item that starts inside the view, we can stop.
-          break
-        }
-      }
-
-      if (targetItem) {
-        container.scrollTo({
-          left: targetItem.offsetLeft,
-          behavior: 'smooth',
-        })
-      } else {
-        // If no item is clipped on the left, scroll to the very beginning
-        container.scrollTo({ left: 0, behavior: 'smooth' })
-      }
-    },
-  },
-}
-</script>
-
-<style scoped>
-.scroller-wrapper {
-  position: relative;
-  width: 100%;
-}
-
-.scroll-container {
-  /* This is the key: hide the native scrollbar */
-  overflow-x: scroll;
-  scrollbar-width: none; /* For Firefox */
-  -ms-overflow-style: none; /* For Internet Explorer and Edge */
-
-  /* Enables smooth scrolling on iOS devices */
-  -webkit-overflow-scrolling: touch;
-}
-
-.scroll-container::-webkit-scrollbar {
-  display: none; /* For Chrome, Safari, and Opera */
-}
-
-.content-wrapper {
-  display: flex;
-  flex-wrap: nowrap;
-  gap: 1rem; /* Adjust the gap between your items */
-  padding-block: 1rem; /* Adds some vertical space so arrows aren't on the edge */
-}
-
-.content-wrapper > * {
-  flex-grow: 1;
-  flex-shrink: 0;
-  flex-basis: 5rem;
-}
-
-.nav-arrow {
-  position: absolute;
-  top: 50%;
-  transform: translateY(-50%);
-  z-index: 10;
-  /*width: 40px;*/
-  aspect-ratio: 1 / 1;
-  padding: 10px;
-  border-radius: 50%;
-  background-color: rgba(255, 255, 255, 0.7);
-  border: 1px solid #ddd;
-  box-shadow: inset 0 2px 8px rgba(0, 0, 0, 0.1);
-  cursor: pointer;
-  display: flex;
-  justify-content: center;
-  align-items: center;
-  /*  vertical-align: top;
-  text-align: start;*/
-
-  color: #333;
-  transition:
-    transform 0.2s ease,
-    box-shadow 0.2s ease;
-}
-
-.nav-arrow:hover {
-  transform: translateY(-50%) scale(1.1);
-  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
-}
-
-.nav-arrow.prev {
-  left: -20px; /* Position half-way out of the container */
-}
-
-.nav-arrow.next {
-  right: -20px; /* Position half-way out of the container */
-}
-</style>
Index: serveNGo-frontend/src/components/Project/Utility/ImageModalLocale.vue
===================================================================
--- ReserveNGo-frontend/src/components/Project/Utility/ImageModalLocale.vue	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,304 +1,0 @@
-<!-- components/ImageModal.vue -->
-<script lang="ts">
-import { userStore } from '@/PiniaStores/UserStore'
-
-export default {
-  props: {
-    images: { type: Array, required: true },
-    startIndex: { type: Number, default: 0 },
-    show: { type: Boolean, default: false },
-  },
-  emits: ['close', 'remove-image'], // Added 'remove-image' emit
-
-  data() {
-    return {
-      activeIndex: this.startIndex,
-      userStore_: userStore(),
-    }
-  },
-  computed: {
-    activeImage() {
-      if (!this.images || this.images.length === 0) return ''
-      return this.images[this.activeIndex]
-    },
-    // --- NEW: A computed property to easily check the role ---
-  },
-  methods: {
-    closeModal() {
-      this.$emit('close')
-    },
-    selectImage(index) {
-      this.activeIndex = index
-    },
-    nextImage() {
-      this.activeIndex = (this.activeIndex + 1) % this.images.length
-    },
-    prevImage() {
-      this.activeIndex = (this.activeIndex - 1 + this.images.length) % this.images.length
-    },
-
-    // --- NEW: Method to handle image removal ---
-    // We get the full image object to have access to its ID
-    handleRemove(image, index) {
-      // Add a confirmation step to prevent accidental deletion
-      if (confirm('Are you sure you want to remove this image?')) {
-        this.$emit('delete-photo', image, index)
-      }
-    },
-  },
-  watch: {
-    show(newValue) {
-      if (newValue) {
-        this.activeIndex = this.startIndex
-      }
-    },
-  },
-}
-</script>
-
-<template>
-  <Transition name="modal-fade">
-    <div v-if="show" class="modal-backdrop" @click="closeModal">
-      <div class="modal-container" @click.stop>
-        <button @click="closeModal" class="close-btn">×</button>
-
-        <!-- Main image wrapper is now a flex item that can shrink -->
-        <div class="main-image-wrapper">
-          <img :src="activeImage" alt="Enlarged view" class="main-image" />
-          <template v-if="images.length > 1">
-            <button @click.stop="prevImage" class="nav-arrow prev">
-              <svg
-                xmlns="http://www.w3.org/2000/svg"
-                fill="none"
-                viewBox="0 0 24 24"
-                stroke-width="1.5"
-                stroke="currentColor"
-                class="size-6"
-              >
-                <path
-                  stroke-linecap="round"
-                  stroke-linejoin="round"
-                  d="M15.75 19.5 8.25 12l7.5-7.5"
-                />
-              </svg>
-            </button>
-            <button @click.stop="nextImage" class="nav-arrow next">
-              <svg
-                xmlns="http://www.w3.org/2000/svg"
-                fill="none"
-                viewBox="0 0 24 24"
-                stroke-width="1.5"
-                stroke="currentColor"
-                class="size-6"
-              >
-                <path
-                  stroke-linecap="round"
-                  stroke-linejoin="round"
-                  d="m8.25 4.5 7.5 7.5-7.5 7.5"
-                />
-              </svg>
-            </button>
-          </template>
-        </div>
-
-        <!-- Thumbnails wrapper will take the space it needs and scroll if necessary -->
-        <div class="thumbnails-wrapper">
-          <!-- Each thumbnail is now a container for the image and the button -->
-          <div v-for="(image, index) in images" :key="index" class="thumbnail-item">
-            <img
-              :src="image"
-              alt="Thumbnail"
-              class="thumbnail-image"
-              :class="{ active: index === activeIndex }"
-              @click="selectImage(index)"
-            />
-            <!-- === NEW: Conditional Remove Button === -->
-            <button
-              v-if="userStore_.isLocaleManager || userStore_.isAdmin"
-              @click.stop="handleRemove(image, index)"
-              class="btn btn-danger btn-sm remove-btn"
-            >
-              Remove
-            </button>
-          </div>
-        </div>
-      </div>
-    </div>
-  </Transition>
-</template>
-
-<style scoped>
-/* Modal container is now a flex container for its children */
-.modal-container {
-  width: 80%;
-  max-width: 900px;
-  height: 80%;
-  background-color: white;
-  border-radius: 12px;
-  box-shadow: 0 10px 25px rgba(0, 0, 0, 0.2);
-  display: flex;
-  flex-direction: column;
-  position: relative;
-  overflow: hidden;
-}
-
-/* --- LAYOUT CHANGE: Fixed height removed --- */
-/* This wrapper will now take up the remaining space and can shrink. */
-.main-image-wrapper {
-  flex: 1 1 auto; /* Allow grow, allow shrink, auto basis */
-  min-height: 0; /* A flexbox trick to allow shrinking below content size */
-  background-color: #f0f0f0;
-  display: flex;
-  justify-content: center;
-  align-items: center;
-  position: relative;
-}
-
-/* --- LAYOUT CHANGE: Fixed height removed, other properties added --- */
-.thumbnails-wrapper {
-  flex-shrink: 0; /* Prevent this container from shrinking */
-  background-color: #fff;
-  padding: 1rem;
-  display: flex;
-  align-items: flex-start; /* Align items to the top */
-  gap: 1rem;
-  overflow-x: auto;
-  border-top: 1px solid #eee;
-}
-
-/* === NEW: Container for each thumbnail and its button === */
-.thumbnail-item {
-  display: flex;
-  flex-direction: column;
-  align-items: center;
-  gap: 0.5rem; /* Space between image and button */
-}
-
-/* The thumbnail image itself doesn't need to define height anymore */
-.thumbnail-image {
-  /* Set a fixed height here to keep thumbnails uniform */
-  height: max(80px, 15vh);
-  width: auto;
-  border-radius: 6px;
-  cursor: pointer;
-  filter: grayscale(100%) brightness(0.9);
-  transition: all 0.3s ease;
-}
-
-/* === NEW: Style for the remove button === */
-.remove-btn {
-  /* You can add more specific styles if Bootstrap isn't enough */
-  padding: 0.2rem 0.5rem;
-  font-size: 0.75rem;
-}
-
-/* --- The rest of the styles, now properly formatted --- */
-
-.modal-backdrop {
-  position: fixed;
-  top: 0;
-  left: 0;
-  width: 100vw;
-  height: 100vh;
-  background-color: rgba(0, 0, 0, 0.6);
-  display: flex;
-  justify-content: center;
-  align-items: center;
-  z-index: 1000;
-}
-
-.close-btn {
-  position: absolute;
-  top: 10px;
-  right: 15px;
-  font-size: 2.5rem;
-  font-weight: bold;
-  color: #333;
-  background: none;
-  border: none;
-  cursor: pointer;
-  z-index: 1010;
-  line-height: 1;
-}
-
-.main-image {
-  max-width: 100%;
-  max-height: 100%;
-  object-fit: contain;
-}
-
-.nav-arrow {
-  position: absolute;
-  /*  top: 50%;*/
-  /*  transform: translateY(-50%);*/ /*Here this css is not needed because align items from parent flex does the job for you,
-                                     If you agg 50% top this takes priority and now you have to add a translateY -50% to make it perfectly vertical*/
-  background-color: rgba(0, 0, 0, 0.4);
-  color: white;
-  border: none;
-  border-radius: 50%;
-  width: 40px;
-  height: 40px;
-  font-size: 2rem;
-  font-weight: bold;
-  cursor: pointer;
-  display: flex;
-  justify-content: center;
-  align-items: center;
-  z-index: 10;
-  transition: background-color 0.2s ease;
-}
-
-.nav-arrow:hover {
-  background-color: rgba(0, 0, 0, 0.7);
-}
-
-.nav-arrow.prev {
-  left: 15px;
-}
-
-.nav-arrow.next {
-  right: 15px;
-}
-
-.thumbnails-wrapper::-webkit-scrollbar {
-  height: 8px;
-}
-.thumbnails-wrapper::-webkit-scrollbar-track {
-  background: #f1f1f1;
-}
-.thumbnails-wrapper::-webkit-scrollbar-thumb {
-  background: #ccc;
-  border-radius: 4px;
-}
-.thumbnails-wrapper::-webkit-scrollbar-thumb:hover {
-  background: #aaa;
-}
-
-.thumbnail-image:hover {
-  filter: grayscale(0) brightness(1);
-  transform: scale(1.05);
-}
-
-.thumbnail-image.active {
-  filter: grayscale(0) brightness(1);
-  outline: 3px solid #3498db;
-  outline-offset: 2px;
-}
-
-@media (max-width: 1000px) {
-  .modal-container {
-    width: 100%;
-    height: 100%;
-    border-radius: 0;
-  }
-}
-
-.modal-fade-enter-active,
-.modal-fade-leave-active {
-  transition: opacity 0.4s ease;
-}
-.modal-fade-enter-from,
-.modal-fade-leave-to {
-  opacity: 0;
-}
-</style>
Index: serveNGo-frontend/src/components/Project/Utility/LeftArrow.vue
===================================================================
--- ReserveNGo-frontend/src/components/Project/Utility/LeftArrow.vue	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,12 +1,0 @@
-<template>
-  <svg xmlns="http://www.w3.org/2000/svg" width="1.2em" height="1.2em" viewBox="0 0 24 24">
-    <path
-      fill="none"
-      stroke="currentColor"
-      stroke-linecap="round"
-      stroke-linejoin="round"
-      stroke-width="2"
-      d="m15 6l-6 6l6 6"
-    />
-  </svg>
-</template>
Index: serveNGo-frontend/src/components/Project/Utility/LoadingIcon.vue
===================================================================
--- ReserveNGo-frontend/src/components/Project/Utility/LoadingIcon.vue	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,14 +1,0 @@
-<template>
-  <svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 24 24">
-    <g>
-      <rect width="2" height="5" x="11" y="1" fill="currentColor" opacity="0.14" />
-      <rect width="2" height="5" x="11" y="1" fill="currentColor" opacity="0.29" transform="rotate(30 12 12)" />
-      <rect width="2" height="5" x="11" y="1" fill="currentColor" opacity="0.43" transform="rotate(60 12 12)" />
-      <rect width="2" height="5" x="11" y="1" fill="currentColor" opacity="0.57" transform="rotate(90 12 12)" />
-      <rect width="2" height="5" x="11" y="1" fill="currentColor" opacity="0.71" transform="rotate(120 12 12)" />
-      <rect width="2" height="5" x="11" y="1" fill="currentColor" opacity="0.86" transform="rotate(150 12 12)" />
-      <rect width="2" height="5" x="11" y="1" fill="currentColor" transform="rotate(180 12 12)" />
-      <animateTransform attributeName="transform" calcMode="discrete" dur="0.75s" repeatCount="indefinite" type="rotate" values="0 12 12;30 12 12;60 12 12;90 12 12;120 12 12;150 12 12;180 12 12;210 12 12;240 12 12;270 12 12;300 12 12;330 12 12;360 12 12" />
-    </g>
-  </svg>
-</template>
Index: serveNGo-frontend/src/components/Project/Utility/ManagerFileInput.vue
===================================================================
--- ReserveNGo-frontend/src/components/Project/Utility/ManagerFileInput.vue	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,180 +1,0 @@
-<!-- components/CustomFileInput.vue -->
-<template>
-  <div class="custom-file-input-container">
-    <!-- 1. This is the actual file input, but it's hidden from view. -->
-    <input
-      type="file"
-      :id="inputId"
-      ref="fileInput"
-      @change="handleFileChange"
-      style="display: none"
-      accept="image/*"
-    />
-
-    <!-- 2. This black button acts as a label. Clicking it triggers the hidden input. -->
-    <label :for="inputId" class="btn btn-dark">
-      {{ leftButtonText }}
-    </label>
-
-    <!-- 3. This span displays the name of the selected file or the default text. -->
-    <span class="file-name-display">
-      {{ fileNameDisplay }}
-    </span>
-
-    <!-- 4. The right-side action button. -->
-    <button
-      class="btn btn-dark"
-      :disabled="isRightButtonDisabled || isLoading"
-      @click="handleRightButtonClick"
-    >
-      <span v-if="!isLoading">{{ rightButtonText }}</span>
-      <LoadingIcon v-else></LoadingIcon>
-    </button>
-  </div>
-</template>
-
-<script>
-import LoadingIcon from '@/components/Project/Utility/LoadingIcon.vue'
-export default {
-  name: 'ManagerFileInput',
-  components: {
-    LoadingIcon,
-  },
-  props: {
-    // The text for the button on the far right.
-    rightButtonText: {
-      type: String,
-      required: true,
-    },
-    leftButtonText: {
-      type: String,
-      required: true,
-    },
-    // The unique ID for the hidden file input. Crucial for the <label> to work.
-    inputId: {
-      type: String,
-      required: true,
-    },
-    // The text to display in the middle when no file is selected.
-    defaultText: {
-      type: String,
-      default: 'No file chosen',
-    },
-    // The ID of the <img> tag for the live preview. Optional.
-    previewElementId: {
-      type: String,
-      default: null, // Not required
-    },
-    isLoading: {
-      type: Boolean,
-      default: false,
-    },
-  },
-  emits: ['file-sent', 'file-input-inserted'],
-  data() {
-    return {
-      selectedFile: null,
-      isRightButtonDisabled: true,
-    }
-  },
-  computed: {
-    // A computed property to dynamically show the correct text in the middle.
-    fileNameDisplay() {
-      return this.selectedFile ? this.selectedFile.name : this.defaultText
-    },
-  },
-  methods: {
-    // This method runs when a user selects a file from the dialog.
-    handleFileChange(event) {
-      const file = event.target.files[0]
-
-      // If a user cancels the file dialog, do nothing.
-      if (!file) return
-
-      this.selectedFile = file
-      this.isRightButtonDisabled = false // Enable the right button
-      // --- This section handles the live image preview ---
-      // It only runs if a previewElementId was passed in props.
-      if (this.previewElementId && file.type.startsWith('image/')) {
-        const previewElement = document.getElementById(this.previewElementId)
-
-        if (previewElement) {
-          const reader = new FileReader()
-          reader.onload = (e) => {
-            // Sets the 'src' attribute of the image tag to the new file data
-            previewElement.src = e.target.result
-          }
-          reader.readAsDataURL(file)
-        } else {
-          console.warn(
-            `[CustomFileInput] Preview element with ID '${this.previewElementId}' was not found in the DOM.`,
-          )
-        }
-      }
-    },
-
-    // This method runs when the user clicks the right-side button.
-    handleRightButtonClick() {
-      if (this.isRightButtonDisabled) return
-      if (this.previewElementId) {
-        const previewElement = document.getElementById(this.previewElementId)
-        if (previewElement) {
-          previewElement.src = ''
-        }
-      }
-      this.$emit('file-sent', this.selectedFile) // Notify the parent that the file was removed
-    },
-    reset() {
-      this.selectedFile = null
-      this.isRightButtonDisabled = true
-      this.$refs.fileInput.value = ''
-      if (this.previewElementId) {
-        const previewElement = document.getElementById(this.previewElementId)
-        if (previewElement) {
-          previewElement.src = ''
-        }
-      }
-    },
-  },
-}
-</script>
-
-<style scoped>
-/*
- The main container styling.
- We use Flexbox for easy horizontal alignment.
-*/
-.custom-file-input-container {
-  display: flex;
-  align-items: center;
-  gap: 1rem; /* Creates space between the elements */
-  background-color: #212529; /* Bootstrap's standard dark color */
-  color: white;
-  padding: 1rem;
-  border-radius: 0.375rem; /* Bootstrap's standard border-radius */
-  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.25); /* The border shadow */
-  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial,
-    sans-serif;
-}
-
-/*
-  Styling for the middle section that displays the file name.
-*/
-.file-name-display {
-  flex-grow: 1; /* This makes the element take up all available space */
-  font-style: italic;
-  color: #adb5bd; /* A muted gray color */
-  white-space: nowrap; /* Prevents the text from wrapping to a new line */
-  overflow: hidden; /* Hides any text that overflows the element's width */
-  text-overflow: ellipsis; /* Adds "..." to the end of overflowing text */
-}
-
-/*
-  Ensures the label (acting as a button) aligns properly.
-  Bootstrap buttons can sometimes have a default margin-bottom.
-*/
-.btn {
-  margin-bottom: 0;
-  flex-shrink: 0; /* Prevents buttons from shrinking if space is tight */
-}
-</style>
Index: serveNGo-frontend/src/components/Project/Utility/PhotosGridSystem.vue
===================================================================
--- ReserveNGo-frontend/src/components/Project/Utility/PhotosGridSystem.vue	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,97 +1,0 @@
-<script lang="ts">
-import { PropType } from 'vue'
-
-export default {
-  data() {
-    return {}
-  },
-  props: {
-    images: {
-      type: Array,
-      required: false,
-    },
-    openImageModal: {
-      type: Function as PropType<(imageIndex: number, secondRow?: boolean) => void>,
-      required: true,
-    },
-  },
-}
-</script>
-
-<template>
-  <div class="logo-options-wrapper">
-    <!-- Top row with 2 images -->
-    <div class="grid-row-top">
-      <img
-        @click="openImageModal(index)"
-        class="grid-image"
-        v-for="(image, index) in images.slice(0, 2)"
-        :key="index"
-        :src="image"
-        alt=""
-      />
-    </div>
-    <!-- Bottom row with 3 images -->
-    <div class="grid-row-bottom">
-      <img
-        @click="openImageModal(index, true)"
-        class="grid-image"
-        v-for="(image, index) in images.slice(2, 5)"
-        :key="index"
-        :src="image"
-        alt=""
-      />
-    </div>
-  </div>
-</template>
-
-<style scoped>
-/* Main wrapper to hold our grid rows */
-.logo-options-wrapper {
-  max-width: 100%;
-  margin: 1.5rem auto 0;
-  display: flex;
-  flex-direction: column;
-  gap: 0.5rem; /* Space between the top and bottom rows */
-}
-
-/* --- GRID SPECIFIC STYLES --- */
-
-.grid-row-top {
-  display: grid;
-  /* This is the magic: Create 2 columns of equal fractional width (2 x 1/2) */
-  grid-template-columns: 1fr 1fr;
-  gap: 0.5rem; /* This handles the space between the images perfectly */
-  /* grid-auto-rows: 50px;*/
-}
-
-.grid-row-bottom {
-  display: grid;
-  /* And here: Create 3 columns of equal fractional width (3 x 1/3) */
-  grid-template-columns: repeat(3, 1fr);
-  gap: 0.5rem; /* This handles the space between the images perfectly */
-}
-
-/* --- SHARED STYLES FOR IMAGES & RESPONSIVENESS --- */
-
-.grid-image {
-  /* This tells the image to fill the grid cell it's placed in */
-  width: 100%;
-  aspect-ratio: 1 / 1;
-  border-radius: 8px;
-  cursor: pointer;
-  outline: 3px solid transparent;
-  transition: outline-color 0.3s ease;
-}
-
-.grid-image:hover {
-  outline-color: #3498db;
-}
-
-/* On small screens, hide the top row */
-@media (max-width: 768px) {
-  .grid-row-top {
-    display: none;
-  }
-}
-</style>
Index: serveNGo-frontend/src/components/Project/Utility/PlusAddImage.vue
===================================================================
--- ReserveNGo-frontend/src/components/Project/Utility/PlusAddImage.vue	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,42 +1,0 @@
-<script lang="ts">
-export default {
-  data() {
-    return {
-      isProfileImageButtonDisabled: true,
-    }
-  },
-  methods: {},
-  mounted() {
-    this.isProfileImageButtonDisabled = true
-    const logoLocalePicture = document.getElementById('logoLocalePicture')
-    const inputProfilePicture = document.getElementById('logoPhotoInput')
-
-    inputProfilePicture.addEventListener('change', (event) => {
-      this.isProfileImageButtonDisabled = false
-
-      const file = event.target.files[0]
-      if (file && file.type.startsWith('image/')) {
-        const reader = new FileReader()
-        reader.onload = (e) => {
-          logoLocalePicture.src = e.target.result
-        }
-        reader.readAsDataURL(file)
-      }
-    })
-  },
-}
-</script>
-
-<template>
-  <input type="file" id="logoPhotoInput" class="" accept="image/*" />
-
-  <label
-    for="logoPhotoInput"
-    style="bottom: 0; right: 0.4rem; cursor: pointer"
-    class="position-absolute rounded-full"
-  >
-    <i style="font-size: 1.7rem" class="fa-solid fa-square-plus"></i>
-  </label>
-</template>
-
-<style scoped></style>
Index: serveNGo-frontend/src/components/Project/Utility/PopUpAlertIcon.vue
===================================================================
--- ReserveNGo-frontend/src/components/Project/Utility/PopUpAlertIcon.vue	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,10 +1,0 @@
-<template>
-  <svg xmlns="http://www.w3.org/2000/svg" width="2em" height="2em" viewBox="0 0 24 24">
-    <path
-      fill="currentColor"
-      fill-rule="evenodd"
-      d="M12 2C6.477 2 2 6.477 2 12s4.477 10 10 10s10-4.477 10-10S17.523 2 12 2m0 5a1 1 0 0 1 1 1v5a1 1 0 1 1-2 0V8a1 1 0 0 1 1-1m1 9a1 1 0 1 0-2 0a1 1 0 1 0 2 0"
-      clip-rule="evenodd"
-    />
-  </svg>
-</template>
Index: serveNGo-frontend/src/components/Project/Utility/PopUpWindow.vue
===================================================================
--- ReserveNGo-frontend/src/components/Project/Utility/PopUpWindow.vue	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,39 +1,0 @@
-<script lang="ts">
-import { defineComponent } from 'vue'
-
-export default defineComponent({
-  name: 'PopUpWindow',
-  props: {
-    isHoveringAlert: {
-      type: Boolean,
-    },
-  },
-})
-</script>
-
-<template>
-  <div :class="isHoveringAlert ? 'displayed' : 'hidden'" id="component"><slot></slot></div>
-</template>
-
-<style scoped>
-#component {
-  color: black;
-  position: absolute;
-  padding: 12px;
-  border: 1px solid #838282;
-  background-color: whitesmoke;
-  bottom: 0;
-  left: 100%;
-  box-shadow: 0 0 10px whitesmoke;
-  width: 300px;
-}
-#component.displayed {
-  display: block;
-}
-.displayed {
-  display: block;
-}
-.hidden {
-  display: none;
-}
-</style>
Index: serveNGo-frontend/src/components/Project/Utility/RightArrow.vue
===================================================================
--- ReserveNGo-frontend/src/components/Project/Utility/RightArrow.vue	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,12 +1,0 @@
-<template>
-  <svg xmlns="http://www.w3.org/2000/svg" width="1.2em" height="1.2em" viewBox="0 0 24 24">
-    <path
-      fill="none"
-      stroke="currentColor"
-      stroke-linecap="round"
-      stroke-linejoin="round"
-      stroke-width="2"
-      d="m9 6l6 6l-6 6"
-    />
-  </svg>
-</template>
Index: serveNGo-frontend/src/components/Project/Utility/ToastContainer.vue
===================================================================
--- ReserveNGo-frontend/src/components/Project/Utility/ToastContainer.vue	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,59 +1,0 @@
-<template>
-  <TransitionGroup tag="div" name="toast-stack" class="toast-container">
-    <ToastNotification
-      v-for="toast in toasts"
-      :key="toast.id"
-      :message="toast.message"
-      :type="toast.type"
-      :duration="toast.duration"
-      :id="toast.id"
-      @dismiss="removeToast"
-    />
-  </TransitionGroup>
-</template>
-
-<script>
-import ToastNotification from './ToastNotification.vue'
-import { useToasts } from '@/composables/useToast.js'
-
-export default {
-  name: 'ToastContainer',
-  components: { ToastNotification },
-  setup() {
-    const { toasts, removeToast } = useToasts()
-
-    return {
-      toasts,
-      removeToast,
-    }
-  },
-}
-</script>
-
-<style scoped>
-.toast-container {
-  position: fixed;
-  bottom: 1rem;
-  right: 1rem;
-  z-index: 9999;
-}
-
-/* --- Transitions for TransitionGroup --- */
-
-/* 1. Enter/Leave transitions (slide in/out from the right) */
-.toast-stack-enter-active,
-.toast-stack-leave-active {
-  transition: all 0.5s ease;
-}
-.toast-stack-enter-from,
-.toast-stack-leave-to {
-  opacity: 0;
-  transform: translateX(100%);
-}
-
-/* 2. Move transition (the magic for smooth stacking) */
-/* This is applied when items in the list change position */
-.toast-stack-move {
-  transition: transform 0.4s ease-out;
-}
-</style>
Index: serveNGo-frontend/src/components/Project/Utility/ToastNotification.vue
===================================================================
--- ReserveNGo-frontend/src/components/Project/Utility/ToastNotification.vue	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,71 +1,0 @@
-<template>
-  <div :class="['toast-notification', `toast--${type}`]">
-    <span class="toast-message">{{ message }}</span>
-    <div class="toast-timer" :style="{ animationDuration: `${duration}ms` }"></div>
-  </div>
-</template>
-
-<script>
-export default {
-  name: 'ToastNotification',
-  props: {
-    message: { type: String, required: true },
-    type: { type: String, default: 'success' },
-    duration: { type: Number, default: 5000 },
-    id: { type: [String, Number], required: true },
-  },
-  emits: ['dismiss'],
-  mounted() {
-    setTimeout(() => {
-      this.$emit('dismiss', this.id)
-    }, this.duration)
-  },
-}
-</script>
-
-<style scoped>
-@keyframes deplete {
-  from {
-    width: 100%;
-  }
-  to {
-    width: 0;
-  }
-}
-
-.toast-notification {
-  width: 320px;
-  margin-bottom: 1rem;
-  padding: 1rem;
-  border-radius: 8px;
-  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
-  display: flex;
-  flex-direction: column;
-  color: white;
-  position: relative;
-  overflow: hidden;
-}
-
-.toast--success {
-  background-color: #28a745;
-}
-.toast--error {
-  background-color: #dc3545;
-}
-
-.toast-message {
-  font-weight: 500;
-}
-
-.toast-timer {
-  position: absolute;
-  bottom: 0;
-  left: 0;
-  height: 4px;
-  background-color: rgba(255, 255, 255, 0.4);
-
-  animation-name: deplete;
-  animation-timing-function: linear;
-  animation-fill-mode: forwards;
-}
-</style>
Index: serveNGo-frontend/src/components/Project/Worker/WorkerReservationsDashboard.vue
===================================================================
--- ReserveNGo-frontend/src/components/Project/Worker/WorkerReservationsDashboard.vue	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,387 +1,0 @@
-<script>
-import LoadingIcon from '@/components/Project/Utility/LoadingIcon.vue'
-import { useLocalWorker } from '@/repository/LocalWorker.ts'
-import { useToasts } from '@/composables/useToast.js'
-
-export default {
-  components: { LoadingIcon },
-
-  data() {
-    return {
-      reservations: [],
-      statusFilter: 'ALL',
-
-      acceptingId: null,
-      denyingId: null,
-      finishingId: null,
-
-      showToast: useToasts().showToast,
-      sortKey: '',
-      sortOrder: 'asc',
-
-      // Multi-delete state
-      selectionMode: false,
-      selectedIds: [],
-      deletingSelected: false,
-    }
-  },
-
-  computed: {
-    filteredReservations() {
-      let data = [...this.reservations]
-
-      // filter
-      if (this.statusFilter !== 'ALL') {
-        data = data.filter((r) => r.reservationStatus === this.statusFilter)
-      }
-
-      // sort
-      if (!this.sortKey) return data
-
-      return data.sort((a, b) => {
-        let valueA = a[this.sortKey]
-        let valueB = b[this.sortKey]
-
-        // date sorting
-        if (this.sortKey === 'timeOfReservation') {
-          valueA = new Date(valueA).getTime()
-          valueB = new Date(valueB).getTime()
-        }
-
-        // string normalization
-        if (typeof valueA === 'string') {
-          valueA = valueA.toLowerCase()
-          valueB = valueB.toLowerCase()
-        }
-
-        if (valueA < valueB) return this.sortOrder === 'asc' ? -1 : 1
-        if (valueA > valueB) return this.sortOrder === 'asc' ? 1 : -1
-        return 0
-      })
-    },
-  },
-
-  methods: {
-    async fetchReservations() {
-      try {
-        this.reservations = await useLocalWorker.getReservations()
-      } catch (error) {
-        console.error(error)
-        this.showToast('Failed to load reservations.', 'error')
-      }
-    },
-
-    // Multiple delete helpers
-    startSelection() {
-      this.selectionMode = true
-      this.selectedIds = []
-    },
-    cancelSelection() {
-      this.selectionMode = false
-      this.selectedIds = []
-    },
-    toggleSelect(reservation) {
-      const id = reservation?.reservationId ?? null
-      if (id == null) return
-      const idx = this.selectedIds.indexOf(id)
-      if (idx >= 0) this.selectedIds.splice(idx, 1)
-      else this.selectedIds.push(id)
-    },
-    async confirmDeleteSelected() {
-      if (!this.selectedIds.length) return
-      if (!confirm(`Delete ${this.selectedIds.length} reservation(s)?`)) return
-      try {
-        this.deletingSelected = true
-        await useLocalWorker.deleteReservations({ reservationIds: this.selectedIds })
-        const set = new Set(this.selectedIds)
-        this.reservations = this.reservations.filter((r) => !set.has(r.reservationId))
-        this.showToast('Selected reservations deleted successfully.', 'success')
-        this.cancelSelection()
-      } catch (error) {
-        console.error(error)
-        this.showToast('Failed to delete selected reservations.', 'error')
-      } finally {
-        this.deletingSelected = false
-      }
-    },
-
-    async acceptReservation(id) {
-      this.acceptingId = id
-      try {
-        await useLocalWorker.acceptReservation(id)
-        this.showToast('Reservation accepted.', 'success')
-        await this.fetchReservations()
-      } catch (error) {
-        console.error(error)
-        this.showToast('Failed to accept reservation.', 'error')
-      } finally {
-        this.acceptingId = null
-      }
-    },
-
-    async denyReservation(id) {
-      this.denyingId = id
-      try {
-        await useLocalWorker.denyReservation(id)
-        this.showToast('Reservation denied.', 'success')
-        await this.fetchReservations()
-      } catch (error) {
-        console.error(error)
-        this.showToast('Failed to deny reservation.', 'error')
-      } finally {
-        this.denyingId = null
-      }
-    },
-
-    async finishReservation(id) {
-      this.finishingId = id
-      try {
-        await useLocalWorker.finishReservation(id)
-        this.showToast('Reservation finished.', 'success')
-        await this.fetchReservations()
-      } catch (error) {
-        console.error(error)
-        this.showToast('Failed to finish reservation.', 'error')
-      } finally {
-        this.finishingId = null
-      }
-    },
-
-    canAccept(status) {
-      return status === 'PENDING'
-    },
-    canDeny(status) {
-      return status === 'PENDING' || status === 'ACCEPTED'
-    },
-    canFinish(status) {
-      return status === 'ACCEPTED'
-    },
-    formatDate(timestamp) {
-      if (!timestamp) return '-'
-
-      const date = new Date(timestamp)
-
-      const dd = String(date.getDate()).padStart(2, '0')
-      const mm = String(date.getMonth() + 1).padStart(2, '0')
-      const yyyy = date.getFullYear()
-
-      const hh = String(date.getHours()).padStart(2, '0')
-      const min = String(date.getMinutes()).padStart(2, '0')
-
-      return `${dd}.${mm}.${yyyy} - ${hh}:${min}`
-    },
-    sortBy(key) {
-      if (this.sortKey === key) {
-        this.sortOrder = this.sortOrder === 'asc' ? 'desc' : 'asc'
-      } else {
-        this.sortKey = key
-        this.sortOrder = 'asc'
-      }
-    },
-  },
-
-  mounted() {
-    this.fetchReservations()
-  },
-}
-</script>
-
-<template>
-  <div class="container mt-4">
-    <h4 class="mb-3">Reservations Overview</h4>
-    <hr>
-
-    <!-- Status Filter -->
-    <div class="mb-3 d-flex gap-2 justify-content-between align-items-center">
-      <!-- Left: filter -->
-      <select v-model="statusFilter" class="form-select form-select-sm w-auto">
-        <option value="ALL">All</option>
-        <option value="PENDING">Pending</option>
-        <option value="ACCEPTED">Accepted</option>
-        <option value="CANCELED">Cancelled</option>
-        <option value="FINISHED">Finished</option>
-        <option value="EXPIRED">Expired</option>
-      </select>
-
-      <!-- Right: multi-delete controls -->
-      <div class="ms-auto">
-        <template v-if="!selectionMode">
-          <button
-            class="btn btn-outline-danger btn-sm"
-            @click="startSelection"
-            :disabled="filteredReservations.length === 0"
-          >
-            <i class="fas fa-trash-alt me-1"></i> Delete Reservations
-          </button>
-        </template>
-        <template v-else>
-          <div class="btn-group">
-            <button
-              class="btn btn-danger btn-sm"
-              :disabled="selectedIds.length === 0 || deletingSelected"
-              @click="confirmDeleteSelected"
-            >
-              <span
-                v-if="deletingSelected"
-                class="spinner-border spinner-border-sm me-1"
-                role="status"
-                aria-hidden="true"
-              ></span>
-              <i v-else class="fas fa-check me-1"></i>
-              Confirm delete ({{ selectedIds.length }})
-            </button>
-            <button
-              class="btn btn-secondary btn-sm"
-              :disabled="deletingSelected"
-              @click="cancelSelection"
-            >
-              Cancel
-            </button>
-          </div>
-        </template>
-      </div>
-    </div>
-
-    <!-- Reservations Table -->
-    <div class="table-responsive shadow-sm table-container">
-      <table class="table table-striped table-hover align-middle">
-        <thead class="table-light">
-          <tr>
-            <th v-if="selectionMode" style="width: 48px">Select</th>
-            <th style="cursor: pointer" @click="sortBy('customerName')">
-              Customer
-              <span v-if="sortKey === 'customerName'">
-                {{ sortOrder === 'asc' ? '↑' : '↓' }}
-              </span>
-            </th>
-
-            <th style="cursor: pointer" @click="sortBy('timeOfReservation')">
-              Time
-              <span v-if="sortKey === 'timeOfReservation'">
-                {{ sortOrder === 'asc' ? '↑' : '↓' }}
-              </span>
-            </th>
-
-            <th style="cursor: pointer" @click="sortBy('reservationStatus')">
-              Status
-              <span v-if="sortKey === 'reservationStatus'">
-                {{ sortOrder === 'asc' ? '↑' : '↓' }}
-              </span>
-            </th>
-
-            <th>
-              Description
-            </th>
-
-            <th style="cursor: pointer" @click="sortBy('capacity')">
-              Capacity
-              <span v-if="sortKey === 'capacity'">
-                {{ sortOrder === 'asc' ? '↑' : '↓' }}
-              </span>
-            </th>
-
-            <th class="text-end">Actions</th>
-          </tr>
-        </thead>
-
-        <tbody>
-          <tr v-for="reservation in filteredReservations" :key="reservation.reservationId">
-            <td v-if="selectionMode">
-              <input
-                type="checkbox"
-                class="form-check-input"
-                :checked="selectedIds.includes(reservation.reservationId)"
-                @change="toggleSelect(reservation)"
-              />
-            </td>
-            <td>{{ reservation.customerName }}</td>
-            <td>{{ formatDate(reservation.timeOfReservation) }}</td>
-            <td>
-              <span class="badge bg-secondary">
-                {{ reservation.reservationStatus }}
-              </span>
-            </td>
-            <td>{{ reservation.description }}</td>
-            <td>{{ reservation.capacity }}</td>
-
-            <td class="text-end">
-              <div class="btn-group btn-group-sm">
-                <button
-                  v-if="canAccept(reservation.reservationStatus)"
-                  class="btn btn-outline-success"
-                  @click="acceptReservation(reservation.reservationId)"
-                  :disabled="acceptingId === reservation.reservationId || selectionMode"
-                >
-                  <LoadingIcon v-if="acceptingId === reservation.reservationId" />
-                  <span v-else>Accept</span>
-                </button>
-
-                <button
-                  v-if="canDeny(reservation.reservationStatus)"
-                  class="btn btn-outline-danger"
-                  @click="denyReservation(reservation.reservationId)"
-                  :disabled="denyingId === reservation.reservationId || selectionMode"
-                >
-                  <LoadingIcon v-if="denyingId === reservation.reservationId" />
-                  <span v-else>Deny</span>
-                </button>
-
-                <button
-                  v-if="canFinish(reservation.reservationStatus)"
-                  class="btn btn-outline-primary"
-                  @click="finishReservation(reservation.reservationId)"
-                  :disabled="finishingId === reservation.reservationId || selectionMode"
-                >
-                  <LoadingIcon v-if="finishingId === reservation.reservationId" />
-                  <span v-else>Finish</span>
-                </button>
-              </div>
-            </td>
-          </tr>
-
-          <tr v-if="filteredReservations.length === 0">
-            <td :colspan="selectionMode ? 7 : 6" class="text-center text-muted py-4">
-              No reservations found.
-            </td>
-          </tr>
-        </tbody>
-      </table>
-    </div>
-  </div>
-</template>
-
-<style scoped>
-.container {
-  max-width: 1200px;
-  margin: 0 auto;
-}
-
-.table-container {
-  max-height: 65vh;
-  overflow-y: auto;
-}
-
-table {
-  table-layout: fixed;
-  width: 100%;
-  font-size: 0.95rem;
-}
-
-th,
-td {
-  white-space: nowrap;
-  overflow: hidden;
-  text-overflow: ellipsis;
-}
-
-thead th {
-  position: sticky;
-  top: 0;
-  background-color: #f8f9fa;
-  z-index: 2;
-}
-
-.badge {
-  font-size: 0.75rem;
-}
-</style>
Index: serveNGo-frontend/src/components/Project/home_.vue
===================================================================
--- ReserveNGo-frontend/src/components/Project/home_.vue	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,399 +1,0 @@
-<script>
-import Locale_listing_container from '@/components/Project/Local/Locale_listing_container.vue'
-import Event_listing_container from '@/components/Project/Event/event_listing_container.vue'
-import SearchFilterPanel from '@/components/Project/search_filter_panel.vue'
-import Events_carousel from '@/components/Project/Event/events_carousel.vue'
-import { ensureEventDateTime } from '@/utils/utilFunctions.js'
-import { userStore } from '@/PiniaStores/UserStore.js'
-
-import { useEvents } from '@/repository/Events.ts'
-import { useLocales } from '@/repository/Locale.ts'
-import { useCustomer } from '@/repository/Customer.ts'
-
-export default {
-  components: {
-    Locale_listing_container,
-    Event_listing_container,
-    SearchFilterPanel,
-    Events_carousel,
-  },
-
-  data() {
-    return {
-      locals: [],
-      events: [],
-      carouselEvents: [],
-      favouriteLocals: [],
-      favouriteEvents: [],
-      user: userStore(),
-
-      activeView: 'locals',
-      isFavouritesMode: false,
-
-      localPage: 0,
-      localTotalPages: 0,
-      eventPage: 0,
-      eventTotalPages: 0,
-      pageSize: 5,
-
-      /* filters */
-      lastSearch: '',
-      lastSortBy: 'name',
-      lastDirection: 'asc',
-
-      lastIsOpen: null,
-      lastLocalType: null,
-      lastServices: [],
-
-      lastEventStatus: null,
-      lastEventType: null,
-    }
-  },
-
-  computed: {
-    // Enrich events with helper date/time fields derived from eventStart
-    enrichedEvents() {
-      if (!this.events || this.events.length === 0) return []
-      // Map to the same objects but ensure date/time props exist
-      return this.events.map((ev) => ensureEventDateTime(ev))
-    },
-  },
-
-  methods: {
-    /* ===================== LOCALS ===================== */
-    fetchLocals(page = 0) {
-      useLocales
-        .getLocals({
-          name: this.lastSearch,
-          sortBy: this.lastSortBy,
-          direction: this.lastDirection,
-          isOpen: this.lastIsOpen,
-          localType: this.lastLocalType,
-          services: this.lastServices,
-          page,
-          size: this.pageSize,
-        })
-        .then((data) => {
-          this.locals = data.locals
-          this.localPage = data.currentPage
-          this.localTotalPages = data.totalPages
-        })
-        .catch((err) => console.log('Failed fetching locals', err))
-    },
-
-    /* ===================== EVENTS ===================== */
-    fetchEvents(page = 0) {
-      useEvents
-        .getEvents({
-          name: this.lastSearch,
-          sortBy: this.lastSortBy,
-          direction: this.lastDirection,
-          eventStatus: this.lastEventStatus,
-          eventType: this.lastEventType,
-          page,
-          size: this.pageSize,
-        })
-        .then((data) => {
-          this.events = data.events
-          this.eventPage = data.currentPage
-          this.eventTotalPages = data.totalPages
-        })
-        .catch((err) => console.log('Failed fetching events', err))
-    },
-
-    fetchCarouselEvents() {
-      useEvents
-        .getEvents({
-          page: 0,
-          size: 9,
-          sortBy: 'createdAt',
-          direction: 'desc',
-        })
-        .then((data) => {
-          this.carouselEvents = data.events
-          console.log('EVENTS', data.events)
-        })
-        .catch((err) => console.log('Failed fetching carousel events', err))
-    },
-
-    /* ===================== SEARCH / FILTER ===================== */
-    sendSearchQuery(payload) {
-      this.lastSearch = payload.name || ''
-      this.lastSortBy = payload.sortBy || 'name'
-      this.lastDirection = payload.direction || 'asc'
-
-      if (this.activeView === 'locals') {
-        this.lastIsOpen = payload.isOpen
-        this.lastLocalType = payload.localType
-        this.lastServices = payload.services || []
-
-        this.localPage = 0
-        this.fetchLocals(0)
-      } else {
-        this.lastEventStatus = payload.eventStatus
-        this.lastEventType = payload.eventType
-
-        this.eventPage = 0
-        this.fetchEvents(0)
-      }
-    },
-
-    setActiveView(view) {
-      this.activeView = view
-
-      // Load data if switching view and a list is empty
-      if (view === 'locals' && this.locals.length === 0) {
-        this.fetchLocals(this.localPage)
-      }
-
-      if (view === 'events' && this.events.length === 0) {
-        this.fetchEvents(this.eventPage)
-      }
-    },
-
-    /* ===================== FAVOURITES ===================== */
-    async loadFavouriteLocals() {
-      try {
-        const data = await useCustomer.getFavouriteLocals()
-        // Expecting an array of local objects
-        this.favouriteLocals = data || []
-      } catch (err) {
-        console.log('Failed to fetch favourite locals', err)
-        this.favouriteLocals = []
-      }
-    },
-
-    async loadFavouriteEvents() {
-      try {
-        const data = await useCustomer.getFavouriteEvent()
-        // API sometimes returns { events: [...] } or array directly
-        this.favouriteEvents = data.events || data || []
-      } catch (error) {
-        console.log('Failed to fetch favourite events', error)
-        this.favouriteEvents = []
-      }
-    },
-
-    // Called when event card emits toggle
-    toggleFavouriteEvent(id) {
-      const isFav = this.favouriteEvents.map((item) => item.id).includes(id)
-      const action = isFav
-        ? useCustomer.removeFavouriteEvent(id)
-        : useCustomer.addFavouriteEvent(id)
-
-      Promise.resolve(action)
-        .then(() => {
-          if (isFav) {
-            this.favouriteEvents = this.favouriteEvents.filter((fav) => fav.id !== id)
-          } else {
-            // find in current events page (if exists) and push an object
-            const event = this.events.find((e) => e.id === id)
-            if (event) {
-              this.favouriteEvents.push(event)
-            } else {
-              // If the event wasn't in currently loaded events, it's safer to reload favourites
-              this.loadFavouriteEvents()
-            }
-          }
-        })
-        .catch((err) => console.log('Error toggling favourite event:', err))
-    },
-
-    // Called when local card emits toggle
-    toggleFavouriteLocal(id) {
-      const isFav = this.favouriteLocals.map((item) => item.id).includes(id)
-      const action = isFav ? useCustomer.removeFavourite(id) : useCustomer.addFavourite(id)
-
-      Promise.resolve(action)
-        .then(() => {
-          if (isFav) {
-            this.favouriteLocals = this.favouriteLocals.filter((fav) => fav.id !== id)
-          } else {
-            const local = this.locals.find((l) => l.id === id)
-            if (local) {
-              this.favouriteLocals.push(local)
-            } else {
-              // If the local isn't on the current page, reload favourites
-              this.loadFavouriteLocals()
-            }
-          }
-        })
-        .catch((err) => console.log('Error toggling favourite local:', err))
-    },
-  },
-
-  beforeMount() {
-    // only get carousel here — the rest is handled in the watcher, so we react to route changes
-    this.fetchCarouselEvents()
-  },
-
-  watch: {
-    '$route.query.mode': {
-      immediate: true,
-      async handler(mode) {
-        this.isFavouritesMode = mode === 'favourites'
-
-        // ALWAYS load favourites (needed for correct toggle state)
-        if (this.user.data.role === 'ROLE_CUSTOMER') {
-          await this.loadFavouriteEvents()
-          await this.loadFavouriteLocals()
-        } else {
-          this.favouriteEvents = []
-          this.favouriteLocals = []
-        }
-
-        if (!this.isFavouritesMode) {
-          this.fetchLocals(0)
-          this.fetchEvents(0)
-        }
-      },
-    },
-  },
-}
-</script>
-
-<template>
-  <div class="home-page-wrapper">
-    <div class="container-fluid px-0">
-      <div class="row justify-content-center">
-        <!-- SEARCH -->
-        <SearchFilterPanel :activeView="activeView" @search-query-sent="sendSearchQuery" />
-
-        <!-- EVENTS CAROUSEL (NOT PAGED) -->
-        <div class="col-12 events-section-wrapper">
-          <div class="container">
-            <Events_carousel :all-events="carouselEvents" />
-          </div>
-        </div>
-
-        <!-- VIEW TOGGLE -->
-        <div class="col-md-8">
-          <div class="navigation-toggle">
-            <button
-              @click="setActiveView('locals')"
-              :class="['nav-btn', { active: activeView === 'locals' }]"
-            >
-              <i class="fas fa-utensils me-2"></i>Locals
-            </button>
-            <button
-              @click="setActiveView('events')"
-              :class="['nav-btn', { active: activeView === 'events' }]"
-            >
-              <i class="fas fa-calendar-alt me-2"></i>Events
-            </button>
-          </div>
-        </div>
-
-        <!-- LISTING -->
-        <div class="col-md-8 listing-column">
-          <Locale_listing_container
-            v-if="activeView === 'locals'"
-            :locals="locals"
-            :mode="isFavouritesMode ? 'favourites' : 'all'"
-            :favouriteLocals="favouriteLocals"
-            @toggle-favourite="toggleFavouriteLocal"
-          />
-
-          <Event_listing_container
-            v-else
-            :mode="isFavouritesMode ? 'favourites' : 'all'"
-            :events="enrichedEvents"
-            :favouriteEvents="favouriteEvents"
-            @toggle-favourite="toggleFavouriteEvent"
-          />
-
-          <!-- ===================== PAGINATION ===================== -->
-          <div
-            v-if="!isFavouritesMode && activeView === 'locals' && localTotalPages > 1"
-            class="d-flex justify-content-center align-items-center mt-4 gap-2"
-          >
-            <button
-              class="btn btn-outline-secondary"
-              :disabled="localPage === 0"
-              @click="fetchLocals(localPage - 1)"
-            >
-              Prev
-            </button>
-
-            <span>Page {{ localPage + 1 }} of {{ localTotalPages }}</span>
-
-            <button
-              class="btn btn-outline-secondary"
-              :disabled="localPage >= localTotalPages - 1"
-              @click="fetchLocals(localPage + 1)"
-            >
-              Next
-            </button>
-          </div>
-
-          <div
-            v-if="!isFavouritesMode && activeView === 'events' && eventTotalPages > 1"
-            class="d-flex justify-content-center align-items-center mt-4 gap-2"
-          >
-            <button
-              class="btn btn-outline-secondary"
-              :disabled="eventPage === 0"
-              @click="fetchEvents(eventPage - 1)"
-            >
-              Prev
-            </button>
-
-            <span>Page {{ eventPage + 1 }} of {{ eventTotalPages }}</span>
-
-            <button
-              class="btn btn-outline-secondary"
-              :disabled="eventPage >= eventTotalPages - 1"
-              @click="fetchEvents(eventPage + 1)"
-            >
-              Next
-            </button>
-          </div>
-          <!-- ===================== END PAGINATION ===================== -->
-        </div>
-      </div>
-    </div>
-  </div>
-</template>
-
-<style scoped>
-.home-page-wrapper {
-  overflow-x: hidden;
-}
-
-.events-section-wrapper {
-  background-color: #f3f5f8;
-  padding: 0.75rem 0;
-  margin-bottom: 0.5rem;
-  border-bottom: 1px solid #dee2e6;
-}
-
-.navigation-toggle {
-  display: flex;
-  gap: 1rem;
-  padding: 1rem 1rem 0.5rem;
-  background-color: #f3f5f8;
-}
-
-.nav-btn {
-  flex: 1;
-  padding: 0.75rem 1.5rem;
-  background-color: #fff;
-  border: 2px solid #dee2e6;
-  border-radius: 8px;
-  font-weight: 500;
-  color: #6c757d;
-  cursor: pointer;
-  transition: all 0.3s ease;
-}
-
-.nav-btn.active {
-  background-color: #5ea5bc;
-  border-color: #5ea5bc;
-  color: #fff;
-}
-
-.listing-column {
-  background-color: #f3f5f8;
-  padding: 1rem;
-}
-</style>
Index: serveNGo-frontend/src/components/Project/search_filter_panel.vue
===================================================================
--- ReserveNGo-frontend/src/components/Project/search_filter_panel.vue	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,273 +1,0 @@
-<script setup lang="ts">
-import { ref, watch, computed } from 'vue'
-import { getEnumLabel } from '@/utils/enumLabels'
-
-const props = defineProps({
-  activeView: {
-    type: String,
-    default: 'locals',
-  },
-})
-
-/* ===================== STATE ===================== */
-const searchInput = ref('')
-const sortQuery = ref('')
-
-/* Locals */
-const isOpen = ref(false)
-const localType = ref<string | null>(null)
-const services = ref<string[]>([])
-
-/* Events */
-const eventStatus = ref<string | null>(null)
-const eventType = ref<string | null>(null)
-
-/* ===================== OPTIONS ===================== */
-const localSortOptions = [
-  { value: 'name,asc', text: 'Name (A–Z)' },
-  { value: 'name,desc', text: 'Name (Z–A)' },
-  { value: 'rating,desc', text: 'Highest rating' },
-  { value: 'createdAt,desc', text: 'Newest' },
-]
-
-const eventSortOptions = [
-  { value: 'name,asc', text: 'Name (A–Z)' },
-  { value: 'name,desc', text: 'Name (Z–A)' },
-  { value: 'createdAt,desc', text: 'Newest' },
-]
-
-const localTypes = [
-  { value: 'RESTAURANT', label: getEnumLabel('RESTAURANT', 'LocalType') },
-  { value: 'CAFE', label: getEnumLabel('CAFE', 'LocalType') },
-  { value: 'BAR', label: getEnumLabel('BAR', 'LocalType') },
-  { value: 'PUB', label: getEnumLabel('PUB', 'LocalType') },
-  { value: 'BISTRO', label: getEnumLabel('BISTRO', 'LocalType') },
-  { value: 'FOOD_TRUCK', label: getEnumLabel('FOOD_TRUCK', 'LocalType') },
-  { value: 'BUFFET', label: getEnumLabel('BUFFET', 'LocalType') },
-  { value: 'FAST_FOOD', label: getEnumLabel('FAST_FOOD', 'LocalType') },
-  { value: 'LOUNGE', label: getEnumLabel('LOUNGE', 'LocalType') },
-  { value: 'DELI', label: getEnumLabel('DELI', 'LocalType') },
-]
-
-const serviceOptions = [
-  { value: 'WIFI', label: getEnumLabel('WIFI', 'ProvidedService') },
-  { value: 'PET_FRIENDLY', label: getEnumLabel('PET_FRIENDLY', 'ProvidedService') },
-  { value: 'PARKING', label: getEnumLabel('PARKING', 'ProvidedService') },
-  { value: 'OUTDOOR', label: getEnumLabel('OUTDOOR', 'ProvidedService') },
-  { value: 'INDOOR', label: getEnumLabel('INDOOR', 'ProvidedService') },
-  { value: 'PLAYGROUND', label: getEnumLabel('PLAYGROUND', 'ProvidedService') },
-  { value: 'VEGAN_FRIENDLY', label: getEnumLabel('VEGAN_FRIENDLY', 'ProvidedService') },
-  { value: 'VEGETARIAN_FRIENDLY', label: getEnumLabel('VEGETARIAN_FRIENDLY', 'ProvidedService') },
-  { value: 'GLUTEN_FREE_FRIENDLY', label: getEnumLabel('GLUTEN_FREE_FRIENDLY', 'ProvidedService') },
-  { value: 'FAMILY_KIDS_FRIENDLY', label: getEnumLabel('FAMILY_KIDS_FRIENDLY', 'ProvidedService') },
-  { value: 'SMOKING_FRIENDLY', label: getEnumLabel('SMOKING_FRIENDLY', 'ProvidedService') },
-]
-
-const eventStatuses = [
-  { value: 'UPCOMING', label: 'Upcoming' },
-  { value: 'ACTIVE', label: 'Active' },
-  { value: 'FINISHED', label: 'Finished' },
-]
-
-const eventTypes = [
-  { value: 'LIVE_MUSIC', label: getEnumLabel('LIVE_MUSIC', 'EventType') },
-  { value: 'DJ_NIGHT', label: getEnumLabel('DJ_NIGHT', 'EventType') },
-  { value: 'FOOD_SPECIAL', label: getEnumLabel('FOOD_SPECIAL', 'EventType') },
-  { value: 'DRINK_SPECIAL', label: getEnumLabel('DRINK_SPECIAL', 'EventType') },
-  { value: 'HAPPY_HOUR', label: getEnumLabel('HAPPY_HOUR', 'EventType') },
-  { value: 'SPORTS_SCREENING', label: getEnumLabel('SPORTS_SCREENING', 'EventType') },
-  { value: 'KARAOKE', label: getEnumLabel('KARAOKE', 'EventType') },
-  { value: 'THEME_PARTY', label: getEnumLabel('THEME_PARTY', 'EventType') },
-  { value: 'OPEN_MIC', label: getEnumLabel('OPEN_MIC', 'EventType') },
-  { value: 'COOKING_WORKSHOP', label: getEnumLabel('COOKING_WORKSHOP', 'EventType') },
-  { value: 'ART_EXHIBITION', label: getEnumLabel('ART_EXHIBITION', 'EventType') },
-  { value: 'COMEDY_SHOW', label: getEnumLabel('COMEDY_SHOW', 'EventType') },
-  { value: 'GAME_NIGHT', label: getEnumLabel('GAME_NIGHT', 'EventType') },
-  { value: 'PRIVATE_EVENT', label: getEnumLabel('PRIVATE_EVENT', 'EventType') },
-  { value: 'SEASONAL_EVENT', label: getEnumLabel('SEASONAL_EVENT', 'EventType') },
-]
-
-const sortOptions = computed(() =>
-  props.activeView === 'locals' ? localSortOptions : eventSortOptions,
-)
-
-/* ===================== EMIT ===================== */
-const emit = defineEmits<{ (e: 'searchQuerySent', payload: any): void }>()
-let debounceTimer: number | null = null
-
-watch([searchInput, sortQuery, isOpen, localType, services, eventStatus, eventType], () => {
-  if (debounceTimer) clearTimeout(debounceTimer)
-
-  debounceTimer = window.setTimeout(() => {
-    const [sortBy, direction = 'asc'] = sortQuery.value.split(',')
-
-    if (props.activeView === 'locals') {
-      emit('searchQuerySent', {
-        name: searchInput.value,
-        sortBy,
-        direction,
-        isOpen: isOpen.value || null,
-        localType: localType.value,
-        services: services.value,
-      })
-    } else {
-      emit('searchQuerySent', {
-        name: searchInput.value,
-        sortBy,
-        direction,
-        eventStatus: eventStatus.value,
-        eventType: eventType.value,
-      })
-    }
-  }, 350)
-})
-</script>
-
-<template>
-  <div class="search-bar-wrapper">
-    <div class="container">
-      <div class="row justify-content-center">
-        <!-- ================= FILTER BOX ================= -->
-        <div class="col-12 col-md-10 search-bar shadow-sm px-3 py-3">
-          <div class="row g-2 align-items-center">
-            <!-- SEARCH -->
-            <div class="col-12 col-md-4">
-              <input
-                v-model="searchInput"
-                type="text"
-                class="form-control"
-                :placeholder="activeView === 'locals' ? 'Search locals…' : 'Search events…'"
-              />
-            </div>
-
-            <!-- SORT -->
-            <div class="col-6 col-md-2">
-              <select v-model="sortQuery" class="form-select">
-                <option disabled value="">Sort by</option>
-                <option v-for="opt in sortOptions" :key="opt.value" :value="opt.value">
-                  {{ opt.text }}
-                </option>
-              </select>
-            </div>
-
-            <!-- LOCALS FILTERS -->
-            <template v-if="activeView === 'locals'">
-              <!-- LOCAL TYPE -->
-              <div class="col-6 col-md-3">
-                <select v-model="localType" class="form-select">
-                  <option :value="null">Type</option>
-                  <option v-for="t in localTypes" :key="t.value" :value="t.value">
-                    {{ t.label }}
-                  </option>
-                </select>
-              </div>
-
-              <!-- SERVICES (SAME ROW) -->
-              <div class="col-12 col-md-3">
-                <div class="dropdown w-100">
-                  <button
-                    class="form-select services-select"
-                    type="button"
-                    data-bs-toggle="dropdown"
-                  >
-                    Services
-                    <span v-if="services.length" class="badge bg-primary ms-1">
-                      {{ services.length }}
-                    </span>
-                  </button>
-
-                  <ul class="dropdown-menu p-3 services-dropdown">
-                    <li v-for="s in serviceOptions" :key="s.value">
-                      <div class="form-check">
-                        <input
-                          class="form-check-input"
-                          type="checkbox"
-                          :value="s.value"
-                          v-model="services"
-                        />
-                        <label class="form-check-label">
-                          {{ s.label }}
-                        </label>
-                      </div>
-                    </li>
-                  </ul>
-                </div>
-              </div>
-            </template>
-
-            <!-- EVENTS FILTERS -->
-            <template v-else>
-              <div class="col-6 col-md-3">
-                <select v-model="eventStatus" class="form-select">
-                  <option :value="null">Status</option>
-                  <option v-for="s in eventStatuses" :key="s.value" :value="s.value">
-                    {{ s.label }}
-                  </option>
-                </select>
-              </div>
-
-              <div class="col-6 col-md-3">
-                <select v-model="eventType" class="form-select">
-                  <option :value="null">Type</option>
-                  <option v-for="t in eventTypes" :key="t.value" :value="t.value">
-                    {{ t.label }}
-                  </option>
-                </select>
-              </div>
-            </template>
-          </div>
-        </div>
-
-        <!-- ================= OPEN NOW (OUTSIDE BOX) ================= -->
-        <div
-          v-if="activeView === 'locals'"
-          class="col-12 col-md-10 mt-2 d-flex align-items-center gap-2"
-        >
-          <div class="form-check form-switch">
-            <input class="form-check-input open-switch" type="checkbox" v-model="isOpen" />
-          </div>
-          <span class="fw-medium text-success">Open now</span>
-        </div>
-      </div>
-    </div>
-  </div>
-</template>
-
-<style scoped>
-.search-bar-wrapper {
-  position: sticky;
-  top: 0;
-  z-index: 900;
-}
-
-.search-bar {
-  background-color: #f3f5f8;
-  border-radius: 10px;
-}
-
-/* Services dropdown styled like select */
-.services-select {
-  appearance: none;
-  background-color: #fff;
-  border: 1px solid #ced4da;
-  cursor: pointer;
-  text-align: left;
-}
-
-.services-select:focus {
-  border-color: #86b7fe;
-  box-shadow: 0 0 0 0.25rem rgba(13, 110, 253, 0.25);
-}
-
-.services-dropdown {
-  min-width: 260px;
-  max-height: 300px;
-  overflow-y: auto;
-}
-
-/* Green switch */
-.open-switch:checked {
-  background-color: #5ea5bc;
-  border-color: #5ea5bc;
-}
-</style>
Index: serveNGo-frontend/src/composables/useToast.js
===================================================================
--- ReserveNGo-frontend/src/composables/useToast.js	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,29 +1,0 @@
-import { readonly, reactive } from 'vue'
-
-const toasts = reactive([])
-
-function showToast(message, type = 'success', duration = 5000) {
-  const id = Date.now() + Math.random()
-
-  toasts.push({
-    id,
-    message,
-    type,
-    duration,
-  })
-}
-
-function removeToast(id) {
-  const index = toasts.findIndex((toast) => toast.id === id)
-  if (index > -1) {
-    toasts.splice(index, 1)
-  }
-}
-
-export function useToasts() {
-  return {
-    toasts: readonly(toasts),
-    showToast,
-    removeToast,
-  }
-}
Index: serveNGo-frontend/src/constants/Api_config.js
===================================================================
--- ReserveNGo-frontend/src/constants/Api_config.js	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,37 +1,0 @@
-// Build API base URL using .env values API_BASE_URL and API_LISTEN_PORT
-// Falls back to localhost:8080 if not provided
-const RAW_BASE = import.meta.env.API_BASE_URL || import.meta.env.VITE_API_BASE_URL || 'http://localhost'
-const RAW_PORT = import.meta.env.API_LISTEN_PORT || import.meta.env.VITE_API_LISTEN_PORT || '8080'
-
-function buildBaseUrl(hostLike, portLike) {
-  try {
-    // If hostLike already includes protocol, host, and maybe port/path
-    const u = new URL(hostLike)
-    // If the port is not specified in hostLike, apply the provided port
-    if (!u.port && portLike) {
-      u.port = String(portLike)
-    }
-    return u.origin
-  } catch (e) {
-    // hostLike might be just a hostname without protocol
-    const prefixed = hostLike.startsWith('http') ? hostLike : `http://${hostLike}`
-    try {
-      const u2 = new URL(prefixed)
-      if (!u2.port && portLike) {
-        u2.port = String(portLike)
-      }
-      return u2.origin
-    } catch (e2) {
-      // Fallback
-      return `http://localhost:${portLike || '8080'}`
-    }
-  }
-}
-
-const API_ORIGIN = buildBaseUrl(RAW_BASE, RAW_PORT)
-
-export const config = {
-  API_BASE_URL: API_ORIGIN,
-  API_LISTEN_PORT: RAW_PORT,
-}
-console.log('API_ORIGIN', config)
Index: serveNGo-frontend/src/main.js
===================================================================
--- ReserveNGo-frontend/src/main.js	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,31 +1,0 @@
-import { createApp } from 'vue'
-import { createPinia } from 'pinia'
-import vue3GoogleLogin from 'vue3-google-login'
-
-import App from './App.vue'
-import router from './router'
-
-import { createVuetify } from 'vuetify'
-import * as components from 'vuetify/components'
-import * as directives from 'vuetify/directives'
-import '@mdi/font/css/materialdesignicons.css'
-import 'bootstrap/dist/css/bootstrap.min.css'
-import 'bootstrap/dist/js/bootstrap.bundle.min.js'
-import '@fortawesome/fontawesome-free/css/all.min.css'
-import '@/assets/main.css'
-
-const vuetify = createVuetify({
-  components,
-  directives,
-})
-
-const app = createApp(App)
-
-app.use(createPinia())
-app.use(router)
-app.use(vuetify)
-app.use(vue3GoogleLogin, {
-  clientId: import.meta.env.VITE_GOOGLE_CLIENT_ID,
-})
-
-app.mount('#app')
Index: serveNGo-frontend/src/repository/Admin.ts
===================================================================
--- ReserveNGo-frontend/src/repository/Admin.ts	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,45 +1,0 @@
-import { config } from '@/constants/Api_config'
-import { HttpClient } from '@/Api_Classes/HttpClient'
-
-const BASE_API_URL = config.API_BASE_URL
-
-class Admin {
-  private readonly httpClient: HttpClient
-
-  constructor(baseUrl: string) {
-    this.httpClient = new HttpClient(baseUrl)
-  }
-
-  inviteManager(newEmail: string): Promise<any> {
-    return this.httpClient.post('invite-manager', { newEmail })
-  }
-  addRestaurant(name: string): Promise<any> {
-    return this.httpClient.post('add-local', { name })
-  }
-
-  async deleteRestaurant(localId: number): Promise<any> {
-    return this.httpClient.delete(`delete-local/${localId}`)
-  }
-
-  fetchRestaurants(): Promise<any> {
-    return this.httpClient.get('locals')
-  }
-
-  fetchLocalMangers(): Promise<any> {
-    return this.httpClient.get('local-managers')
-  }
-
-  fetchManagersForRestaurant(localId: number): Promise<any> {
-    return this.httpClient.get(`local-managers/${localId}`)
-  }
-
-  async assignManager(localId: number, managerId: number): Promise<any> {
-    return this.httpClient.post(`assign/${localId}/${managerId}`)
-  }
-
-  async removeManager(managerId : number) {
-    return this.httpClient.delete(`remove/${managerId}`)
-  }
-}
-
-export const useAdmin = new Admin(BASE_API_URL + '/api/admin')
Index: serveNGo-frontend/src/repository/Authentication.ts
===================================================================
--- ReserveNGo-frontend/src/repository/Authentication.ts	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,50 +1,0 @@
-import { config } from '@/constants/Api_config'
-import { HttpClient } from '@/Api_Classes/HttpClient'
-
-const BASE_API_URL = config.API_BASE_URL
-
-class Authentication {
-  private readonly httpClient: HttpClient
-
-  constructor(baseUrl: string) {
-    this.httpClient = new HttpClient(baseUrl)
-  }
-
-  makeLogin(email: String, password: String): Promise<any> {
-    return this.httpClient.post('login', { email, password })
-  }
-  // Google OAuth login
-  makeGoogleLogin(googleIdToken: String): Promise<any> {
-    const headers: Record<string, any> = { 'X-Google-Token': googleIdToken }
-    return this.httpClient.post('oauth/google/login', null, { headers })
-  }
-  makeRegister(
-    firstName: String,
-    lastName: String,
-    email: String,
-    phoneNumber: String,
-    password: String,
-    role: String,
-    inviteToken?: String,
-  ) {
-    return this.httpClient.post(
-      'register/' + role,
-      { firstName, lastName, email, phoneNumber, password },
-      { headers: { 'Invite-Token': inviteToken } },
-    )
-  }
-  verifyAccount(email: String, verificationCode: String): Promise<any> {
-    return this.httpClient.patch('verify', { email, verificationCode })
-  }
-  reEnableAccount(email: String, password: String): Promise<any> {
-    return this.httpClient.patch('enable', { email, password })
-  }
-
-  googleRegister(role: String, googleIdToken: String, inviteToken?: String): Promise<any> {
-    const headers: Record<string, any> = { 'X-Google-Token': googleIdToken }
-    if (inviteToken) headers['Invite-Token'] = inviteToken
-    return this.httpClient.post(`oauth/google/${role}`, null, { headers })
-  }
-}
-
-export const useAuth = new Authentication(BASE_API_URL + '/api/auth')
Index: serveNGo-frontend/src/repository/Customer.ts
===================================================================
--- ReserveNGo-frontend/src/repository/Customer.ts	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,47 +1,0 @@
-import { config } from '@/constants/Api_config'
-import { HttpClient } from '@/Api_Classes/HttpClient'
-
-const BASE_API_URL = config.API_BASE_URL
-
-class CustomerRepository {
-  private readonly httpClient: HttpClient
-
-  constructor(baseUrl: string) {
-    this.httpClient = new HttpClient(baseUrl)
-  }
-
-  // FAVOURITES
-  getFavouriteLocals(): Promise<any[]> {
-    return this.httpClient.get('favourite-locals')
-  }
-  addFavourite(localId: number | string): Promise<any> {
-    return this.httpClient.post(`favourite-locals/add/${localId}`, {})
-  }
-  removeFavourite(localId: number | string): Promise<any> {
-    return this.httpClient.post(`favourite-locals/remove/${localId}`, {})
-  }
-
-  getFavouriteEvent(): Promise<any> {
-    return this.httpClient.get(`favourite-events`)
-  }
-  addFavouriteEvent(eventId: number | string): Promise<any> {
-    return this.httpClient.post(`favourite-events/add/${eventId}`)
-  }
-
-  removeFavouriteEvent(eventId: number | string): Promise<any> {
-    return this.httpClient.post(`favourite-events/remove/${eventId}`)
-  }
-
-  // RATINGS
-  getRatingForLocal(localId: number | string): Promise<any> {
-    return this.httpClient.get(`local/${localId}/rating`)
-  }
-  rateLocal(localId: number | string, rating: number): Promise<any> {
-    return this.httpClient.put(`local/${localId}/rate`, { rating })
-  }
-  removeRating(localId: number | string): Promise<any> {
-    return this.httpClient.delete(`local/${localId}/remove-rating`)
-  }
-}
-
-export const useCustomer = new CustomerRepository(BASE_API_URL + '/api/customer')
Index: serveNGo-frontend/src/repository/Events.ts
===================================================================
--- ReserveNGo-frontend/src/repository/Events.ts	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,35 +1,0 @@
-import { config } from '@/constants/Api_config'
-import { HttpClient } from '@/Api_Classes/HttpClient'
-
-const BASE_API_URL = config.API_BASE_URL
-
-class EventsRepository {
-  private readonly httpClient: HttpClient
-
-  constructor(baseUrl: string) {
-    this.httpClient = new HttpClient(baseUrl)
-  }
-
-  getEvents(params: {
-    localId?: number
-    name?: string
-    eventType?: string
-    eventStatus?: string
-    sortBy?: string
-    direction?: string
-    page?: number
-    size?: number
-  }) {
-    const queryParams: any = {}
-
-    Object.entries(params).forEach(([key, value]) => {
-      if (value !== undefined && value !== null) {
-        queryParams[key] = value
-      }
-    })
-
-    return this.httpClient.get('', { queryParams })
-  }
-}
-
-export const useEvents = new EventsRepository(BASE_API_URL + '/api/events')
Index: serveNGo-frontend/src/repository/LocalManager.ts
===================================================================
--- ReserveNGo-frontend/src/repository/LocalManager.ts	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,63 +1,0 @@
-import { config } from '@/constants/Api_config'
-import { HttpClient } from '@/Api_Classes/HttpClient'
-
-const BASE_API_URL = config.API_BASE_URL
-
-class LocalManager {
-  private readonly httpClient: HttpClient
-
-  constructor(baseUrl: string) {
-    this.httpClient = new HttpClient(baseUrl)
-  }
-
-  getMyLocal(): Promise<any> {
-    return this.httpClient.get('my-local')
-  }
-
-  getLocalWorkers(): Promise<any[]> {
-    return this.httpClient.get('local-workers')
-  }
-
-  getAvailableWorkers(): Promise<any[]> {
-    return this.httpClient.get('workers')
-  }
-
-  assignWorker(workerId: string): Promise<any> {
-    return this.httpClient.post(`assign/${workerId}`, {})
-  }
-
-  removeWorker(workerId: string): Promise<any> {
-    return this.httpClient.delete(`remove/${workerId}`)
-  }
-
-  changeWorkerPosition(workerId: string, position: string): Promise<any> {
-    return this.httpClient.put(`change-position/${workerId}`, { position })
-  }
-
-  uploadLogo(formData: FormData): Promise<any> {
-    return this.httpClient.upload('upload-logo', formData)
-  }
-  uploadImage(formData: FormData): Promise<any> {
-    return this.httpClient.upload('upload-photo', formData)
-  }
-  deletePhoto(photoUrls: Object): Promise<any> {
-    return this.httpClient.delete('delete-photos', photoUrls)
-  }
-  saveDetailChanges(payload): Promise<any> {
-    return this.httpClient.put('my-local/edit', payload)
-  }
-  addEvent(formData: FormData): Promise<any> {
-    return this.httpClient.post('add-event', formData)
-  }
-  updateEvent(formData: FormData, eventId : number): Promise<any> {
-    return this.httpClient.put(`events/edit/${eventId}`, formData)
-  }
-  deleteEvent(eventId: number): Promise<any> {
-    return this.httpClient.delete(`delete-event/${eventId}`)
-  }
-  inviteWorker(newEmail: string): Promise<any> {
-    return this.httpClient.post('invite-worker', { newEmail })
-  }
-}
-
-export const useLocalManager = new LocalManager(BASE_API_URL + '/api/local-manager')
Index: serveNGo-frontend/src/repository/LocalWorker.ts
===================================================================
--- ReserveNGo-frontend/src/repository/LocalWorker.ts	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,45 +1,0 @@
-import { config } from '@/constants/Api_config'
-import { HttpClient } from '@/Api_Classes/HttpClient'
-import { ReservationStatus } from '@/repository/Reservations'
-
-const BASE_API_URL = config.API_BASE_URL
-
-export type DashboardReservationDisplayDTO = {
-  reservationId?: number | string
-  customerName?: string
-  customerId?: number | string
-  timeOfReservation: string
-  tableCapacity: number
-  reservationStatus: ReservationStatus
-}
-
-class LocalWorker {
-  private readonly httpClient: HttpClient
-
-  constructor(baseUrl: string) {
-    this.httpClient = new HttpClient(baseUrl)
-  }
-
-  getReservations(): Promise<DashboardReservationDisplayDTO[]> {
-    return this.httpClient.get('reservations')
-  }
-
-  acceptReservation(reservationId: number): Promise<any> {
-    return this.httpClient.put(`reservations/${reservationId}/accept`)
-  }
-
-  denyReservation(reservationId: number): Promise<any> {
-    return this.httpClient.put(`reservations/${reservationId}/deny`)
-  }
-
-  finishReservation(reservationId: number): Promise<any> {
-    return this.httpClient.put(`reservations/${reservationId}/finish`)
-  }
-
-  // DELETE /api/local-worker/reservations/delete
-  deleteReservations(dto: { reservationIds: Array<number | string> }): Promise<void> {
-    return this.httpClient.delete('reservations/delete', dto)
-  }
-}
-
-export const useLocalWorker = new LocalWorker(BASE_API_URL + '/api/local-worker')
Index: serveNGo-frontend/src/repository/Locale.ts
===================================================================
--- ReserveNGo-frontend/src/repository/Locale.ts	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,39 +1,0 @@
-import { config } from '@/constants/Api_config'
-import { HttpClient } from '@/Api_Classes/HttpClient'
-
-const BASE_API_URL = config.API_BASE_URL
-
-class Locale {
-  private readonly httpClient: HttpClient
-
-  constructor(baseUrl: string) {
-    this.httpClient = new HttpClient(baseUrl)
-  }
-
-  getLocals(params: {
-    name?: string
-    services?: string[]
-    localType?: string
-    isOpen?: boolean | null
-    sortBy?: string
-    direction?: string
-    page?: number
-    size?: number
-  }) {
-    const queryParams: any = {}
-
-    Object.entries(params).forEach(([key, value]) => {
-      if (value !== undefined && value !== null && !(Array.isArray(value) && value.length === 0)) {
-        queryParams[key] = value
-      }
-    })
-
-    return this.httpClient.get('', { queryParams })
-  }
-
-  getSpecificLocale(localeId: number) {
-    return this.httpClient.get(`${localeId}`)
-  }
-}
-
-export const useLocales = new Locale(BASE_API_URL + '/api/locals')
Index: serveNGo-frontend/src/repository/Reservations.ts
===================================================================
--- ReserveNGo-frontend/src/repository/Reservations.ts	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,77 +1,0 @@
-import { config } from '@/constants/Api_config'
-import { HttpClient } from '@/Api_Classes/HttpClient'
-
-const BASE_API_URL = config.API_BASE_URL
-
-export type CreateReservationDTO = {
-  timeOfReservation: string
-  capacity: number
-  description?: string
-}
-
-export type ReservationStatus = 'PENDING' | 'CONFIRMED' | 'CANCELLED' | string
-
-export type DisplayReservationDTO = {
-  id?: number | string
-  localName: string
-  localLogo: string | null
-  timeOfReservation: string
-  capacity: number
-  description?: string
-  status: ReservationStatus
-}
-
-export type EditReservationDTO = {
-  timeOfReservation: string // ISO string
-  capacity: number
-  description: string
-}
-
-export type DeleteReservationDTO = {
-  reservationIds: Array<number | string>
-}
-
-class ReservationsRepository {
-  private readonly httpClient: HttpClient
-
-  constructor(baseUrl: string) {
-    this.httpClient = new HttpClient(baseUrl)
-  }
-
-  // POST /api/reservations/make-reservation
-  makeReservation(dto: CreateReservationDTO, localId: number): Promise<any> {
-    return this.httpClient.post(`${localId}/create`, dto)
-  }
-
-  // GET /api/reservations
-  listMyReservations(): Promise<DisplayReservationDTO[]> {
-    return this.httpClient.get('')
-  }
-
-  // PUT /api/reservations/{id}/cancel
-  cancelReservation(reservationId: number | string): Promise<void> {
-    return this.httpClient.put(`${reservationId}/cancel`, null)
-  }
-
-  // GET /api/reservations/{id}
-  getReservationDetails(reservationId: number | string): Promise<DisplayReservationDTO> {
-    return this.httpClient.get(`${reservationId}`)
-  }
-
-  // PUT /api/reservations/{id}/edit
-  editReservation(
-    reservationId: number | string,
-    dto: EditReservationDTO,
-  ): Promise<DisplayReservationDTO> {
-    return this.httpClient.put(`${reservationId}/edit`, dto)
-  }
-
-  // DELETE /api/customer/reservations/delete
-  deleteReservations(dto: DeleteReservationDTO): Promise<void> {
-    return this.httpClient.delete('delete', dto)
-  }
-}
-
-export const useReservations = new ReservationsRepository(
-  BASE_API_URL + '/api/customer/reservations',
-)
Index: serveNGo-frontend/src/repository/user.ts
===================================================================
--- ReserveNGo-frontend/src/repository/user.ts	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,45 +1,0 @@
-import { config } from '@/constants/Api_config'
-import { HttpClient } from '@/Api_Classes/HttpClient'
-
-const BASE_API_URL = config.API_BASE_URL
-
-class UserManager {
-  private readonly httpClient: HttpClient
-
-  constructor(baseUrl: string) {
-    this.httpClient = new HttpClient(baseUrl)
-  }
-
-  getProfile(): Promise<any> {
-    return this.httpClient.get('profile')
-  }
-
-  updateProfile(payload: {
-    firstName: string
-    lastName: string
-    phoneNumber: string
-  }): Promise<any> {
-    return this.httpClient.put('edit', payload)
-  }
-
-  changeEmail(payload: { newEmail: string }): Promise<any> {
-    return this.httpClient.patch('change-email', payload)
-  }
-
-  changePassword(payload: { currentPassword: string; newPassword: string }): Promise<any> {
-    return this.httpClient.patch('change-password', payload)
-  }
-
-  uploadAvatar(formData: FormData): Promise<any> {
-    return this.httpClient.upload('upload-avatar', formData)
-  }
-
-  deleteAvatar(): Promise<any> {
-    return this.httpClient.delete('delete-avatar')
-  }
-  disableUserAccount(): Promise<any> {
-    return this.httpClient.patch('disable')
-  }
-}
-
-export const useUser = new UserManager(BASE_API_URL + '/api/user')
Index: serveNGo-frontend/src/repository/utility.ts
===================================================================
--- ReserveNGo-frontend/src/repository/utility.ts	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,16 +1,0 @@
-import { ApiClient } from '@/Api_Classes/ApiClient'
-import { config } from '@/constants/Api_config'
-
-const BASE_API_URL = config.API_BASE_URL
-
-class Utility extends ApiClient {
-  constructor(baseUrl: string) {
-    super(baseUrl)
-  }
-
-  fetchImageBase64(imagePath: string): Promise<any> {
-    return this.httpClient.fetchImageAsBase64(imagePath)
-  }
-}
-
-export const useUtility = new Utility(BASE_API_URL)
Index: serveNGo-frontend/src/router/index.js
===================================================================
--- ReserveNGo-frontend/src/router/index.js	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,136 +1,0 @@
-import { createRouter, createWebHistory } from 'vue-router'
-
-import home_ from '@/components/Project/home_.vue'
-import login_ from '@/components/Project/Auth/login_.vue'
-import register_ from '@/components/Project/Auth/register_.vue'
-import my_reservations from '@/components/Project/Reservation/My_reservations.vue'
-import Locale_ from '@/components/Project/Local/Locale_.vue'
-import Profile_Page from '@/components/Project/Customer/Profile_Page.vue'
-import AdminDashboard from '@/components/Project/Admin/AdminDashboard.vue'
-import LocalNotAssigned from '@/components/Project/Local/LocalNotAssigned.vue'
-import ManagerDashboard from '@/components/Project/Manager/ManagerDashboard.vue'
-import Locale_listing_container from '@/components/Project/Local/Locale_listing_container.vue'
-import DisabledAccountPage from '@/components/Project/Auth/DisabledAccountPage.vue'
-import WorkerReservationsDashboard from '@/components/Project/Worker/WorkerReservationsDashboard.vue'
-import AboutUs from '@/components/Project/StaticPages/AboutUs.vue'
-import ContactComp from '@/components/Project/StaticPages/ContactComp.vue'
-import PrivacyPolicy from '@/components/Project/StaticPages/PrivacyPolicy.vue'
-import { useLocalManager } from '@/repository/LocalManager'
-import { useLocalWorker } from '@/repository/LocalWorker'
-
-const managerBeforeEnter = async (to, from, next) => {
-  try {
-    await useLocalManager.getMyLocal()
-    next()
-  } catch (err) {
-    const status = err?.status ?? err?.response?.status
-    if (status === 409) {
-      next({ name: 'LocalNotAssigned' })
-    } else {
-      console.error('Error checking manager local assignment', err)
-      next(false)
-    }
-  }
-}
-
-const workerBeforeEnter = async (to, from, next) => {
-  try {
-    await useLocalWorker.getReservations()
-    next()
-  } catch (err) {
-    const status = err?.status ?? err?.response?.status
-    if (status === 409) {
-      next({ name: 'LocalNotAssigned' })
-    } else {
-      console.error('Error checking worker local assignment', err)
-      next(false)
-    }
-  }
-}
-
-const router = createRouter({
-  history: createWebHistory(import.meta.env.BASE_URL),
-  routes: [
-    {
-      path: '/favourite_locals/:mode',
-      name: 'favourite_locals',
-      component: Locale_listing_container,
-      props: true,
-    },
-    {
-      path: '/my_reservations',
-      name: 'my reservations',
-      component: my_reservations,
-    },
-    {
-      path: '/',
-      name: 'home',
-      component: home_,
-    },
-    {
-      path: '/login',
-      name: 'login',
-      component: login_,
-    },
-    {
-      path: '/register/:userType?',
-      name: 'register',
-      component: register_,
-    },
-    {
-      path: '/more_details/:id',
-      name: 'more_details',
-      component: Locale_,
-    },
-    {
-      path: '/local-not-assigned',
-      name: 'LocalNotAssigned',
-      component: LocalNotAssigned,
-    },
-
-    {
-      path: '/profilePage',
-      name: 'profilePage',
-      component: Profile_Page,
-    },
-    {
-      path: '/admin-dashboard',
-      name: 'admin-dashboard',
-      component: AdminDashboard,
-    },
-    {
-      path: '/manager-dashboard',
-      name: 'manager-dashboard',
-      component: ManagerDashboard,
-      beforeEnter: managerBeforeEnter,
-    },
-    {
-      path: '/disabledAccountPage',
-      name: 'disabledAccountPage',
-      component: DisabledAccountPage,
-    },
-    {
-      path: '/worker-reservations-dashboard',
-      name: 'worker-reservations-dashboard',
-      component: WorkerReservationsDashboard,
-      beforeEnter: workerBeforeEnter,
-    },
-    {
-      path: '/about-us',
-      name: 'about-us',
-      component: AboutUs,
-    },
-    {
-      path: '/contact',
-      name: 'contact',
-      component: ContactComp,
-    },
-    {
-      path: '/privacy-policy',
-      name: 'privacy-policy',
-      component: PrivacyPolicy,
-    },
-  ],
-})
-
-export default router
Index: serveNGo-frontend/src/types.d.ts
===================================================================
--- ReserveNGo-frontend/src/types.d.ts	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,12 +1,0 @@
-declare module '*.jpg' {
-  const value: string
-  export default value
-}
-declare module '*.png' {
-  const value: string
-  export default value
-}
-declare module '*.svg' {
-  const value: string
-  export default value
-}
Index: serveNGo-frontend/src/utils/enumLabels.ts
===================================================================
--- ReserveNGo-frontend/src/utils/enumLabels.ts	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,75 +1,0 @@
-// Generic fallback
-export function enumToLabel(value?: string): string {
-  if (!value) return ''
-
-  return value
-    .toLowerCase()
-    .split('_')
-    .map((word) => word.charAt(0).toUpperCase() + word.slice(1))
-    .join(' ')
-}
-
-export const EnumLabelMaps = {
-  LocalType: {
-    RESTAURANT: 'Restaurant',
-    CAFE: 'Cafe',
-    BAR: 'Bar',
-    PUB: 'Pub',
-    BISTRO: 'Bistro',
-    FOOD_TRUCK: 'Food truck',
-    BUFFET: 'Buffet',
-    FAST_FOOD: 'Fast food',
-    LOUNGE: 'Lounge',
-    DELI: 'Deli',
-  },
-  EventType: {
-    DJ_NIGHT: 'DJ night',
-    LIVE_MUSIC: 'Live music',
-    FOOD_SPECIAL: 'Food special',
-    DRINK_SPECIAL: 'Drink special',
-    HAPPY_HOUR: 'Happy hour',
-    SPORTS_SCREENING: 'Sports screening',
-    KARAOKE: 'Karaoke',
-    THEME_PARTY: 'Theme party',
-    OPEN_MIC: 'Open mic',
-    COOKING_WORKSHOP: 'Cooking workshop',
-    ART_EXHIBITION: 'Art exhibition',
-    COMEDY_SHOW: 'Comedy show',
-    GAME_NIGHT: 'Game night',
-    PRIVATE_EVENT: 'Private event',
-    SEASONAL_EVENT: 'Seasonal event',
-  },
-  ProvidedService: {
-    WIFI: 'Wi-Fi',
-    PET_FRIENDLY: 'Pet friendly',
-    FAMILY_KIDS_FRIENDLY: 'Family & kids friendly',
-    PARKING: 'Parking',
-    OUTDOOR: 'Outdoor seating',
-    INDOOR: 'Indoor seating',
-    PLAYGROUND: 'Playground',
-    VEGAN_FRIENDLY: 'Vegan friendly',
-    VEGETARIAN_FRIENDLY: 'Vegetarian friendly',
-    GLUTEN_FREE_FRIENDLY: 'Gluten free friendly',
-    SMOKING_FRIENDLY: 'Smoking friendly',
-  },
-} as const
-
-export type EnumGroup = keyof typeof EnumLabelMaps
-
-export function getEnumLabel(enumValue: string | undefined, enumGroup?: EnumGroup): string {
-  if (!enumValue) return ''
-
-  if (enumGroup && EnumLabelMaps[enumGroup] && EnumLabelMaps[enumGroup][enumValue]) {
-    return EnumLabelMaps[enumGroup][enumValue as keyof (typeof EnumLabelMaps)[typeof enumGroup]]
-  }
-
-  return enumToLabel(enumValue)
-}
-
-export function getEnumOptions(enumGroup?: EnumGroup): Array<{ value: string; label: string }> {
-  if (!enumGroup || !EnumLabelMaps[enumGroup]) return []
-  return Object.keys(EnumLabelMaps[enumGroup]).map((k) => ({
-    value: k,
-    label: (EnumLabelMaps[enumGroup] as Record<string, string>)[k],
-  }))
-}
Index: serveNGo-frontend/src/utils/utilFunctions.js
===================================================================
--- ReserveNGo-frontend/src/utils/utilFunctions.js	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,49 +1,0 @@
-export function transformDate(dateTime) {
-  let [date, time] = dateTime.split('T')
-  let timeSplit = time.split(':')
-  time = timeSplit[0] + ':' + timeSplit[1]
-  return { date: date, time: time }
-}
-
-export function ensureEventDateTime(event) {
-  if (!event) return event
-  try {
-    const start = event?.eventStart
-    if (typeof start === 'string' && start.includes('T')) {
-      const [datePart, timePartRaw] = start.split('T')
-      const timeParts = (timePartRaw || '').split(':')
-      const hhmm = timeParts.length >= 2 ? `${timeParts[0]}:${timeParts[1]}` : ''
-      if (!event.date) event.date = datePart
-      if (!event.time) event.time = hhmm
-    } else if (start && typeof start === 'object') {
-      if (!event.date && start.date) event.date = start.date
-      if (!event.time && start.time) event.time = start.time
-    }
-  } catch (e) {
-  }
-  return event
-}
-
-export function transformArray(arr, howMany, doDateEdit = true) {
-  const copiedArray = JSON.parse(JSON.stringify(arr))
-
-  if (doDateEdit) {
-    copiedArray.forEach((item) => {
-      item.eventEnd = transformDate(item.eventEnd)
-      item.eventStart = transformDate(item.eventStart)
-    })
-  }
-
-  let newArray = []
-  for (let i = 0; i < arr.length; i += howMany) {
-    newArray.push(copiedArray.slice(i, i + howMany))
-  }
-  return newArray
-}
-
-export function isValidEmail(email) {
-  const emailRegex = new RegExp(
-    /^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/,
-  )
-  return emailRegex.test(email)
-}
Index: serveNGo-frontend/vite.config.js
===================================================================
--- ReserveNGo-frontend/vite.config.js	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,17 +1,0 @@
-import {fileURLToPath, URL} from 'node:url'
-
-import {defineConfig} from 'vite'
-import vue from '@vitejs/plugin-vue'
-import vueDevTools from 'vite-plugin-vue-devtools'
-
-// https://vite.dev/config/
-export default defineConfig({
-  plugins: [vue(), vueDevTools()],
-  // Allow using environment variables starting with API_ in addition to VITE_
-  envPrefix: ['VITE_', 'API_'],
-  resolve: {
-    alias: {
-      '@': fileURLToPath(new URL('./src', import.meta.url))
-    },
-  },
-})
Index: serveNGo-frontend/vitest.config.js
===================================================================
--- ReserveNGo-frontend/vitest.config.js	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,14 +1,0 @@
-import { fileURLToPath } from 'node:url'
-import { mergeConfig, defineConfig, configDefaults } from 'vitest/config'
-import viteConfig from './vite.config'
-
-export default mergeConfig(
-  viteConfig,
-  defineConfig({
-    test: {
-      environment: 'jsdom',
-      exclude: [...configDefaults.exclude, 'e2e/**'],
-      root: fileURLToPath(new URL('./', import.meta.url)),
-    },
-  }),
-)
Index: cker-compose.yml
===================================================================
--- docker-compose.yml	(revision 040563284d04e1dd27e171fe80cf2f0c26f168cd)
+++ 	(revision )
@@ -1,49 +1,0 @@
-services:
-  frontend:
-    build:
-      context: ./ReserveNGo-frontend
-      dockerfile: Dockerfile
-      args:
-        VITE_API_BASE_URL: ${VITE_API_BASE_URL}
-        VITE_GOOGLE_CLIENT_ID: ${VITE_GOOGLE_CLIENT_ID}
-    ports:
-      - "5173:80"
-    depends_on:
-      - backend
-
-  backend:
-    build:
-      context: ./ReserveNGo-backend
-      dockerfile: Dockerfile
-    ports:
-      - "8080:8080"
-    depends_on:
-      - db
-    environment:
-      SPRING_PROFILES_ACTIVE: prod
-      PG_DB_HOST: ${PG_DB_HOST}
-      PG_DB_USER: ${PG_DB_USER}
-      PG_DB_PORT: ${PG_DB_PORT}
-      PG_DB_PASSWORD: ${PG_DB_PASSWORD}
-      MAIL_HOST: ${MAIL_HOST}
-      MAIL_PORT: ${MAIL_PORT}
-      MAIL_USERNAME: ${MAIL_USERNAME}
-      MAIL_PASSWORD: ${MAIL_PASSWORD}
-      CLIENT_ID: ${CLIENT_ID}
-      CLIENT_SECRET: ${CLIENT_SECRET}
-
-  db:
-    image: postgres:17
-    container_name: database
-    restart: always
-    environment:
-      POSTGRES_DB: ${PG_DB_NAME}
-      POSTGRES_USER: ${PG_DB_USER}
-      POSTGRES_PASSWORD: ${PG_DB_PASSWORD}
-    ports:
-      - "5433:5432"
-    volumes:
-      - db_data:/var/lib/postgresql/data
-
-volumes:
-  db_data:
