diff --git a/.dockerignore b/.dockerignore
deleted file mode 100644
index bb28cbb16ed2cc2e3111ec3d031d709e80643963..0000000000000000000000000000000000000000
--- a/.dockerignore
+++ /dev/null
@@ -1,33 +0,0 @@
-# Dependency directories
-/node_modules
-
-# Distribution directories
-/dist
-/build
-
-# Environment files
-.env.*
-
-# Editor directories and files
-.vscode
-.idea
-*.suo
-*.ntvs*
-*.njsproj
-*.sln
-*.sw?
-
-# Cache directories
-/.cache
-
-# Test directories
-/coverage
-/cypress/videos/
-/cypress/screenshots/
-
-# Temporary files
-*.temp
-
-# System files
-.DS_Store
-Thumbs.db
\ No newline at end of file
diff --git a/.eslintrc.cjs b/.eslintrc.cjs
deleted file mode 100644
index 6617ed2a88898f11fd513893024133b50cc14c7a..0000000000000000000000000000000000000000
--- a/.eslintrc.cjs
+++ /dev/null
@@ -1,26 +0,0 @@
-/* eslint-env node */
-require('@rushstack/eslint-patch/modern-module-resolution')
-
-module.exports = {
-  root: true,
-  'extends': [
-    'plugin:vue/vue3-essential',
-    'eslint:recommended',
-    '@vue/eslint-config-typescript',
-    '@vue/eslint-config-prettier/skip-formatting'
-  ],
-  overrides: [
-    {
-      files: [
-        'cypress/e2e/**/*.{cy,spec}.{js,ts,jsx,tsx}',
-        'cypress/support/**/*.{js,ts,jsx,tsx}'
-      ],
-      'extends': [
-        'plugin:cypress/recommended'
-      ]
-    }
-  ],
-  parserOptions: {
-    ecmaVersion: 'latest'
-  }
-}
diff --git a/.gitignore b/.gitignore
deleted file mode 100644
index 8ee54e8d343e466a213c8c30aa04be77126b170d..0000000000000000000000000000000000000000
--- a/.gitignore
+++ /dev/null
@@ -1,30 +0,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
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
deleted file mode 100644
index 10032958b39ddcdf8800fb2191a028ed56336cc0..0000000000000000000000000000000000000000
--- a/.gitlab-ci.yml
+++ /dev/null
@@ -1,65 +0,0 @@
-image: node:20-slim
-
-stages:
-  - install
-  - lint_and_format
-  - build
-  - test
-  - security_scan
-
-cache:
-  key: ${CI_COMMIT_REF_SLUG}
-  paths:
-    - node_modules/
-
-install:
-  stage: install
-  script:
-    - npm install
-  artifacts:
-    paths:
-      - node_modules/
-
-format-code:
-  stage: lint_and_format
-  script:
-    - npm run format-test
-
-lint-code:
-  stage: lint_and_format
-  script:
-    - npm run lint
-
-type-check:
-  stage: build
-  script:
-    - npm run type-check
-    - npm run build
-
-unit-tests:
-  stage: test
-  script:
-    - npm run test:unit
-
-test:e2e:
-  image: cypress/browsers:node16.14.2-slim-chrome100-ff99-edge
-  stage: test
-  script:
-    - npm ci --cache .npm --prefer-offline
-    - npx cypress verify
-    - npm run test:e2e
-  dependencies:
-    - install
-
-test-coverage:
-  stage: test
-  script:
-    - npm run test:coverage
-
-include:
-  - template: SAST.gitlab-ci.yml
-
-sast:
-  stage: security_scan
-  script:
-    - echo "Running SAST..."
\ No newline at end of file
diff --git a/.prettierrc.json b/.prettierrc.json
deleted file mode 100644
index 34f62fb090b60fba4944a1cd0ddaf1505e0d45e4..0000000000000000000000000000000000000000
--- a/.prettierrc.json
+++ /dev/null
@@ -1,9 +0,0 @@
-{
-  "$schema": "https://json.schemastore.org/prettierrc",
-  "semi": false,
-  "tabWidth": 4,
-  "singleQuote": true,
-  "printWidth": 100,
-  "trailingComma": "none",
-  "endOfLine": "lf"
-}
\ No newline at end of file
diff --git a/.vscode/extensions.json b/.vscode/extensions.json
deleted file mode 100644
index 93ea3e7838b1b661bb7052023576ffa6deb2e7a1..0000000000000000000000000000000000000000
--- a/.vscode/extensions.json
+++ /dev/null
@@ -1,7 +0,0 @@
-{
-  "recommendations": [
-    "Vue.volar",
-    "dbaeumer.vscode-eslint",
-    "esbenp.prettier-vscode"
-  ]
-}
diff --git a/Dockerfile b/Dockerfile
deleted file mode 100644
index a61fa0595dc86c1c85276f06baefd2b01f827abf..0000000000000000000000000000000000000000
--- a/Dockerfile
+++ /dev/null
@@ -1,13 +0,0 @@
-FROM node:21.5.0
-
-WORKDIR /app
-
-COPY package*.json ./
-
-RUN npm install
-
-COPY . .
-
-EXPOSE 5173
-
-CMD [ "npm", "run", "dev" ]
\ No newline at end of file
diff --git a/Makefile b/Makefile
deleted file mode 100644
index c483e0b12516af8ea4d80e3cf72efbf340d9a9a1..0000000000000000000000000000000000000000
--- a/Makefile
+++ /dev/null
@@ -1,25 +0,0 @@
-.PHONY: build run run-dev unit e2e clean-docker
-
-build-docker:
-	docker build -t sparesti_frontend .
-
-run-docker:
-	docker run --rm --name sparesti_frontend_container -p 5173:5173 sparesti_frontend
-
-clean-docker:
-	-docker stop sparesti_frontend_container
-	-docker rm sparesti_frontend_container
-
-run:
-	make build-docker
-	make clean-docker
-	make run-docker
-
-run-dev:
-	npm run dev
-
-unit:
-	npm run test:unit
-
-e2e:
-	npm run test:e2e
diff --git a/README.md b/README.md
deleted file mode 100644
index d1a779a4752196653f8658c6d493f3e14e6619c5..0000000000000000000000000000000000000000
--- a/README.md
+++ /dev/null
@@ -1,61 +0,0 @@
-# idatt2106_2024_02_frontend
-
-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).
-
-## Type Support for `.vue` Imports in TS
-
-TypeScript cannot handle type information for `.vue` imports by default, so we replace the `tsc` CLI with `vue-tsc` for type checking. In editors, we need [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) to make the TypeScript language service aware of `.vue` types.
-
-## Customize configuration
-
-See [Vite Configuration Reference](https://vitejs.dev/config/).
-
-## Project Setup
-
-```sh
-npm install
-```
-
-### Compile and Hot-Reload for Development
-
-```sh
-npm run dev
-```
-
-### Type-Check, Compile and Minify for Production
-
-```sh
-npm run build
-```
-
-### Run Unit Tests with [Vitest](https://vitest.dev/)
-
-```sh
-npm run test:unit
-```
-
-### Run End-to-End Tests with [Cypress](https://www.cypress.io/)
-
-```sh
-npm run test:e2e:dev
-```
-
-This runs the end-to-end tests against the Vite development server.
-It is much faster than the production build.
-
-But it's still recommended to test the production build with `test:e2e` before deploying (e.g. in CI environments):
-
-```sh
-npm run build
-npm run test:e2e
-```
-
-### Lint with [ESLint](https://eslint.org/)
-
-```sh
-npm run lint
-```
diff --git a/cypress.config.ts b/cypress.config.ts
deleted file mode 100644
index 3b0082d8d060e60816c857dafd22ef7e42c74320..0000000000000000000000000000000000000000
--- a/cypress.config.ts
+++ /dev/null
@@ -1,11 +0,0 @@
-import { defineConfig } from 'cypress';
-
-export default defineConfig({
-  e2e: {
-    baseUrl: 'http://localhost:4173/',
-    video: false,
-  },
-  env: {
-    apiUrl: 'http://localhost:8080/',
-  },
-});
\ No newline at end of file
diff --git a/cypress/e2e/homeView.cy.ts b/cypress/e2e/homeView.cy.ts
deleted file mode 100644
index c36a497515644ec32fde9cce49a6e3f78850b3ae..0000000000000000000000000000000000000000
--- a/cypress/e2e/homeView.cy.ts
+++ /dev/null
@@ -1,95 +0,0 @@
-describe('Goals and Challenges Page Load', () => {
-  beforeEach(() => {
-    // Add console log to trace API calls
-    cy.on('window:before:load', (win) => {
-      cy.spy(win.console, 'log');
-    });
-
-    // Mock the API responses that are called on component mount
-    cy.intercept('GET', '/goals', {
-      statusCode: 200,
-      body: {
-        content: [
-          { id: 1, title: 'gaming', saved: 150, target: 1000, completion: 15 },
-        ],
-      },
-    }).as('fetchGoals');
-
-    cy.intercept('GET', '/challenges', {
-      statusCode: 200,
-      body: {
-        content: [
-          { id: 1, title: 'Coffee Challenge', type:'coffee',perPurchase: 20, saved: 60, target: 100, completion: 60 },
-        ],
-      },
-    }).as('fetchChallenges');
-
-    // Visit the component that triggers these requests in `onMounted`
-    cy.visit('/hjem');
-  });
-
-  it('loads and displays goals and challenges after onMounted', () => {
-    // Wait for API calls made during `onMounted` to complete
-    cy.wait(['@fetchGoals', '@fetchChallenges']);
-
-    // Check console logs for any errors or warnings that might indicate issues
-    cy.window().then((win) => {
-      expect(win.console.log).to.be.calledWithMatch(/Goals:/); // Adjust based on actual logging in your Vue app
-    });
-
-    // Assertions to verify the DOM is updated correctly
-    cy.get('[data-cy=goal-title]').should('exist').and('contain', 'gaming');
-    cy.get('[data-cy=challenge-title]').should('exist').and('contain', 'Coffee Challenge');
-  });
-  it('Should increment a challenges progress when the increment button is clicked', () => {
-  cy.wait('@fetchChallenges');
-    // Separate aliases for clarity
-    cy.intercept('PUT', '/challenges/1', {
-      statusCode: 200,
-      body: {
-        id: 1,
-        title: 'Coffee Challenge',
-        type: 'coffee',
-        perPurchase: 20,
-        saved: 80,  // this is the updated amount
-        target: 100,
-        completion: 80,
-      },
-    }).as('incrementChallenge1');
-
-
-    cy.intercept('PUT', '/goals/1', {
-      statusCode: 200,
-      body:  { id: 1, title: 'gaming', saved: 170, target: 1000, completion: 15 },
-    }).as('incrementChallenge');
-
-    // Mock the POST request for renewing the token if it's not implemented in the backend
-    cy.intercept('POST', '/auth/renewToken', {
-      statusCode: 200,
-      body: {
-        accessToken: 'newlyRenewedAccessToken'
-      }
-    }).as('renewToken');
-    cy.get('[data-cy=increment-challenge1]').click();
-    cy.wait('@incrementChallenge1'); // Wait for the specific challenge update intercept
-
-    // Check if the progress bar reflects the right percentage
-    cy.get('[data-cy=challenge-progress]')
-    .invoke('attr', 'style')
-    .should('contain', 'width: 80%');  // Directly check the style attribute for the width
-  });
-  it('Should navigate to the spare challenges page when adding a new challenge', () => {
-    // Mock the routing to the spare challenges page
-    cy.intercept('GET', '/spareutfordringer', {
-      statusCode: 200,
-      body: { content: 'Spare Challenges Page' }
-    }).as('spareChallenges');
-
-    // Trigger the route change
-    cy.get('[data-cy=challenge-icon-1]').click();
-
-    // Assert that navigation has occurred
-    cy.url().should('include', '/spareutfordringer/1');
-  });
-
-});
diff --git a/cypress/e2e/login.cy.ts b/cypress/e2e/login.cy.ts
deleted file mode 100644
index 3dba281cd4821c44dbe43c8600cf71e3c8ca1302..0000000000000000000000000000000000000000
--- a/cypress/e2e/login.cy.ts
+++ /dev/null
@@ -1,50 +0,0 @@
-describe('Login', () => {
-    beforeEach(() => {
-        cy.visit('/logginn')
-    })
-
-    function fullInput() {
-        cy.get('input[name=username]').type('test')
-        cy.get('input[name=password]').type('test')
-    }
-
-    it('visits the login page as default', () => {
-        cy.contains('button', 'Logg inn')
-    })
-
-    it('disables the login button when no input', () => {
-        cy.contains('button', 'Logg inn').should('be.disabled')
-    })
-
-    it('disables the login button when only username is input', () => {
-        cy.get('input[name=username]').type('test')
-        cy.contains('button', 'Logg inn').should('be.disabled')
-    })
-
-    it('disables the login button when only password is input', () => {
-        cy.get('input[name=password]').type('test')
-        cy.contains('button', 'Logg inn').should('be.disabled')
-    })
-
-    it('enables the login button when both username and password is input', () => {
-        fullInput()
-        cy.contains('button', 'Logg inn').should('not.be.disabled')
-    })
-
-    it('pushes the the user to root page on successful login', () => {
-        cy.intercept('POST', 'http://localhost:8080/auth/login', {
-            body: {
-                accessToken: 'fakeToken',
-                refreshToken: 'fakeToken'
-            }
-        }).as('login')
-
-        fullInput()
-
-        cy.get('button[name=submit]').click()
-
-        cy.wait('@login')
-
-        cy.url().should('include', '/')
-    })
-})
diff --git a/cypress/e2e/register.cy.ts b/cypress/e2e/register.cy.ts
deleted file mode 100644
index 508e05569bccb1553a227967aad3bf9e55ee3625..0000000000000000000000000000000000000000
--- a/cypress/e2e/register.cy.ts
+++ /dev/null
@@ -1,45 +0,0 @@
-describe('Register', () => {
-    beforeEach(() => {
-        cy.visit('/registrer')
-        cy.contains('h3', 'Registrer deg').click()
-    })
-
-    function fullInput() {
-        cy.get('input[name="firstname"]').type('firstname')
-        cy.get('input[name="lastname"]').type('lastname')
-        cy.get('input[name="email"]').type('email@test.work')
-        cy.get('input[name="username"]').type('username')
-        cy.get('input[name="password"]').type('Password123!')
-        cy.get('input[name="confirm"]').type('Password123!')
-    }
-
-    it('visits the register page when clicked', () => {
-        cy.contains('button[name="submit"]', 'Registrer deg')
-    })
-
-    it('disables the login button when no input', () => {
-        cy.get('button[name="submit"]').should('be.disabled')
-    })
-
-    it('enable the login button when all inputs are filled and l', () => {
-        fullInput()
-
-        cy.get('button[name="submit"]').should('not.be.disabled')
-    })
-
-    it('pushes the user to the root page on successful register', () => {
-        cy.intercept('POST', 'http://localhost:8080/auth/register', {
-            body: {
-                accessToken: 'fakeToken',
-                refreshToken: 'fakeToken'
-            }
-        }).as('register')
-
-        fullInput()
-
-        cy.get('button[name="submit"]').click()
-
-        cy.wait('@register')
-        cy.url().should('include', '/')
-    })
-})
diff --git a/cypress/e2e/tsconfig.json b/cypress/e2e/tsconfig.json
deleted file mode 100644
index 37748feb7f2d4d4ae6959e38d27ad35d96b7d1d3..0000000000000000000000000000000000000000
--- a/cypress/e2e/tsconfig.json
+++ /dev/null
@@ -1,10 +0,0 @@
-{
-  "extends": "@vue/tsconfig/tsconfig.dom.json",
-  "include": ["./**/*", "../support/**/*"],
-  "compilerOptions": {
-    "isolatedModules": false,
-    "target": "es5",
-    "lib": ["es5", "dom"],
-    "types": ["cypress"]
-  }
-}
diff --git a/cypress/fixtures/example.json b/cypress/fixtures/example.json
deleted file mode 100644
index 02e4254378e9785f013be7cc8d94a8229dcbcbb7..0000000000000000000000000000000000000000
--- a/cypress/fixtures/example.json
+++ /dev/null
@@ -1,5 +0,0 @@
-{
-  "name": "Using fixtures to represent data",
-  "email": "hello@cypress.io",
-  "body": "Fixtures are a great way to mock data for responses to routes"
-}
diff --git a/cypress/support/commands.ts b/cypress/support/commands.ts
deleted file mode 100644
index 9b7bb8e2584cf20c9f578c69dada5f6024b4b042..0000000000000000000000000000000000000000
--- a/cypress/support/commands.ts
+++ /dev/null
@@ -1,39 +0,0 @@
-/// <reference types="cypress" />
-// ***********************************************
-// This example commands.ts shows you how to
-// create various custom commands and overwrite
-// existing commands.
-//
-// For more comprehensive examples of custom
-// commands please read more here:
-// https://on.cypress.io/custom-commands
-// ***********************************************
-//
-//
-// -- This is a parent command --
-// Cypress.Commands.add('login', (email, password) => { ... })
-//
-//
-// -- This is a child command --
-// Cypress.Commands.add('drag', { prevSubject: 'element'}, (subject, options) => { ... })
-//
-//
-// -- This is a dual command --
-// Cypress.Commands.add('dismiss', { prevSubject: 'optional'}, (subject, options) => { ... })
-//
-//
-// -- This will overwrite an existing command --
-// Cypress.Commands.overwrite('visit', (originalFn, url, options) => { ... })
-//
-// declare global {
-//   namespace Cypress {
-//     interface Chainable {
-//       login(email: string, password: string): Chainable<void>
-//       drag(subject: string, options?: Partial<TypeOptions>): Chainable<Element>
-//       dismiss(subject: string, options?: Partial<TypeOptions>): Chainable<Element>
-//       visit(originalFn: CommandOriginalFn, url: string, options: Partial<VisitOptions>): Chainable<Element>
-//     }
-//   }
-// }
-
-export {}
diff --git a/cypress/support/e2e.ts b/cypress/support/e2e.ts
deleted file mode 100644
index d68db96df2697e0835f5c490db0c2cc81673f407..0000000000000000000000000000000000000000
--- a/cypress/support/e2e.ts
+++ /dev/null
@@ -1,20 +0,0 @@
-// ***********************************************************
-// This example support/index.js is processed and
-// loaded automatically before your test files.
-//
-// This is a great place to put global configuration and
-// behavior that modifies Cypress.
-//
-// You can change the location of this file or turn off
-// automatically serving support files with the
-// 'supportFile' configuration option.
-//
-// You can read more here:
-// https://on.cypress.io/configuration
-// ***********************************************************
-
-// Import commands.js using ES2015 syntax:
-import './commands'
-
-// Alternatively you can use CommonJS syntax:
-// require('./commands')
diff --git a/env.d.ts b/env.d.ts
deleted file mode 100644
index 11f02fe2a0061d6e6e1f271b21da95423b448b32..0000000000000000000000000000000000000000
--- a/env.d.ts
+++ /dev/null
@@ -1 +0,0 @@
-/// <reference types="vite/client" />
diff --git a/index.html b/index.html
deleted file mode 100644
index 39387a42927fef2354002b09708ac4f557e65175..0000000000000000000000000000000000000000
--- a/index.html
+++ /dev/null
@@ -1,13 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-  <head>
-    <meta charset="UTF-8">
-    <link rel="icon" href="/favicon.png">
-    <meta name="viewport" content="width=device-width, initial-scale=1.0">
-    <title>SpareSti</title>
-  </head>
-  <body>
-    <div id="app"></div>
-    <script type="module" src="/src/main.ts"></script>
-  </body>
-</html>
diff --git a/package-lock.json b/package-lock.json
deleted file mode 100644
index 962f0ccbb36ff69aa08fc85c6ff4ba24d66f855f..0000000000000000000000000000000000000000
--- a/package-lock.json
+++ /dev/null
@@ -1,7560 +0,0 @@
-{
-  "name": "idatt2106_2024_02_frontend",
-  "version": "0.0.0",
-  "lockfileVersion": 3,
-  "requires": true,
-  "packages": {
-    "": {
-      "name": "idatt2106_2024_02_frontend",
-      "version": "0.0.0",
-      "dependencies": {
-        "animejs": "^3.2.2",
-        "canvas-confetti": "^1.9.2",
-        "pinia": "^2.1.7",
-        "vue": "^3.4.21",
-        "vue-router": "^4.3.1",
-        "vuedraggable": "^4.1.0"
-      },
-      "devDependencies": {
-        "@rushstack/eslint-patch": "^1.8.0",
-        "@tsconfig/node20": "^20.1.4",
-        "@types/animejs": "^3.1.12",
-        "@types/canvas-confetti": "^1.6.4",
-        "@types/jsdom": "^21.1.6",
-        "@types/node": "^20.12.5",
-        "@typescript-eslint/eslint-plugin": "^7.7.0",
-        "@typescript-eslint/parser": "^7.7.0",
-        "@vitejs/plugin-vue": "^5.0.4",
-        "@vitest/coverage-v8": "^1.5.0",
-        "@vue/eslint-config-prettier": "^9.0.0",
-        "@vue/eslint-config-typescript": "^13.0.0",
-        "@vue/test-utils": "^2.4.5",
-        "@vue/tsconfig": "^0.5.1",
-        "autoprefixer": "^10.4.19",
-        "axios-mock-adapter": "^1.22.0",
-        "cypress": "^13.7.3",
-        "eslint": "^8.57.0",
-        "eslint-plugin-cypress": "^2.15.1",
-        "eslint-plugin-vue": "^9.23.0",
-        "jsdom": "^24.0.0",
-        "npm-run-all2": "^6.1.2",
-        "postcss": "^8.4.38",
-        "prettier": "^3.2.5",
-        "start-server-and-test": "^2.0.3",
-        "tailwindcss": "^3.4.3",
-        "typescript": "~5.4.0",
-        "vite": "^5.2.8",
-        "vitest": "^1.4.0",
-        "vue-tsc": "^2.0.11"
-      }
-    },
-    "node_modules/@aashutoshrathi/word-wrap": {
-      "version": "1.2.6",
-      "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz",
-      "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==",
-      "dev": true,
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/@alloc/quick-lru": {
-      "version": "5.2.0",
-      "resolved": "https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.2.0.tgz",
-      "integrity": "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==",
-      "dev": true,
-      "engines": {
-        "node": ">=10"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "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,
-      "dependencies": {
-        "@jridgewell/gen-mapping": "^0.3.5",
-        "@jridgewell/trace-mapping": "^0.3.24"
-      },
-      "engines": {
-        "node": ">=6.0.0"
-      }
-    },
-    "node_modules/@babel/helper-string-parser": {
-      "version": "7.24.1",
-      "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.1.tgz",
-      "integrity": "sha512-2ofRCjnnA9y+wk8b9IAREroeUP02KHp431N2mhKniy2yKIDKpbrHv9eXwm8cBeWQYcJmzv5qKCu65P47eCF7CQ==",
-      "dev": true,
-      "engines": {
-        "node": ">=6.9.0"
-      }
-    },
-    "node_modules/@babel/helper-validator-identifier": {
-      "version": "7.22.20",
-      "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz",
-      "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==",
-      "dev": true,
-      "engines": {
-        "node": ">=6.9.0"
-      }
-    },
-    "node_modules/@babel/parser": {
-      "version": "7.24.4",
-      "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.4.tgz",
-      "integrity": "sha512-zTvEBcghmeBma9QIGunWevvBAp4/Qu9Bdq+2k0Ot4fVMD6v3dsC9WOcRSKk7tRRyBM/53yKMJko9xOatGQAwSg==",
-      "bin": {
-        "parser": "bin/babel-parser.js"
-      },
-      "engines": {
-        "node": ">=6.0.0"
-      }
-    },
-    "node_modules/@babel/types": {
-      "version": "7.24.0",
-      "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.0.tgz",
-      "integrity": "sha512-+j7a5c253RfKh8iABBhywc8NSfP5LURe7Uh4qpsh6jc+aLJguvmIUBdjSdEMQv2bENrCR5MfRdjGo7vzS/ob7w==",
-      "dev": true,
-      "dependencies": {
-        "@babel/helper-string-parser": "^7.23.4",
-        "@babel/helper-validator-identifier": "^7.22.20",
-        "to-fast-properties": "^2.0.0"
-      },
-      "engines": {
-        "node": ">=6.9.0"
-      }
-    },
-    "node_modules/@bcoe/v8-coverage": {
-      "version": "0.2.3",
-      "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz",
-      "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==",
-      "dev": true
-    },
-    "node_modules/@colors/colors": {
-      "version": "1.5.0",
-      "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz",
-      "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==",
-      "dev": true,
-      "optional": true,
-      "engines": {
-        "node": ">=0.1.90"
-      }
-    },
-    "node_modules/@cypress/request": {
-      "version": "3.0.1",
-      "resolved": "https://registry.npmjs.org/@cypress/request/-/request-3.0.1.tgz",
-      "integrity": "sha512-TWivJlJi8ZDx2wGOw1dbLuHJKUYX7bWySw377nlnGOW3hP9/MUKIsEdXT/YngWxVdgNCHRBmFlBipE+5/2ZZlQ==",
-      "dev": true,
-      "dependencies": {
-        "aws-sign2": "~0.7.0",
-        "aws4": "^1.8.0",
-        "caseless": "~0.12.0",
-        "combined-stream": "~1.0.6",
-        "extend": "~3.0.2",
-        "forever-agent": "~0.6.1",
-        "form-data": "~2.3.2",
-        "http-signature": "~1.3.6",
-        "is-typedarray": "~1.0.0",
-        "isstream": "~0.1.2",
-        "json-stringify-safe": "~5.0.1",
-        "mime-types": "~2.1.19",
-        "performance-now": "^2.1.0",
-        "qs": "6.10.4",
-        "safe-buffer": "^5.1.2",
-        "tough-cookie": "^4.1.3",
-        "tunnel-agent": "^0.6.0",
-        "uuid": "^8.3.2"
-      },
-      "engines": {
-        "node": ">= 6"
-      }
-    },
-    "node_modules/@cypress/request/node_modules/form-data": {
-      "version": "2.3.3",
-      "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz",
-      "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==",
-      "dev": true,
-      "dependencies": {
-        "asynckit": "^0.4.0",
-        "combined-stream": "^1.0.6",
-        "mime-types": "^2.1.12"
-      },
-      "engines": {
-        "node": ">= 0.12"
-      }
-    },
-    "node_modules/@cypress/xvfb": {
-      "version": "1.2.4",
-      "resolved": "https://registry.npmjs.org/@cypress/xvfb/-/xvfb-1.2.4.tgz",
-      "integrity": "sha512-skbBzPggOVYCbnGgV+0dmBdW/s77ZkAOXIC1knS8NagwDjBrNC1LuXtQJeiN6l+m7lzmHtaoUw/ctJKdqkG57Q==",
-      "dev": true,
-      "dependencies": {
-        "debug": "^3.1.0",
-        "lodash.once": "^4.1.1"
-      }
-    },
-    "node_modules/@cypress/xvfb/node_modules/debug": {
-      "version": "3.2.7",
-      "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz",
-      "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==",
-      "dev": true,
-      "dependencies": {
-        "ms": "^2.1.1"
-      }
-    },
-    "node_modules/@esbuild/aix-ppc64": {
-      "version": "0.20.2",
-      "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.20.2.tgz",
-      "integrity": "sha512-D+EBOJHXdNZcLJRBkhENNG8Wji2kgc9AZ9KiPr1JuZjsNtyHzrsfLRrY0tk2H2aoFu6RANO1y1iPPUCDYWkb5g==",
-      "cpu": [
-        "ppc64"
-      ],
-      "dev": true,
-      "optional": true,
-      "os": [
-        "aix"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/android-arm": {
-      "version": "0.20.2",
-      "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.20.2.tgz",
-      "integrity": "sha512-t98Ra6pw2VaDhqNWO2Oph2LXbz/EJcnLmKLGBJwEwXX/JAN83Fym1rU8l0JUWK6HkIbWONCSSatf4sf2NBRx/w==",
-      "cpu": [
-        "arm"
-      ],
-      "dev": true,
-      "optional": true,
-      "os": [
-        "android"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/android-arm64": {
-      "version": "0.20.2",
-      "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.20.2.tgz",
-      "integrity": "sha512-mRzjLacRtl/tWU0SvD8lUEwb61yP9cqQo6noDZP/O8VkwafSYwZ4yWy24kan8jE/IMERpYncRt2dw438LP3Xmg==",
-      "cpu": [
-        "arm64"
-      ],
-      "dev": true,
-      "optional": true,
-      "os": [
-        "android"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/android-x64": {
-      "version": "0.20.2",
-      "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.20.2.tgz",
-      "integrity": "sha512-btzExgV+/lMGDDa194CcUQm53ncxzeBrWJcncOBxuC6ndBkKxnHdFJn86mCIgTELsooUmwUm9FkhSp5HYu00Rg==",
-      "cpu": [
-        "x64"
-      ],
-      "dev": true,
-      "optional": true,
-      "os": [
-        "android"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/darwin-arm64": {
-      "version": "0.20.2",
-      "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.20.2.tgz",
-      "integrity": "sha512-4J6IRT+10J3aJH3l1yzEg9y3wkTDgDk7TSDFX+wKFiWjqWp/iCfLIYzGyasx9l0SAFPT1HwSCR+0w/h1ES/MjA==",
-      "cpu": [
-        "arm64"
-      ],
-      "dev": true,
-      "optional": true,
-      "os": [
-        "darwin"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/darwin-x64": {
-      "version": "0.20.2",
-      "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.20.2.tgz",
-      "integrity": "sha512-tBcXp9KNphnNH0dfhv8KYkZhjc+H3XBkF5DKtswJblV7KlT9EI2+jeA8DgBjp908WEuYll6pF+UStUCfEpdysA==",
-      "cpu": [
-        "x64"
-      ],
-      "dev": true,
-      "optional": true,
-      "os": [
-        "darwin"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/freebsd-arm64": {
-      "version": "0.20.2",
-      "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.20.2.tgz",
-      "integrity": "sha512-d3qI41G4SuLiCGCFGUrKsSeTXyWG6yem1KcGZVS+3FYlYhtNoNgYrWcvkOoaqMhwXSMrZRl69ArHsGJ9mYdbbw==",
-      "cpu": [
-        "arm64"
-      ],
-      "dev": true,
-      "optional": true,
-      "os": [
-        "freebsd"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/freebsd-x64": {
-      "version": "0.20.2",
-      "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.20.2.tgz",
-      "integrity": "sha512-d+DipyvHRuqEeM5zDivKV1KuXn9WeRX6vqSqIDgwIfPQtwMP4jaDsQsDncjTDDsExT4lR/91OLjRo8bmC1e+Cw==",
-      "cpu": [
-        "x64"
-      ],
-      "dev": true,
-      "optional": true,
-      "os": [
-        "freebsd"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/linux-arm": {
-      "version": "0.20.2",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.20.2.tgz",
-      "integrity": "sha512-VhLPeR8HTMPccbuWWcEUD1Az68TqaTYyj6nfE4QByZIQEQVWBB8vup8PpR7y1QHL3CpcF6xd5WVBU/+SBEvGTg==",
-      "cpu": [
-        "arm"
-      ],
-      "dev": true,
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/linux-arm64": {
-      "version": "0.20.2",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.20.2.tgz",
-      "integrity": "sha512-9pb6rBjGvTFNira2FLIWqDk/uaf42sSyLE8j1rnUpuzsODBq7FvpwHYZxQ/It/8b+QOS1RYfqgGFNLRI+qlq2A==",
-      "cpu": [
-        "arm64"
-      ],
-      "dev": true,
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/linux-ia32": {
-      "version": "0.20.2",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.20.2.tgz",
-      "integrity": "sha512-o10utieEkNPFDZFQm9CoP7Tvb33UutoJqg3qKf1PWVeeJhJw0Q347PxMvBgVVFgouYLGIhFYG0UGdBumROyiig==",
-      "cpu": [
-        "ia32"
-      ],
-      "dev": true,
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/linux-loong64": {
-      "version": "0.20.2",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.20.2.tgz",
-      "integrity": "sha512-PR7sp6R/UC4CFVomVINKJ80pMFlfDfMQMYynX7t1tNTeivQ6XdX5r2XovMmha/VjR1YN/HgHWsVcTRIMkymrgQ==",
-      "cpu": [
-        "loong64"
-      ],
-      "dev": true,
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/linux-mips64el": {
-      "version": "0.20.2",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.20.2.tgz",
-      "integrity": "sha512-4BlTqeutE/KnOiTG5Y6Sb/Hw6hsBOZapOVF6njAESHInhlQAghVVZL1ZpIctBOoTFbQyGW+LsVYZ8lSSB3wkjA==",
-      "cpu": [
-        "mips64el"
-      ],
-      "dev": true,
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/linux-ppc64": {
-      "version": "0.20.2",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.20.2.tgz",
-      "integrity": "sha512-rD3KsaDprDcfajSKdn25ooz5J5/fWBylaaXkuotBDGnMnDP1Uv5DLAN/45qfnf3JDYyJv/ytGHQaziHUdyzaAg==",
-      "cpu": [
-        "ppc64"
-      ],
-      "dev": true,
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/linux-riscv64": {
-      "version": "0.20.2",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.20.2.tgz",
-      "integrity": "sha512-snwmBKacKmwTMmhLlz/3aH1Q9T8v45bKYGE3j26TsaOVtjIag4wLfWSiZykXzXuE1kbCE+zJRmwp+ZbIHinnVg==",
-      "cpu": [
-        "riscv64"
-      ],
-      "dev": true,
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/linux-s390x": {
-      "version": "0.20.2",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.20.2.tgz",
-      "integrity": "sha512-wcWISOobRWNm3cezm5HOZcYz1sKoHLd8VL1dl309DiixxVFoFe/o8HnwuIwn6sXre88Nwj+VwZUvJf4AFxkyrQ==",
-      "cpu": [
-        "s390x"
-      ],
-      "dev": true,
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/linux-x64": {
-      "version": "0.20.2",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.20.2.tgz",
-      "integrity": "sha512-1MdwI6OOTsfQfek8sLwgyjOXAu+wKhLEoaOLTjbijk6E2WONYpH9ZU2mNtR+lZ2B4uwr+usqGuVfFT9tMtGvGw==",
-      "cpu": [
-        "x64"
-      ],
-      "dev": true,
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/netbsd-x64": {
-      "version": "0.20.2",
-      "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.20.2.tgz",
-      "integrity": "sha512-K8/DhBxcVQkzYc43yJXDSyjlFeHQJBiowJ0uVL6Tor3jGQfSGHNNJcWxNbOI8v5k82prYqzPuwkzHt3J1T1iZQ==",
-      "cpu": [
-        "x64"
-      ],
-      "dev": true,
-      "optional": true,
-      "os": [
-        "netbsd"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/openbsd-x64": {
-      "version": "0.20.2",
-      "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.20.2.tgz",
-      "integrity": "sha512-eMpKlV0SThJmmJgiVyN9jTPJ2VBPquf6Kt/nAoo6DgHAoN57K15ZghiHaMvqjCye/uU4X5u3YSMgVBI1h3vKrQ==",
-      "cpu": [
-        "x64"
-      ],
-      "dev": true,
-      "optional": true,
-      "os": [
-        "openbsd"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/sunos-x64": {
-      "version": "0.20.2",
-      "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.20.2.tgz",
-      "integrity": "sha512-2UyFtRC6cXLyejf/YEld4Hajo7UHILetzE1vsRcGL3earZEW77JxrFjH4Ez2qaTiEfMgAXxfAZCm1fvM/G/o8w==",
-      "cpu": [
-        "x64"
-      ],
-      "dev": true,
-      "optional": true,
-      "os": [
-        "sunos"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/win32-arm64": {
-      "version": "0.20.2",
-      "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.20.2.tgz",
-      "integrity": "sha512-GRibxoawM9ZCnDxnP3usoUDO9vUkpAxIIZ6GQI+IlVmr5kP3zUq+l17xELTHMWTWzjxa2guPNyrpq1GWmPvcGQ==",
-      "cpu": [
-        "arm64"
-      ],
-      "dev": true,
-      "optional": true,
-      "os": [
-        "win32"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/win32-ia32": {
-      "version": "0.20.2",
-      "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.20.2.tgz",
-      "integrity": "sha512-HfLOfn9YWmkSKRQqovpnITazdtquEW8/SoHW7pWpuEeguaZI4QnCRW6b+oZTztdBnZOS2hqJ6im/D5cPzBTTlQ==",
-      "cpu": [
-        "ia32"
-      ],
-      "dev": true,
-      "optional": true,
-      "os": [
-        "win32"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/win32-x64": {
-      "version": "0.20.2",
-      "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.20.2.tgz",
-      "integrity": "sha512-N49X4lJX27+l9jbLKSqZ6bKNjzQvHaT8IIFUy+YIqmXQdjYCToGWwOItDrfby14c78aDd5NHQl29xingXfCdLQ==",
-      "cpu": [
-        "x64"
-      ],
-      "dev": true,
-      "optional": true,
-      "os": [
-        "win32"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@eslint-community/eslint-utils": {
-      "version": "4.4.0",
-      "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz",
-      "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==",
-      "dev": true,
-      "dependencies": {
-        "eslint-visitor-keys": "^3.3.0"
-      },
-      "engines": {
-        "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
-      },
-      "peerDependencies": {
-        "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0"
-      }
-    },
-    "node_modules/@eslint-community/regexpp": {
-      "version": "4.10.0",
-      "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.10.0.tgz",
-      "integrity": "sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==",
-      "dev": true,
-      "engines": {
-        "node": "^12.0.0 || ^14.0.0 || >=16.0.0"
-      }
-    },
-    "node_modules/@eslint/eslintrc": {
-      "version": "2.1.4",
-      "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz",
-      "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==",
-      "dev": true,
-      "dependencies": {
-        "ajv": "^6.12.4",
-        "debug": "^4.3.2",
-        "espree": "^9.6.0",
-        "globals": "^13.19.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": "^12.22.0 || ^14.17.0 || >=16.0.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,
-      "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,
-      "dependencies": {
-        "brace-expansion": "^1.1.7"
-      },
-      "engines": {
-        "node": "*"
-      }
-    },
-    "node_modules/@eslint/js": {
-      "version": "8.57.0",
-      "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.0.tgz",
-      "integrity": "sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==",
-      "dev": true,
-      "engines": {
-        "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
-      }
-    },
-    "node_modules/@hapi/hoek": {
-      "version": "9.3.0",
-      "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.3.0.tgz",
-      "integrity": "sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ==",
-      "dev": true
-    },
-    "node_modules/@hapi/topo": {
-      "version": "5.1.0",
-      "resolved": "https://registry.npmjs.org/@hapi/topo/-/topo-5.1.0.tgz",
-      "integrity": "sha512-foQZKJig7Ob0BMAYBfcJk8d77QtOe7Wo4ox7ff1lQYoNNAb6jwcY1ncdoy2e9wQZzvNy7ODZCYJkK8kzmcAnAg==",
-      "dev": true,
-      "dependencies": {
-        "@hapi/hoek": "^9.0.0"
-      }
-    },
-    "node_modules/@humanwhocodes/config-array": {
-      "version": "0.11.14",
-      "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz",
-      "integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==",
-      "dev": true,
-      "dependencies": {
-        "@humanwhocodes/object-schema": "^2.0.2",
-        "debug": "^4.3.1",
-        "minimatch": "^3.0.5"
-      },
-      "engines": {
-        "node": ">=10.10.0"
-      }
-    },
-    "node_modules/@humanwhocodes/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,
-      "dependencies": {
-        "balanced-match": "^1.0.0",
-        "concat-map": "0.0.1"
-      }
-    },
-    "node_modules/@humanwhocodes/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,
-      "dependencies": {
-        "brace-expansion": "^1.1.7"
-      },
-      "engines": {
-        "node": "*"
-      }
-    },
-    "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,
-      "engines": {
-        "node": ">=12.22"
-      },
-      "funding": {
-        "type": "github",
-        "url": "https://github.com/sponsors/nzakas"
-      }
-    },
-    "node_modules/@humanwhocodes/object-schema": {
-      "version": "2.0.3",
-      "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz",
-      "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==",
-      "dev": true
-    },
-    "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,
-      "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/@isaacs/cliui/node_modules/ansi-regex": {
-      "version": "6.0.1",
-      "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz",
-      "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==",
-      "dev": true,
-      "engines": {
-        "node": ">=12"
-      },
-      "funding": {
-        "url": "https://github.com/chalk/ansi-regex?sponsor=1"
-      }
-    },
-    "node_modules/@isaacs/cliui/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
-    },
-    "node_modules/@isaacs/cliui/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,
-      "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/@isaacs/cliui/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,
-      "dependencies": {
-        "ansi-regex": "^6.0.1"
-      },
-      "engines": {
-        "node": ">=12"
-      },
-      "funding": {
-        "url": "https://github.com/chalk/strip-ansi?sponsor=1"
-      }
-    },
-    "node_modules/@istanbuljs/schema": {
-      "version": "0.1.3",
-      "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz",
-      "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==",
-      "dev": true,
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/@jest/schemas": {
-      "version": "29.6.3",
-      "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz",
-      "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==",
-      "dev": true,
-      "dependencies": {
-        "@sinclair/typebox": "^0.27.8"
-      },
-      "engines": {
-        "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
-      }
-    },
-    "node_modules/@jridgewell/gen-mapping": {
-      "version": "0.3.5",
-      "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz",
-      "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==",
-      "dev": true,
-      "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==",
-      "dev": true,
-      "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==",
-      "dev": true,
-      "engines": {
-        "node": ">=6.0.0"
-      }
-    },
-    "node_modules/@jridgewell/sourcemap-codec": {
-      "version": "1.4.15",
-      "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz",
-      "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg=="
-    },
-    "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==",
-      "dev": true,
-      "dependencies": {
-        "@jridgewell/resolve-uri": "^3.1.0",
-        "@jridgewell/sourcemap-codec": "^1.4.14"
-      }
-    },
-    "node_modules/@nodelib/fs.scandir": {
-      "version": "2.1.5",
-      "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
-      "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==",
-      "dev": true,
-      "dependencies": {
-        "@nodelib/fs.stat": "2.0.5",
-        "run-parallel": "^1.1.9"
-      },
-      "engines": {
-        "node": ">= 8"
-      }
-    },
-    "node_modules/@nodelib/fs.stat": {
-      "version": "2.0.5",
-      "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz",
-      "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==",
-      "dev": true,
-      "engines": {
-        "node": ">= 8"
-      }
-    },
-    "node_modules/@nodelib/fs.walk": {
-      "version": "1.2.8",
-      "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz",
-      "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==",
-      "dev": true,
-      "dependencies": {
-        "@nodelib/fs.scandir": "2.1.5",
-        "fastq": "^1.6.0"
-      },
-      "engines": {
-        "node": ">= 8"
-      }
-    },
-    "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
-    },
-    "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,
-      "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,
-      "engines": {
-        "node": "^12.20.0 || ^14.18.0 || >=16.0.0"
-      },
-      "funding": {
-        "url": "https://opencollective.com/unts"
-      }
-    },
-    "node_modules/@rollup/rollup-android-arm-eabi": {
-      "version": "4.16.4",
-      "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.16.4.tgz",
-      "integrity": "sha512-GkhjAaQ8oUTOKE4g4gsZ0u8K/IHU1+2WQSgS1TwTcYvL+sjbaQjNHFXbOJ6kgqGHIO1DfUhI/Sphi9GkRT9K+Q==",
-      "cpu": [
-        "arm"
-      ],
-      "dev": true,
-      "optional": true,
-      "os": [
-        "android"
-      ]
-    },
-    "node_modules/@rollup/rollup-android-arm64": {
-      "version": "4.16.4",
-      "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.16.4.tgz",
-      "integrity": "sha512-Bvm6D+NPbGMQOcxvS1zUl8H7DWlywSXsphAeOnVeiZLQ+0J6Is8T7SrjGTH29KtYkiY9vld8ZnpV3G2EPbom+w==",
-      "cpu": [
-        "arm64"
-      ],
-      "dev": true,
-      "optional": true,
-      "os": [
-        "android"
-      ]
-    },
-    "node_modules/@rollup/rollup-darwin-arm64": {
-      "version": "4.16.4",
-      "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.16.4.tgz",
-      "integrity": "sha512-i5d64MlnYBO9EkCOGe5vPR/EeDwjnKOGGdd7zKFhU5y8haKhQZTN2DgVtpODDMxUr4t2K90wTUJg7ilgND6bXw==",
-      "cpu": [
-        "arm64"
-      ],
-      "dev": true,
-      "optional": true,
-      "os": [
-        "darwin"
-      ]
-    },
-    "node_modules/@rollup/rollup-darwin-x64": {
-      "version": "4.16.4",
-      "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.16.4.tgz",
-      "integrity": "sha512-WZupV1+CdUYehaZqjaFTClJI72fjJEgTXdf4NbW69I9XyvdmztUExBtcI2yIIU6hJtYvtwS6pkTkHJz+k08mAQ==",
-      "cpu": [
-        "x64"
-      ],
-      "dev": true,
-      "optional": true,
-      "os": [
-        "darwin"
-      ]
-    },
-    "node_modules/@rollup/rollup-linux-arm-gnueabihf": {
-      "version": "4.16.4",
-      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.16.4.tgz",
-      "integrity": "sha512-ADm/xt86JUnmAfA9mBqFcRp//RVRt1ohGOYF6yL+IFCYqOBNwy5lbEK05xTsEoJq+/tJzg8ICUtS82WinJRuIw==",
-      "cpu": [
-        "arm"
-      ],
-      "dev": true,
-      "optional": true,
-      "os": [
-        "linux"
-      ]
-    },
-    "node_modules/@rollup/rollup-linux-arm-musleabihf": {
-      "version": "4.16.4",
-      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.16.4.tgz",
-      "integrity": "sha512-tJfJaXPiFAG+Jn3cutp7mCs1ePltuAgRqdDZrzb1aeE3TktWWJ+g7xK9SNlaSUFw6IU4QgOxAY4rA+wZUT5Wfg==",
-      "cpu": [
-        "arm"
-      ],
-      "dev": true,
-      "optional": true,
-      "os": [
-        "linux"
-      ]
-    },
-    "node_modules/@rollup/rollup-linux-arm64-gnu": {
-      "version": "4.16.4",
-      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.16.4.tgz",
-      "integrity": "sha512-7dy1BzQkgYlUTapDTvK997cgi0Orh5Iu7JlZVBy1MBURk7/HSbHkzRnXZa19ozy+wwD8/SlpJnOOckuNZtJR9w==",
-      "cpu": [
-        "arm64"
-      ],
-      "dev": true,
-      "optional": true,
-      "os": [
-        "linux"
-      ]
-    },
-    "node_modules/@rollup/rollup-linux-arm64-musl": {
-      "version": "4.16.4",
-      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.16.4.tgz",
-      "integrity": "sha512-zsFwdUw5XLD1gQe0aoU2HVceI6NEW7q7m05wA46eUAyrkeNYExObfRFQcvA6zw8lfRc5BHtan3tBpo+kqEOxmg==",
-      "cpu": [
-        "arm64"
-      ],
-      "dev": true,
-      "optional": true,
-      "os": [
-        "linux"
-      ]
-    },
-    "node_modules/@rollup/rollup-linux-powerpc64le-gnu": {
-      "version": "4.16.4",
-      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.16.4.tgz",
-      "integrity": "sha512-p8C3NnxXooRdNrdv6dBmRTddEapfESEUflpICDNKXpHvTjRRq1J82CbU5G3XfebIZyI3B0s074JHMWD36qOW6w==",
-      "cpu": [
-        "ppc64"
-      ],
-      "dev": true,
-      "optional": true,
-      "os": [
-        "linux"
-      ]
-    },
-    "node_modules/@rollup/rollup-linux-riscv64-gnu": {
-      "version": "4.16.4",
-      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.16.4.tgz",
-      "integrity": "sha512-Lh/8ckoar4s4Id2foY7jNgitTOUQczwMWNYi+Mjt0eQ9LKhr6sK477REqQkmy8YHY3Ca3A2JJVdXnfb3Rrwkng==",
-      "cpu": [
-        "riscv64"
-      ],
-      "dev": true,
-      "optional": true,
-      "os": [
-        "linux"
-      ]
-    },
-    "node_modules/@rollup/rollup-linux-s390x-gnu": {
-      "version": "4.16.4",
-      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.16.4.tgz",
-      "integrity": "sha512-1xwwn9ZCQYuqGmulGsTZoKrrn0z2fAur2ujE60QgyDpHmBbXbxLaQiEvzJWDrscRq43c8DnuHx3QorhMTZgisQ==",
-      "cpu": [
-        "s390x"
-      ],
-      "dev": true,
-      "optional": true,
-      "os": [
-        "linux"
-      ]
-    },
-    "node_modules/@rollup/rollup-linux-x64-gnu": {
-      "version": "4.16.4",
-      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.16.4.tgz",
-      "integrity": "sha512-LuOGGKAJ7dfRtxVnO1i3qWc6N9sh0Em/8aZ3CezixSTM+E9Oq3OvTsvC4sm6wWjzpsIlOCnZjdluINKESflJLA==",
-      "cpu": [
-        "x64"
-      ],
-      "dev": true,
-      "optional": true,
-      "os": [
-        "linux"
-      ]
-    },
-    "node_modules/@rollup/rollup-linux-x64-musl": {
-      "version": "4.16.4",
-      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.16.4.tgz",
-      "integrity": "sha512-ch86i7KkJKkLybDP2AtySFTRi5fM3KXp0PnHocHuJMdZwu7BuyIKi35BE9guMlmTpwwBTB3ljHj9IQXnTCD0vA==",
-      "cpu": [
-        "x64"
-      ],
-      "dev": true,
-      "optional": true,
-      "os": [
-        "linux"
-      ]
-    },
-    "node_modules/@rollup/rollup-win32-arm64-msvc": {
-      "version": "4.16.4",
-      "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.16.4.tgz",
-      "integrity": "sha512-Ma4PwyLfOWZWayfEsNQzTDBVW8PZ6TUUN1uFTBQbF2Chv/+sjenE86lpiEwj2FiviSmSZ4Ap4MaAfl1ciF4aSA==",
-      "cpu": [
-        "arm64"
-      ],
-      "dev": true,
-      "optional": true,
-      "os": [
-        "win32"
-      ]
-    },
-    "node_modules/@rollup/rollup-win32-ia32-msvc": {
-      "version": "4.16.4",
-      "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.16.4.tgz",
-      "integrity": "sha512-9m/ZDrQsdo/c06uOlP3W9G2ENRVzgzbSXmXHT4hwVaDQhYcRpi9bgBT0FTG9OhESxwK0WjQxYOSfv40cU+T69w==",
-      "cpu": [
-        "ia32"
-      ],
-      "dev": true,
-      "optional": true,
-      "os": [
-        "win32"
-      ]
-    },
-    "node_modules/@rollup/rollup-win32-x64-msvc": {
-      "version": "4.16.4",
-      "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.16.4.tgz",
-      "integrity": "sha512-YunpoOAyGLDseanENHmbFvQSfVL5BxW3k7hhy0eN4rb3gS/ct75dVD0EXOWIqFT/nE8XYW6LP6vz6ctKRi0k9A==",
-      "cpu": [
-        "x64"
-      ],
-      "dev": true,
-      "optional": true,
-      "os": [
-        "win32"
-      ]
-    },
-    "node_modules/@rushstack/eslint-patch": {
-      "version": "1.10.2",
-      "resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.10.2.tgz",
-      "integrity": "sha512-hw437iINopmQuxWPSUEvqE56NCPsiU8N4AYtfHmJFckclktzK9YQJieD3XkDCDH4OjL+C7zgPUh73R/nrcHrqw==",
-      "dev": true
-    },
-    "node_modules/@sideway/address": {
-      "version": "4.1.5",
-      "resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.5.tgz",
-      "integrity": "sha512-IqO/DUQHUkPeixNQ8n0JA6102hT9CmaljNTPmQ1u8MEhBo/R4Q8eKLN/vGZxuebwOroDB4cbpjheD4+/sKFK4Q==",
-      "dev": true,
-      "dependencies": {
-        "@hapi/hoek": "^9.0.0"
-      }
-    },
-    "node_modules/@sideway/formula": {
-      "version": "3.0.1",
-      "resolved": "https://registry.npmjs.org/@sideway/formula/-/formula-3.0.1.tgz",
-      "integrity": "sha512-/poHZJJVjx3L+zVD6g9KgHfYnb443oi7wLu/XKojDviHy6HOEOA6z1Trk5aR1dGcmPenJEgb2sK2I80LeS3MIg==",
-      "dev": true
-    },
-    "node_modules/@sideway/pinpoint": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/@sideway/pinpoint/-/pinpoint-2.0.0.tgz",
-      "integrity": "sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ==",
-      "dev": true
-    },
-    "node_modules/@sinclair/typebox": {
-      "version": "0.27.8",
-      "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz",
-      "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==",
-      "dev": true
-    },
-    "node_modules/@tsconfig/node20": {
-      "version": "20.1.4",
-      "resolved": "https://registry.npmjs.org/@tsconfig/node20/-/node20-20.1.4.tgz",
-      "integrity": "sha512-sqgsT69YFeLWf5NtJ4Xq/xAF8p4ZQHlmGW74Nu2tD4+g5fAsposc4ZfaaPixVu4y01BEiDCWLRDCvDM5JOsRxg==",
-      "dev": true
-    },
-    "node_modules/@types/animejs": {
-      "version": "3.1.12",
-      "resolved": "https://registry.npmjs.org/@types/animejs/-/animejs-3.1.12.tgz",
-      "integrity": "sha512-fpdH+ZtlO0kqjTOqRaBdsEmvpRNOayI8k4EVkEtitL5l6wducDOXk0rgQgfZqWf/ZX9DzXrHf257S5i9xTcISQ==",
-      "dev": true
-    },
-    "node_modules/@types/canvas-confetti": {
-      "version": "1.6.4",
-      "resolved": "https://registry.npmjs.org/@types/canvas-confetti/-/canvas-confetti-1.6.4.tgz",
-      "integrity": "sha512-fNyZ/Fdw/Y92X0vv7B+BD6ysHL4xVU5dJcgzgxLdGbn8O3PezZNIJpml44lKM0nsGur+o/6+NZbZeNTt00U1uA==",
-      "dev": true
-    },
-    "node_modules/@types/estree": {
-      "version": "1.0.5",
-      "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz",
-      "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==",
-      "dev": true
-    },
-    "node_modules/@types/jsdom": {
-      "version": "21.1.6",
-      "resolved": "https://registry.npmjs.org/@types/jsdom/-/jsdom-21.1.6.tgz",
-      "integrity": "sha512-/7kkMsC+/kMs7gAYmmBR9P0vGTnOoLhQhyhQJSlXGI5bzTHp6xdo0TtKWQAsz6pmSAeVqKSbqeyP6hytqr9FDw==",
-      "dev": true,
-      "dependencies": {
-        "@types/node": "*",
-        "@types/tough-cookie": "*",
-        "parse5": "^7.0.0"
-      }
-    },
-    "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==",
-      "dev": true
-    },
-    "node_modules/@types/node": {
-      "version": "20.12.7",
-      "resolved": "https://registry.npmjs.org/@types/node/-/node-20.12.7.tgz",
-      "integrity": "sha512-wq0cICSkRLVaf3UGLMGItu/PtdY7oaXaI/RVU+xliKVOtRna3PRY57ZDfztpDL0n11vfymMUnXv8QwYCO7L1wg==",
-      "dev": true,
-      "dependencies": {
-        "undici-types": "~5.26.4"
-      }
-    },
-    "node_modules/@types/semver": {
-      "version": "7.5.8",
-      "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.8.tgz",
-      "integrity": "sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==",
-      "dev": true
-    },
-    "node_modules/@types/sinonjs__fake-timers": {
-      "version": "8.1.1",
-      "resolved": "https://registry.npmjs.org/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-8.1.1.tgz",
-      "integrity": "sha512-0kSuKjAS0TrGLJ0M/+8MaFkGsQhZpB6pxOmvS3K8FYI72K//YmdfoW9X2qPsAKh1mkwxGD5zib9s1FIFed6E8g==",
-      "dev": true
-    },
-    "node_modules/@types/sizzle": {
-      "version": "2.3.8",
-      "resolved": "https://registry.npmjs.org/@types/sizzle/-/sizzle-2.3.8.tgz",
-      "integrity": "sha512-0vWLNK2D5MT9dg0iOo8GlKguPAU02QjmZitPEsXRuJXU/OGIOt9vT9Fc26wtYuavLxtO45v9PGleoL9Z0k1LHg==",
-      "dev": true
-    },
-    "node_modules/@types/tough-cookie": {
-      "version": "4.0.5",
-      "resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-4.0.5.tgz",
-      "integrity": "sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA==",
-      "dev": true
-    },
-    "node_modules/@types/yauzl": {
-      "version": "2.10.3",
-      "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.3.tgz",
-      "integrity": "sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==",
-      "dev": true,
-      "optional": true,
-      "dependencies": {
-        "@types/node": "*"
-      }
-    },
-    "node_modules/@typescript-eslint/eslint-plugin": {
-      "version": "7.7.1",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.7.1.tgz",
-      "integrity": "sha512-KwfdWXJBOviaBVhxO3p5TJiLpNuh2iyXyjmWN0f1nU87pwyvfS0EmjC6ukQVYVFJd/K1+0NWGPDXiyEyQorn0Q==",
-      "dev": true,
-      "dependencies": {
-        "@eslint-community/regexpp": "^4.10.0",
-        "@typescript-eslint/scope-manager": "7.7.1",
-        "@typescript-eslint/type-utils": "7.7.1",
-        "@typescript-eslint/utils": "7.7.1",
-        "@typescript-eslint/visitor-keys": "7.7.1",
-        "debug": "^4.3.4",
-        "graphemer": "^1.4.0",
-        "ignore": "^5.3.1",
-        "natural-compare": "^1.4.0",
-        "semver": "^7.6.0",
-        "ts-api-utils": "^1.3.0"
-      },
-      "engines": {
-        "node": "^18.18.0 || >=20.0.0"
-      },
-      "funding": {
-        "type": "opencollective",
-        "url": "https://opencollective.com/typescript-eslint"
-      },
-      "peerDependencies": {
-        "@typescript-eslint/parser": "^7.0.0",
-        "eslint": "^8.56.0"
-      },
-      "peerDependenciesMeta": {
-        "typescript": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@typescript-eslint/parser": {
-      "version": "7.7.1",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.7.1.tgz",
-      "integrity": "sha512-vmPzBOOtz48F6JAGVS/kZYk4EkXao6iGrD838sp1w3NQQC0W8ry/q641KU4PrG7AKNAf56NOcR8GOpH8l9FPCw==",
-      "dev": true,
-      "dependencies": {
-        "@typescript-eslint/scope-manager": "7.7.1",
-        "@typescript-eslint/types": "7.7.1",
-        "@typescript-eslint/typescript-estree": "7.7.1",
-        "@typescript-eslint/visitor-keys": "7.7.1",
-        "debug": "^4.3.4"
-      },
-      "engines": {
-        "node": "^18.18.0 || >=20.0.0"
-      },
-      "funding": {
-        "type": "opencollective",
-        "url": "https://opencollective.com/typescript-eslint"
-      },
-      "peerDependencies": {
-        "eslint": "^8.56.0"
-      },
-      "peerDependenciesMeta": {
-        "typescript": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@typescript-eslint/scope-manager": {
-      "version": "7.7.1",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.7.1.tgz",
-      "integrity": "sha512-PytBif2SF+9SpEUKynYn5g1RHFddJUcyynGpztX3l/ik7KmZEv19WCMhUBkHXPU9es/VWGD3/zg3wg90+Dh2rA==",
-      "dev": true,
-      "dependencies": {
-        "@typescript-eslint/types": "7.7.1",
-        "@typescript-eslint/visitor-keys": "7.7.1"
-      },
-      "engines": {
-        "node": "^18.18.0 || >=20.0.0"
-      },
-      "funding": {
-        "type": "opencollective",
-        "url": "https://opencollective.com/typescript-eslint"
-      }
-    },
-    "node_modules/@typescript-eslint/type-utils": {
-      "version": "7.7.1",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.7.1.tgz",
-      "integrity": "sha512-ZksJLW3WF7o75zaBPScdW1Gbkwhd/lyeXGf1kQCxJaOeITscoSl0MjynVvCzuV5boUz/3fOI06Lz8La55mu29Q==",
-      "dev": true,
-      "dependencies": {
-        "@typescript-eslint/typescript-estree": "7.7.1",
-        "@typescript-eslint/utils": "7.7.1",
-        "debug": "^4.3.4",
-        "ts-api-utils": "^1.3.0"
-      },
-      "engines": {
-        "node": "^18.18.0 || >=20.0.0"
-      },
-      "funding": {
-        "type": "opencollective",
-        "url": "https://opencollective.com/typescript-eslint"
-      },
-      "peerDependencies": {
-        "eslint": "^8.56.0"
-      },
-      "peerDependenciesMeta": {
-        "typescript": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@typescript-eslint/types": {
-      "version": "7.7.1",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.7.1.tgz",
-      "integrity": "sha512-AmPmnGW1ZLTpWa+/2omPrPfR7BcbUU4oha5VIbSbS1a1Tv966bklvLNXxp3mrbc+P2j4MNOTfDffNsk4o0c6/w==",
-      "dev": true,
-      "engines": {
-        "node": "^18.18.0 || >=20.0.0"
-      },
-      "funding": {
-        "type": "opencollective",
-        "url": "https://opencollective.com/typescript-eslint"
-      }
-    },
-    "node_modules/@typescript-eslint/typescript-estree": {
-      "version": "7.7.1",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.7.1.tgz",
-      "integrity": "sha512-CXe0JHCXru8Fa36dteXqmH2YxngKJjkQLjxzoj6LYwzZ7qZvgsLSc+eqItCrqIop8Vl2UKoAi0StVWu97FQZIQ==",
-      "dev": true,
-      "dependencies": {
-        "@typescript-eslint/types": "7.7.1",
-        "@typescript-eslint/visitor-keys": "7.7.1",
-        "debug": "^4.3.4",
-        "globby": "^11.1.0",
-        "is-glob": "^4.0.3",
-        "minimatch": "^9.0.4",
-        "semver": "^7.6.0",
-        "ts-api-utils": "^1.3.0"
-      },
-      "engines": {
-        "node": "^18.18.0 || >=20.0.0"
-      },
-      "funding": {
-        "type": "opencollective",
-        "url": "https://opencollective.com/typescript-eslint"
-      },
-      "peerDependenciesMeta": {
-        "typescript": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@typescript-eslint/utils": {
-      "version": "7.7.1",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.7.1.tgz",
-      "integrity": "sha512-QUvBxPEaBXf41ZBbaidKICgVL8Hin0p6prQDu6bbetWo39BKbWJxRsErOzMNT1rXvTll+J7ChrbmMCXM9rsvOQ==",
-      "dev": true,
-      "dependencies": {
-        "@eslint-community/eslint-utils": "^4.4.0",
-        "@types/json-schema": "^7.0.15",
-        "@types/semver": "^7.5.8",
-        "@typescript-eslint/scope-manager": "7.7.1",
-        "@typescript-eslint/types": "7.7.1",
-        "@typescript-eslint/typescript-estree": "7.7.1",
-        "semver": "^7.6.0"
-      },
-      "engines": {
-        "node": "^18.18.0 || >=20.0.0"
-      },
-      "funding": {
-        "type": "opencollective",
-        "url": "https://opencollective.com/typescript-eslint"
-      },
-      "peerDependencies": {
-        "eslint": "^8.56.0"
-      }
-    },
-    "node_modules/@typescript-eslint/visitor-keys": {
-      "version": "7.7.1",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.7.1.tgz",
-      "integrity": "sha512-gBL3Eq25uADw1LQ9kVpf3hRM+DWzs0uZknHYK3hq4jcTPqVCClHGDnB6UUUV2SFeBeA4KWHWbbLqmbGcZ4FYbw==",
-      "dev": true,
-      "dependencies": {
-        "@typescript-eslint/types": "7.7.1",
-        "eslint-visitor-keys": "^3.4.3"
-      },
-      "engines": {
-        "node": "^18.18.0 || >=20.0.0"
-      },
-      "funding": {
-        "type": "opencollective",
-        "url": "https://opencollective.com/typescript-eslint"
-      }
-    },
-    "node_modules/@ungap/structured-clone": {
-      "version": "1.2.0",
-      "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz",
-      "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==",
-      "dev": true
-    },
-    "node_modules/@vitejs/plugin-vue": {
-      "version": "5.0.4",
-      "resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-5.0.4.tgz",
-      "integrity": "sha512-WS3hevEszI6CEVEx28F8RjTX97k3KsrcY6kvTg7+Whm5y3oYvcqzVeGCU3hxSAn4uY2CLCkeokkGKpoctccilQ==",
-      "dev": true,
-      "engines": {
-        "node": "^18.0.0 || >=20.0.0"
-      },
-      "peerDependencies": {
-        "vite": "^5.0.0",
-        "vue": "^3.2.25"
-      }
-    },
-    "node_modules/@vitest/coverage-v8": {
-      "version": "1.5.1",
-      "resolved": "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-1.5.1.tgz",
-      "integrity": "sha512-Zx+dYEDcZg+44ksjIWvWosIGlPLJB1PPpN3O8+Xrh/1qa7WSFA6Y8H7lsZJTYrxu4G2unk9tvP5TgjIGDliF1w==",
-      "dev": true,
-      "dependencies": {
-        "@ampproject/remapping": "^2.2.1",
-        "@bcoe/v8-coverage": "^0.2.3",
-        "debug": "^4.3.4",
-        "istanbul-lib-coverage": "^3.2.2",
-        "istanbul-lib-report": "^3.0.1",
-        "istanbul-lib-source-maps": "^5.0.4",
-        "istanbul-reports": "^3.1.6",
-        "magic-string": "^0.30.5",
-        "magicast": "^0.3.3",
-        "picocolors": "^1.0.0",
-        "std-env": "^3.5.0",
-        "strip-literal": "^2.0.0",
-        "test-exclude": "^6.0.0"
-      },
-      "funding": {
-        "url": "https://opencollective.com/vitest"
-      },
-      "peerDependencies": {
-        "vitest": "1.5.1"
-      }
-    },
-    "node_modules/@vitest/expect": {
-      "version": "1.5.1",
-      "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-1.5.1.tgz",
-      "integrity": "sha512-w3Bn+VUMqku+oWmxvPhTE86uMTbfmBl35aGaIPlwVW7Q89ZREC/icfo2HBsEZ3AAW6YR9lObfZKPEzstw9tJOQ==",
-      "dev": true,
-      "dependencies": {
-        "@vitest/spy": "1.5.1",
-        "@vitest/utils": "1.5.1",
-        "chai": "^4.3.10"
-      },
-      "funding": {
-        "url": "https://opencollective.com/vitest"
-      }
-    },
-    "node_modules/@vitest/runner": {
-      "version": "1.5.1",
-      "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-1.5.1.tgz",
-      "integrity": "sha512-mt372zsz0vFR7L1xF/ert4t+teD66oSuXoTyaZbl0eJgilvyzCKP1tJ21gVa8cDklkBOM3DLnkE1ljj/BskyEw==",
-      "dev": true,
-      "dependencies": {
-        "@vitest/utils": "1.5.1",
-        "p-limit": "^5.0.0",
-        "pathe": "^1.1.1"
-      },
-      "funding": {
-        "url": "https://opencollective.com/vitest"
-      }
-    },
-    "node_modules/@vitest/runner/node_modules/p-limit": {
-      "version": "5.0.0",
-      "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-5.0.0.tgz",
-      "integrity": "sha512-/Eaoq+QyLSiXQ4lyYV23f14mZRQcXnxfHrN0vCai+ak9G0pp9iEQukIIZq5NccEvwRB8PUnZT0KsOoDCINS1qQ==",
-      "dev": true,
-      "dependencies": {
-        "yocto-queue": "^1.0.0"
-      },
-      "engines": {
-        "node": ">=18"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/@vitest/runner/node_modules/yocto-queue": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.0.0.tgz",
-      "integrity": "sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g==",
-      "dev": true,
-      "engines": {
-        "node": ">=12.20"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/@vitest/snapshot": {
-      "version": "1.5.1",
-      "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-1.5.1.tgz",
-      "integrity": "sha512-h/1SGaZYXmjn6hULRBOlqam2z4oTlEe6WwARRzLErAPBqljAs6eX7tfdyN0K+MpipIwSZ5sZsubDWkCPAiVXZQ==",
-      "dev": true,
-      "dependencies": {
-        "magic-string": "^0.30.5",
-        "pathe": "^1.1.1",
-        "pretty-format": "^29.7.0"
-      },
-      "funding": {
-        "url": "https://opencollective.com/vitest"
-      }
-    },
-    "node_modules/@vitest/spy": {
-      "version": "1.5.1",
-      "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-1.5.1.tgz",
-      "integrity": "sha512-vsqczk6uPJjmPLy6AEtqfbFqgLYcGBe9BTY+XL8L6y8vrGOhyE23CJN9P/hPimKXnScbqiZ/r/UtUSOQ2jIDGg==",
-      "dev": true,
-      "dependencies": {
-        "tinyspy": "^2.2.0"
-      },
-      "funding": {
-        "url": "https://opencollective.com/vitest"
-      }
-    },
-    "node_modules/@vitest/utils": {
-      "version": "1.5.1",
-      "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-1.5.1.tgz",
-      "integrity": "sha512-92pE17bBXUxA0Y7goPcvnATMCuq4NQLOmqsG0e2BtzRi7KLwZB5jpiELi/8ybY8IQNWemKjSD5rMoO7xTdv8ug==",
-      "dev": true,
-      "dependencies": {
-        "diff-sequences": "^29.6.3",
-        "estree-walker": "^3.0.3",
-        "loupe": "^2.3.7",
-        "pretty-format": "^29.7.0"
-      },
-      "funding": {
-        "url": "https://opencollective.com/vitest"
-      }
-    },
-    "node_modules/@volar/language-core": {
-      "version": "2.2.0-alpha.10",
-      "resolved": "https://registry.npmjs.org/@volar/language-core/-/language-core-2.2.0-alpha.10.tgz",
-      "integrity": "sha512-njVJLtpu0zMvDaEk7K5q4BRpOgbyEUljU++un9TfJoJNhxG0z/hWwpwgTRImO42EKvwIxF3XUzeMk+qatAFy7Q==",
-      "dev": true,
-      "dependencies": {
-        "@volar/source-map": "2.2.0-alpha.10"
-      }
-    },
-    "node_modules/@volar/source-map": {
-      "version": "2.2.0-alpha.10",
-      "resolved": "https://registry.npmjs.org/@volar/source-map/-/source-map-2.2.0-alpha.10.tgz",
-      "integrity": "sha512-nrdWApVkP5cksAnDEyy1JD9rKdwOJsEq1B+seWO4vNXmZNcxQQCx4DULLBvKt7AzRUAQiAuw5aQkb9RBaSqdVA==",
-      "dev": true,
-      "dependencies": {
-        "muggle-string": "^0.4.0"
-      }
-    },
-    "node_modules/@volar/typescript": {
-      "version": "2.2.0-alpha.10",
-      "resolved": "https://registry.npmjs.org/@volar/typescript/-/typescript-2.2.0-alpha.10.tgz",
-      "integrity": "sha512-GCa0vTVVdA9ULUsu2Rx7jwsIuyZQPvPVT9o3NrANTbYv+523Ao1gv3glC5vzNSDPM6bUl37r94HbCj7KINQr+g==",
-      "dev": true,
-      "dependencies": {
-        "@volar/language-core": "2.2.0-alpha.10",
-        "path-browserify": "^1.0.1"
-      }
-    },
-    "node_modules/@vue/compiler-core": {
-      "version": "3.4.25",
-      "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.4.25.tgz",
-      "integrity": "sha512-Y2pLLopaElgWnMNolgG8w3C5nNUVev80L7hdQ5iIKPtMJvhVpG0zhnBG/g3UajJmZdvW0fktyZTotEHD1Srhbg==",
-      "dependencies": {
-        "@babel/parser": "^7.24.4",
-        "@vue/shared": "3.4.25",
-        "entities": "^4.5.0",
-        "estree-walker": "^2.0.2",
-        "source-map-js": "^1.2.0"
-      }
-    },
-    "node_modules/@vue/compiler-core/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=="
-    },
-    "node_modules/@vue/compiler-dom": {
-      "version": "3.4.25",
-      "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.4.25.tgz",
-      "integrity": "sha512-Ugz5DusW57+HjllAugLci19NsDK+VyjGvmbB2TXaTcSlQxwL++2PETHx/+Qv6qFwNLzSt7HKepPe4DcTE3pBWg==",
-      "dependencies": {
-        "@vue/compiler-core": "3.4.25",
-        "@vue/shared": "3.4.25"
-      }
-    },
-    "node_modules/@vue/compiler-sfc": {
-      "version": "3.4.25",
-      "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.4.25.tgz",
-      "integrity": "sha512-m7rryuqzIoQpOBZ18wKyq05IwL6qEpZxFZfRxlNYuIPDqywrXQxgUwLXIvoU72gs6cRdY6wHD0WVZIFE4OEaAQ==",
-      "dependencies": {
-        "@babel/parser": "^7.24.4",
-        "@vue/compiler-core": "3.4.25",
-        "@vue/compiler-dom": "3.4.25",
-        "@vue/compiler-ssr": "3.4.25",
-        "@vue/shared": "3.4.25",
-        "estree-walker": "^2.0.2",
-        "magic-string": "^0.30.10",
-        "postcss": "^8.4.38",
-        "source-map-js": "^1.2.0"
-      }
-    },
-    "node_modules/@vue/compiler-sfc/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=="
-    },
-    "node_modules/@vue/compiler-ssr": {
-      "version": "3.4.25",
-      "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.4.25.tgz",
-      "integrity": "sha512-H2ohvM/Pf6LelGxDBnfbbXFPyM4NE3hrw0e/EpwuSiYu8c819wx+SVGdJ65p/sFrYDd6OnSDxN1MB2mN07hRSQ==",
-      "dependencies": {
-        "@vue/compiler-dom": "3.4.25",
-        "@vue/shared": "3.4.25"
-      }
-    },
-    "node_modules/@vue/devtools-api": {
-      "version": "6.6.1",
-      "resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-6.6.1.tgz",
-      "integrity": "sha512-LgPscpE3Vs0x96PzSSB4IGVSZXZBZHpfxs+ZA1d+VEPwHdOXowy/Y2CsvCAIFrf+ssVU1pD1jidj505EpUnfbA=="
-    },
-    "node_modules/@vue/eslint-config-prettier": {
-      "version": "9.0.0",
-      "resolved": "https://registry.npmjs.org/@vue/eslint-config-prettier/-/eslint-config-prettier-9.0.0.tgz",
-      "integrity": "sha512-z1ZIAAUS9pKzo/ANEfd2sO+v2IUalz7cM/cTLOZ7vRFOPk5/xuRKQteOu1DErFLAh/lYGXMVZ0IfYKlyInuDVg==",
-      "dev": true,
-      "dependencies": {
-        "eslint-config-prettier": "^9.0.0",
-        "eslint-plugin-prettier": "^5.0.0"
-      },
-      "peerDependencies": {
-        "eslint": ">= 8.0.0",
-        "prettier": ">= 3.0.0"
-      }
-    },
-    "node_modules/@vue/eslint-config-typescript": {
-      "version": "13.0.0",
-      "resolved": "https://registry.npmjs.org/@vue/eslint-config-typescript/-/eslint-config-typescript-13.0.0.tgz",
-      "integrity": "sha512-MHh9SncG/sfqjVqjcuFLOLD6Ed4dRAis4HNt0dXASeAuLqIAx4YMB1/m2o4pUKK1vCt8fUvYG8KKX2Ot3BVZTg==",
-      "dev": true,
-      "dependencies": {
-        "@typescript-eslint/eslint-plugin": "^7.1.1",
-        "@typescript-eslint/parser": "^7.1.1",
-        "vue-eslint-parser": "^9.3.1"
-      },
-      "engines": {
-        "node": "^18.18.0 || >=20.0.0"
-      },
-      "peerDependencies": {
-        "eslint": "^8.56.0",
-        "eslint-plugin-vue": "^9.0.0",
-        "typescript": ">=4.7.4"
-      },
-      "peerDependenciesMeta": {
-        "typescript": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@vue/language-core": {
-      "version": "2.0.14",
-      "resolved": "https://registry.npmjs.org/@vue/language-core/-/language-core-2.0.14.tgz",
-      "integrity": "sha512-3q8mHSNcGTR7sfp2X6jZdcb4yt8AjBXAfKk0qkZIh7GAJxOnoZ10h5HToZglw4ToFvAnq+xu/Z2FFbglh9Icag==",
-      "dev": true,
-      "dependencies": {
-        "@volar/language-core": "2.2.0-alpha.10",
-        "@vue/compiler-dom": "^3.4.0",
-        "@vue/shared": "^3.4.0",
-        "computeds": "^0.0.1",
-        "minimatch": "^9.0.3",
-        "path-browserify": "^1.0.1",
-        "vue-template-compiler": "^2.7.14"
-      },
-      "peerDependencies": {
-        "typescript": "*"
-      },
-      "peerDependenciesMeta": {
-        "typescript": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@vue/reactivity": {
-      "version": "3.4.25",
-      "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.4.25.tgz",
-      "integrity": "sha512-mKbEtKr1iTxZkAG3vm3BtKHAOhuI4zzsVcN0epDldU/THsrvfXRKzq+lZnjczZGnTdh3ojd86/WrP+u9M51pWQ==",
-      "dependencies": {
-        "@vue/shared": "3.4.25"
-      }
-    },
-    "node_modules/@vue/runtime-core": {
-      "version": "3.4.25",
-      "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.4.25.tgz",
-      "integrity": "sha512-3qhsTqbEh8BMH3pXf009epCI5E7bKu28fJLi9O6W+ZGt/6xgSfMuGPqa5HRbUxLoehTNp5uWvzCr60KuiRIL0Q==",
-      "dependencies": {
-        "@vue/reactivity": "3.4.25",
-        "@vue/shared": "3.4.25"
-      }
-    },
-    "node_modules/@vue/runtime-dom": {
-      "version": "3.4.25",
-      "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.4.25.tgz",
-      "integrity": "sha512-ode0sj77kuwXwSc+2Yhk8JMHZh1sZp9F/51wdBiz3KGaWltbKtdihlJFhQG4H6AY+A06zzeMLkq6qu8uDSsaoA==",
-      "dependencies": {
-        "@vue/runtime-core": "3.4.25",
-        "@vue/shared": "3.4.25",
-        "csstype": "^3.1.3"
-      }
-    },
-    "node_modules/@vue/server-renderer": {
-      "version": "3.4.25",
-      "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.4.25.tgz",
-      "integrity": "sha512-8VTwq0Zcu3K4dWV0jOwIVINESE/gha3ifYCOKEhxOj6MEl5K5y8J8clQncTcDhKF+9U765nRw4UdUEXvrGhyVQ==",
-      "dependencies": {
-        "@vue/compiler-ssr": "3.4.25",
-        "@vue/shared": "3.4.25"
-      },
-      "peerDependencies": {
-        "vue": "3.4.25"
-      }
-    },
-    "node_modules/@vue/shared": {
-      "version": "3.4.25",
-      "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.4.25.tgz",
-      "integrity": "sha512-k0yappJ77g2+KNrIaF0FFnzwLvUBLUYr8VOwz+/6vLsmItFp51AcxLL7Ey3iPd7BIRyWPOcqUjMnm7OkahXllA=="
-    },
-    "node_modules/@vue/test-utils": {
-      "version": "2.4.5",
-      "resolved": "https://registry.npmjs.org/@vue/test-utils/-/test-utils-2.4.5.tgz",
-      "integrity": "sha512-oo2u7vktOyKUked36R93NB7mg2B+N7Plr8lxp2JBGwr18ch6EggFjixSCdIVVLkT6Qr0z359Xvnafc9dcKyDUg==",
-      "dev": true,
-      "dependencies": {
-        "js-beautify": "^1.14.9",
-        "vue-component-type-helpers": "^2.0.0"
-      }
-    },
-    "node_modules/@vue/tsconfig": {
-      "version": "0.5.1",
-      "resolved": "https://registry.npmjs.org/@vue/tsconfig/-/tsconfig-0.5.1.tgz",
-      "integrity": "sha512-VcZK7MvpjuTPx2w6blwnwZAu5/LgBUtejFOi3pPGQFXQN5Ela03FUtd2Qtg4yWGGissVL0dr6Ro1LfOFh+PCuQ==",
-      "dev": true
-    },
-    "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,
-      "engines": {
-        "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
-      }
-    },
-    "node_modules/acorn": {
-      "version": "8.11.3",
-      "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz",
-      "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==",
-      "dev": 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,
-      "peerDependencies": {
-        "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0"
-      }
-    },
-    "node_modules/acorn-walk": {
-      "version": "8.3.2",
-      "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.2.tgz",
-      "integrity": "sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A==",
-      "dev": true,
-      "engines": {
-        "node": ">=0.4.0"
-      }
-    },
-    "node_modules/agent-base": {
-      "version": "7.1.1",
-      "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.1.tgz",
-      "integrity": "sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==",
-      "dev": true,
-      "dependencies": {
-        "debug": "^4.3.4"
-      },
-      "engines": {
-        "node": ">= 14"
-      }
-    },
-    "node_modules/aggregate-error": {
-      "version": "3.1.0",
-      "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz",
-      "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==",
-      "dev": true,
-      "dependencies": {
-        "clean-stack": "^2.0.0",
-        "indent-string": "^4.0.0"
-      },
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "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,
-      "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/animejs": {
-      "version": "3.2.2",
-      "resolved": "https://registry.npmjs.org/animejs/-/animejs-3.2.2.tgz",
-      "integrity": "sha512-Ao95qWLpDPXXM+WrmwcKbl6uNlC5tjnowlaRYtuVDHHoygjtIPfDUoK9NthrlZsQSKjZXlmji2TrBUAVbiH0LQ=="
-    },
-    "node_modules/ansi-colors": {
-      "version": "4.1.3",
-      "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz",
-      "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==",
-      "dev": true,
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/ansi-escapes": {
-      "version": "4.3.2",
-      "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz",
-      "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==",
-      "dev": true,
-      "dependencies": {
-        "type-fest": "^0.21.3"
-      },
-      "engines": {
-        "node": ">=8"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/ansi-escapes/node_modules/type-fest": {
-      "version": "0.21.3",
-      "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz",
-      "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==",
-      "dev": true,
-      "engines": {
-        "node": ">=10"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "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,
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "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,
-      "dependencies": {
-        "color-convert": "^2.0.1"
-      },
-      "engines": {
-        "node": ">=8"
-      },
-      "funding": {
-        "url": "https://github.com/chalk/ansi-styles?sponsor=1"
-      }
-    },
-    "node_modules/any-promise": {
-      "version": "1.3.0",
-      "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz",
-      "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==",
-      "dev": true
-    },
-    "node_modules/anymatch": {
-      "version": "3.1.3",
-      "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz",
-      "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==",
-      "dev": true,
-      "dependencies": {
-        "normalize-path": "^3.0.0",
-        "picomatch": "^2.0.4"
-      },
-      "engines": {
-        "node": ">= 8"
-      }
-    },
-    "node_modules/arch": {
-      "version": "2.2.0",
-      "resolved": "https://registry.npmjs.org/arch/-/arch-2.2.0.tgz",
-      "integrity": "sha512-Of/R0wqp83cgHozfIYLbBMnej79U/SVGOOyuB3VVFv1NRM/PSFMK12x9KVtiYzJqmnU5WR2qp0Z5rHb7sWGnFQ==",
-      "dev": true,
-      "funding": [
-        {
-          "type": "github",
-          "url": "https://github.com/sponsors/feross"
-        },
-        {
-          "type": "patreon",
-          "url": "https://www.patreon.com/feross"
-        },
-        {
-          "type": "consulting",
-          "url": "https://feross.org/support"
-        }
-      ]
-    },
-    "node_modules/arg": {
-      "version": "5.0.2",
-      "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz",
-      "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==",
-      "dev": true
-    },
-    "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
-    },
-    "node_modules/array-union": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz",
-      "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==",
-      "dev": true,
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/asn1": {
-      "version": "0.2.6",
-      "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz",
-      "integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==",
-      "dev": true,
-      "dependencies": {
-        "safer-buffer": "~2.1.0"
-      }
-    },
-    "node_modules/assert-plus": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
-      "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==",
-      "dev": true,
-      "engines": {
-        "node": ">=0.8"
-      }
-    },
-    "node_modules/assertion-error": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz",
-      "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==",
-      "dev": true,
-      "engines": {
-        "node": "*"
-      }
-    },
-    "node_modules/astral-regex": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz",
-      "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==",
-      "dev": true,
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/async": {
-      "version": "3.2.5",
-      "resolved": "https://registry.npmjs.org/async/-/async-3.2.5.tgz",
-      "integrity": "sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg==",
-      "dev": true
-    },
-    "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
-    },
-    "node_modules/at-least-node": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz",
-      "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==",
-      "dev": true,
-      "engines": {
-        "node": ">= 4.0.0"
-      }
-    },
-    "node_modules/autoprefixer": {
-      "version": "10.4.19",
-      "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.19.tgz",
-      "integrity": "sha512-BaENR2+zBZ8xXhM4pUaKUxlVdxZ0EZhjvbopwnXmxRUfqDmwSpC2lAi/QXvx7NRdPCo1WKEcEF6mV64si1z4Ew==",
-      "dev": true,
-      "funding": [
-        {
-          "type": "opencollective",
-          "url": "https://opencollective.com/postcss/"
-        },
-        {
-          "type": "tidelift",
-          "url": "https://tidelift.com/funding/github/npm/autoprefixer"
-        },
-        {
-          "type": "github",
-          "url": "https://github.com/sponsors/ai"
-        }
-      ],
-      "dependencies": {
-        "browserslist": "^4.23.0",
-        "caniuse-lite": "^1.0.30001599",
-        "fraction.js": "^4.3.7",
-        "normalize-range": "^0.1.2",
-        "picocolors": "^1.0.0",
-        "postcss-value-parser": "^4.2.0"
-      },
-      "bin": {
-        "autoprefixer": "bin/autoprefixer"
-      },
-      "engines": {
-        "node": "^10 || ^12 || >=14"
-      },
-      "peerDependencies": {
-        "postcss": "^8.1.0"
-      }
-    },
-    "node_modules/aws-sign2": {
-      "version": "0.7.0",
-      "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz",
-      "integrity": "sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==",
-      "dev": true,
-      "engines": {
-        "node": "*"
-      }
-    },
-    "node_modules/aws4": {
-      "version": "1.12.0",
-      "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.12.0.tgz",
-      "integrity": "sha512-NmWvPnx0F1SfrQbYwOi7OeaNGokp9XhzNioJ/CSBs8Qa4vxug81mhJEAVZwxXuBmYB5KDRfMq/F3RR0BIU7sWg==",
-      "dev": true
-    },
-    "node_modules/axios": {
-      "version": "1.6.8",
-      "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.8.tgz",
-      "integrity": "sha512-v/ZHtJDU39mDpyBoFVkETcd/uNdxrWRrg3bKpOKzXFA6Bvqopts6ALSMU3y6ijYxbw2B+wPrIv46egTzJXCLGQ==",
-      "dev": true,
-      "dependencies": {
-        "follow-redirects": "^1.15.6",
-        "form-data": "^4.0.0",
-        "proxy-from-env": "^1.1.0"
-      }
-    },
-    "node_modules/axios-mock-adapter": {
-      "version": "1.22.0",
-      "resolved": "https://registry.npmjs.org/axios-mock-adapter/-/axios-mock-adapter-1.22.0.tgz",
-      "integrity": "sha512-dmI0KbkyAhntUR05YY96qg2H6gg0XMl2+qTW0xmYg6Up+BFBAJYRLROMXRdDEL06/Wqwa0TJThAYvFtSFdRCZw==",
-      "dev": true,
-      "dependencies": {
-        "fast-deep-equal": "^3.1.3",
-        "is-buffer": "^2.0.5"
-      },
-      "peerDependencies": {
-        "axios": ">= 0.17.0"
-      }
-    },
-    "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
-    },
-    "node_modules/base64-js": {
-      "version": "1.5.1",
-      "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
-      "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==",
-      "dev": true,
-      "funding": [
-        {
-          "type": "github",
-          "url": "https://github.com/sponsors/feross"
-        },
-        {
-          "type": "patreon",
-          "url": "https://www.patreon.com/feross"
-        },
-        {
-          "type": "consulting",
-          "url": "https://feross.org/support"
-        }
-      ]
-    },
-    "node_modules/bcrypt-pbkdf": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz",
-      "integrity": "sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==",
-      "dev": true,
-      "dependencies": {
-        "tweetnacl": "^0.14.3"
-      }
-    },
-    "node_modules/binary-extensions": {
-      "version": "2.3.0",
-      "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz",
-      "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==",
-      "dev": true,
-      "engines": {
-        "node": ">=8"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/blob-util": {
-      "version": "2.0.2",
-      "resolved": "https://registry.npmjs.org/blob-util/-/blob-util-2.0.2.tgz",
-      "integrity": "sha512-T7JQa+zsXXEa6/8ZhHcQEW1UFfVM49Ts65uBkFL6fz2QmrElqmbajIDJvuA0tEhRe5eIjpV9ZF+0RfZR9voJFQ==",
-      "dev": true
-    },
-    "node_modules/bluebird": {
-      "version": "3.7.2",
-      "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz",
-      "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==",
-      "dev": true
-    },
-    "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
-    },
-    "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,
-      "dependencies": {
-        "balanced-match": "^1.0.0"
-      }
-    },
-    "node_modules/braces": {
-      "version": "3.0.2",
-      "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
-      "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
-      "dev": true,
-      "dependencies": {
-        "fill-range": "^7.0.1"
-      },
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/browserslist": {
-      "version": "4.23.0",
-      "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.0.tgz",
-      "integrity": "sha512-QW8HiM1shhT2GuzkvklfjcKDiWFXHOeFCIA/huJPwHsslwcydgk7X+z2zXpEijP98UCY7HbubZt5J2Zgvf0CaQ==",
-      "dev": true,
-      "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"
-        }
-      ],
-      "dependencies": {
-        "caniuse-lite": "^1.0.30001587",
-        "electron-to-chromium": "^1.4.668",
-        "node-releases": "^2.0.14",
-        "update-browserslist-db": "^1.0.13"
-      },
-      "bin": {
-        "browserslist": "cli.js"
-      },
-      "engines": {
-        "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7"
-      }
-    },
-    "node_modules/buffer": {
-      "version": "5.7.1",
-      "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz",
-      "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==",
-      "dev": true,
-      "funding": [
-        {
-          "type": "github",
-          "url": "https://github.com/sponsors/feross"
-        },
-        {
-          "type": "patreon",
-          "url": "https://www.patreon.com/feross"
-        },
-        {
-          "type": "consulting",
-          "url": "https://feross.org/support"
-        }
-      ],
-      "dependencies": {
-        "base64-js": "^1.3.1",
-        "ieee754": "^1.1.13"
-      }
-    },
-    "node_modules/buffer-crc32": {
-      "version": "0.2.13",
-      "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz",
-      "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==",
-      "dev": true,
-      "engines": {
-        "node": "*"
-      }
-    },
-    "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,
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/cachedir": {
-      "version": "2.4.0",
-      "resolved": "https://registry.npmjs.org/cachedir/-/cachedir-2.4.0.tgz",
-      "integrity": "sha512-9EtFOZR8g22CL7BWjJ9BUx1+A/djkofnyW3aOXZORNW2kxoUpx2h+uN2cOqwPmFhnpVmxg+KW2OjOSgChTEvsQ==",
-      "dev": true,
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/call-bind": {
-      "version": "1.0.7",
-      "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz",
-      "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==",
-      "dev": true,
-      "dependencies": {
-        "es-define-property": "^1.0.0",
-        "es-errors": "^1.3.0",
-        "function-bind": "^1.1.2",
-        "get-intrinsic": "^1.2.4",
-        "set-function-length": "^1.2.1"
-      },
-      "engines": {
-        "node": ">= 0.4"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/ljharb"
-      }
-    },
-    "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,
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/camelcase-css": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz",
-      "integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==",
-      "dev": true,
-      "engines": {
-        "node": ">= 6"
-      }
-    },
-    "node_modules/caniuse-lite": {
-      "version": "1.0.30001612",
-      "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001612.tgz",
-      "integrity": "sha512-lFgnZ07UhaCcsSZgWW0K5j4e69dK1u/ltrL9lTUiFOwNHs12S3UMIEYgBV0Z6C6hRDev7iRnMzzYmKabYdXF9g==",
-      "dev": true,
-      "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"
-        }
-      ]
-    },
-    "node_modules/canvas-confetti": {
-      "version": "1.9.2",
-      "resolved": "https://registry.npmjs.org/canvas-confetti/-/canvas-confetti-1.9.2.tgz",
-      "integrity": "sha512-6Xi7aHHzKwxZsem4mCKoqP6YwUG3HamaHHAlz1hTNQPCqXhARFpSXnkC9TWlahHY5CG6hSL5XexNjxK8irVErg==",
-      "funding": {
-        "type": "donate",
-        "url": "https://www.paypal.me/kirilvatev"
-      }
-    },
-    "node_modules/caseless": {
-      "version": "0.12.0",
-      "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz",
-      "integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==",
-      "dev": true
-    },
-    "node_modules/chai": {
-      "version": "4.4.1",
-      "resolved": "https://registry.npmjs.org/chai/-/chai-4.4.1.tgz",
-      "integrity": "sha512-13sOfMv2+DWduEU+/xbun3LScLoqN17nBeTLUsmDfKdoiC1fr0n9PU4guu4AhRcOVFk/sW8LyZWHuhWtQZiF+g==",
-      "dev": true,
-      "dependencies": {
-        "assertion-error": "^1.1.0",
-        "check-error": "^1.0.3",
-        "deep-eql": "^4.1.3",
-        "get-func-name": "^2.0.2",
-        "loupe": "^2.3.6",
-        "pathval": "^1.1.1",
-        "type-detect": "^4.0.8"
-      },
-      "engines": {
-        "node": ">=4"
-      }
-    },
-    "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,
-      "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/chalk/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,
-      "dependencies": {
-        "has-flag": "^4.0.0"
-      },
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/check-error": {
-      "version": "1.0.3",
-      "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.3.tgz",
-      "integrity": "sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==",
-      "dev": true,
-      "dependencies": {
-        "get-func-name": "^2.0.2"
-      },
-      "engines": {
-        "node": "*"
-      }
-    },
-    "node_modules/check-more-types": {
-      "version": "2.24.0",
-      "resolved": "https://registry.npmjs.org/check-more-types/-/check-more-types-2.24.0.tgz",
-      "integrity": "sha512-Pj779qHxV2tuapviy1bSZNEL1maXr13bPYpsvSDB68HlYcYuhlDrmGd63i0JHMCLKzc7rUSNIrpdJlhVlNwrxA==",
-      "dev": true,
-      "engines": {
-        "node": ">= 0.8.0"
-      }
-    },
-    "node_modules/chokidar": {
-      "version": "3.6.0",
-      "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz",
-      "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==",
-      "dev": true,
-      "dependencies": {
-        "anymatch": "~3.1.2",
-        "braces": "~3.0.2",
-        "glob-parent": "~5.1.2",
-        "is-binary-path": "~2.1.0",
-        "is-glob": "~4.0.1",
-        "normalize-path": "~3.0.0",
-        "readdirp": "~3.6.0"
-      },
-      "engines": {
-        "node": ">= 8.10.0"
-      },
-      "funding": {
-        "url": "https://paulmillr.com/funding/"
-      },
-      "optionalDependencies": {
-        "fsevents": "~2.3.2"
-      }
-    },
-    "node_modules/chokidar/node_modules/glob-parent": {
-      "version": "5.1.2",
-      "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
-      "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
-      "dev": true,
-      "dependencies": {
-        "is-glob": "^4.0.1"
-      },
-      "engines": {
-        "node": ">= 6"
-      }
-    },
-    "node_modules/ci-info": {
-      "version": "3.9.0",
-      "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz",
-      "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==",
-      "dev": true,
-      "funding": [
-        {
-          "type": "github",
-          "url": "https://github.com/sponsors/sibiraj-s"
-        }
-      ],
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/clean-stack": {
-      "version": "2.2.0",
-      "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz",
-      "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==",
-      "dev": true,
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/cli-cursor": {
-      "version": "3.1.0",
-      "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz",
-      "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==",
-      "dev": true,
-      "dependencies": {
-        "restore-cursor": "^3.1.0"
-      },
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/cli-table3": {
-      "version": "0.6.4",
-      "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.4.tgz",
-      "integrity": "sha512-Lm3L0p+/npIQWNIiyF/nAn7T5dnOwR3xNTHXYEBFBFVPXzCVNZ5lqEC/1eo/EVfpDsQ1I+TX4ORPQgp+UI0CRw==",
-      "dev": true,
-      "dependencies": {
-        "string-width": "^4.2.0"
-      },
-      "engines": {
-        "node": "10.* || >= 12.*"
-      },
-      "optionalDependencies": {
-        "@colors/colors": "1.5.0"
-      }
-    },
-    "node_modules/cli-truncate": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-2.1.0.tgz",
-      "integrity": "sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg==",
-      "dev": true,
-      "dependencies": {
-        "slice-ansi": "^3.0.0",
-        "string-width": "^4.2.0"
-      },
-      "engines": {
-        "node": ">=8"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "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,
-      "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
-    },
-    "node_modules/colorette": {
-      "version": "2.0.20",
-      "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz",
-      "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==",
-      "dev": true
-    },
-    "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,
-      "dependencies": {
-        "delayed-stream": "~1.0.0"
-      },
-      "engines": {
-        "node": ">= 0.8"
-      }
-    },
-    "node_modules/commander": {
-      "version": "6.2.1",
-      "resolved": "https://registry.npmjs.org/commander/-/commander-6.2.1.tgz",
-      "integrity": "sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==",
-      "dev": true,
-      "engines": {
-        "node": ">= 6"
-      }
-    },
-    "node_modules/common-tags": {
-      "version": "1.8.2",
-      "resolved": "https://registry.npmjs.org/common-tags/-/common-tags-1.8.2.tgz",
-      "integrity": "sha512-gk/Z852D2Wtb//0I+kRFNKKE9dIIVirjoqPoA1wJU+XePVXZfGeBpk45+A1rKO4Q43prqWBNY/MiIeRLbPWUaA==",
-      "dev": true,
-      "engines": {
-        "node": ">=4.0.0"
-      }
-    },
-    "node_modules/computeds": {
-      "version": "0.0.1",
-      "resolved": "https://registry.npmjs.org/computeds/-/computeds-0.0.1.tgz",
-      "integrity": "sha512-7CEBgcMjVmitjYo5q8JTJVra6X5mQ20uTThdK+0kR7UEaDrAWEQcRiBtWJzga4eRpP6afNwwLsX2SET2JhVB1Q==",
-      "dev": true
-    },
-    "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
-    },
-    "node_modules/confbox": {
-      "version": "0.1.7",
-      "resolved": "https://registry.npmjs.org/confbox/-/confbox-0.1.7.tgz",
-      "integrity": "sha512-uJcB/FKZtBMCJpK8MQji6bJHgu1tixKPxRLeGkNzBoOZzpnZUJm0jm2/sBDWcuBx1dYgxV4JU+g5hmNxCyAmdA==",
-      "dev": true
-    },
-    "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,
-      "dependencies": {
-        "ini": "^1.3.4",
-        "proto-list": "~1.2.1"
-      }
-    },
-    "node_modules/config-chain/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
-    },
-    "node_modules/core-util-is": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
-      "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==",
-      "dev": true
-    },
-    "node_modules/cross-spawn": {
-      "version": "7.0.3",
-      "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
-      "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
-      "dev": true,
-      "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,
-      "bin": {
-        "cssesc": "bin/cssesc"
-      },
-      "engines": {
-        "node": ">=4"
-      }
-    },
-    "node_modules/cssstyle": {
-      "version": "4.0.1",
-      "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-4.0.1.tgz",
-      "integrity": "sha512-8ZYiJ3A/3OkDd093CBT/0UKDWry7ak4BdPTFP2+QEP7cmhouyq/Up709ASSj2cK02BbZiMgk7kYjZNS4QP5qrQ==",
-      "dev": true,
-      "dependencies": {
-        "rrweb-cssom": "^0.6.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=="
-    },
-    "node_modules/cypress": {
-      "version": "13.8.1",
-      "resolved": "https://registry.npmjs.org/cypress/-/cypress-13.8.1.tgz",
-      "integrity": "sha512-Uk6ovhRbTg6FmXjeZW/TkbRM07KPtvM5gah1BIMp4Y2s+i/NMxgaLw0+PbYTOdw1+egE0FP3mWRiGcRkjjmhzA==",
-      "dev": true,
-      "hasInstallScript": true,
-      "dependencies": {
-        "@cypress/request": "^3.0.0",
-        "@cypress/xvfb": "^1.2.4",
-        "@types/sinonjs__fake-timers": "8.1.1",
-        "@types/sizzle": "^2.3.2",
-        "arch": "^2.2.0",
-        "blob-util": "^2.0.2",
-        "bluebird": "^3.7.2",
-        "buffer": "^5.7.1",
-        "cachedir": "^2.3.0",
-        "chalk": "^4.1.0",
-        "check-more-types": "^2.24.0",
-        "cli-cursor": "^3.1.0",
-        "cli-table3": "~0.6.1",
-        "commander": "^6.2.1",
-        "common-tags": "^1.8.0",
-        "dayjs": "^1.10.4",
-        "debug": "^4.3.4",
-        "enquirer": "^2.3.6",
-        "eventemitter2": "6.4.7",
-        "execa": "4.1.0",
-        "executable": "^4.1.1",
-        "extract-zip": "2.0.1",
-        "figures": "^3.2.0",
-        "fs-extra": "^9.1.0",
-        "getos": "^3.2.1",
-        "is-ci": "^3.0.1",
-        "is-installed-globally": "~0.4.0",
-        "lazy-ass": "^1.6.0",
-        "listr2": "^3.8.3",
-        "lodash": "^4.17.21",
-        "log-symbols": "^4.0.0",
-        "minimist": "^1.2.8",
-        "ospath": "^1.2.2",
-        "pretty-bytes": "^5.6.0",
-        "process": "^0.11.10",
-        "proxy-from-env": "1.0.0",
-        "request-progress": "^3.0.0",
-        "semver": "^7.5.3",
-        "supports-color": "^8.1.1",
-        "tmp": "~0.2.1",
-        "untildify": "^4.0.0",
-        "yauzl": "^2.10.0"
-      },
-      "bin": {
-        "cypress": "bin/cypress"
-      },
-      "engines": {
-        "node": "^16.0.0 || ^18.0.0 || >=20.0.0"
-      }
-    },
-    "node_modules/cypress/node_modules/proxy-from-env": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.0.0.tgz",
-      "integrity": "sha512-F2JHgJQ1iqwnHDcQjVBsq3n/uoaFL+iPW/eAeL7kVxy/2RrWaN4WroKjjvbsoRtv0ftelNyC01bjRhn/bhcf4A==",
-      "dev": true
-    },
-    "node_modules/dashdash": {
-      "version": "1.14.1",
-      "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz",
-      "integrity": "sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==",
-      "dev": true,
-      "dependencies": {
-        "assert-plus": "^1.0.0"
-      },
-      "engines": {
-        "node": ">=0.10"
-      }
-    },
-    "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,
-      "dependencies": {
-        "whatwg-mimetype": "^4.0.0",
-        "whatwg-url": "^14.0.0"
-      },
-      "engines": {
-        "node": ">=18"
-      }
-    },
-    "node_modules/dayjs": {
-      "version": "1.11.10",
-      "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.10.tgz",
-      "integrity": "sha512-vjAczensTgRcqDERK0SR2XMwsF/tSvnvlv6VcF2GIhg6Sx4yOIt/irsr1RDJsKiIyBzJDpCoXiWWq28MqH2cnQ==",
-      "dev": true
-    },
-    "node_modules/de-indent": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/de-indent/-/de-indent-1.0.2.tgz",
-      "integrity": "sha512-e/1zu3xH5MQryN2zdVaF0OrdNLUbvWxzMbi+iNA6Bky7l1RoP8a2fIbRocyHclXt/arDrrR6lL3TqFD9pMQTsg==",
-      "dev": true
-    },
-    "node_modules/debug": {
-      "version": "4.3.4",
-      "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
-      "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
-      "dev": true,
-      "dependencies": {
-        "ms": "2.1.2"
-      },
-      "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
-    },
-    "node_modules/deep-eql": {
-      "version": "4.1.3",
-      "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.3.tgz",
-      "integrity": "sha512-WaEtAOpRA1MQ0eohqZjpGD8zdI0Ovsm8mmFhaDN8dvDZzyoUMcYDnf5Y6iu7HTXxf8JDS23qWa4a+hKCDyOPzw==",
-      "dev": true,
-      "dependencies": {
-        "type-detect": "^4.0.0"
-      },
-      "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
-    },
-    "node_modules/define-data-property": {
-      "version": "1.1.4",
-      "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz",
-      "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==",
-      "dev": true,
-      "dependencies": {
-        "es-define-property": "^1.0.0",
-        "es-errors": "^1.3.0",
-        "gopd": "^1.0.1"
-      },
-      "engines": {
-        "node": ">= 0.4"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/ljharb"
-      }
-    },
-    "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,
-      "engines": {
-        "node": ">=0.4.0"
-      }
-    },
-    "node_modules/didyoumean": {
-      "version": "1.2.2",
-      "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz",
-      "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==",
-      "dev": true
-    },
-    "node_modules/diff-sequences": {
-      "version": "29.6.3",
-      "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz",
-      "integrity": "sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==",
-      "dev": true,
-      "engines": {
-        "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
-      }
-    },
-    "node_modules/dir-glob": {
-      "version": "3.0.1",
-      "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz",
-      "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==",
-      "dev": true,
-      "dependencies": {
-        "path-type": "^4.0.0"
-      },
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/dlv": {
-      "version": "1.1.3",
-      "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz",
-      "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==",
-      "dev": true
-    },
-    "node_modules/doctrine": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz",
-      "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==",
-      "dev": true,
-      "dependencies": {
-        "esutils": "^2.0.2"
-      },
-      "engines": {
-        "node": ">=6.0.0"
-      }
-    },
-    "node_modules/duplexer": {
-      "version": "0.1.2",
-      "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz",
-      "integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==",
-      "dev": true
-    },
-    "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
-    },
-    "node_modules/ecc-jsbn": {
-      "version": "0.1.2",
-      "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz",
-      "integrity": "sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==",
-      "dev": true,
-      "dependencies": {
-        "jsbn": "~0.1.0",
-        "safer-buffer": "^2.1.0"
-      }
-    },
-    "node_modules/editorconfig": {
-      "version": "1.0.4",
-      "resolved": "https://registry.npmjs.org/editorconfig/-/editorconfig-1.0.4.tgz",
-      "integrity": "sha512-L9Qe08KWTlqYMVvMcTIvMAdl1cDUubzRNYL+WfA4bLDMHe4nemKkpmYzkznE1FwLKu0EEmy6obgQKzMJrg4x9Q==",
-      "dev": true,
-      "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/commander": {
-      "version": "10.0.1",
-      "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz",
-      "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==",
-      "dev": true,
-      "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,
-      "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.4.747",
-      "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.747.tgz",
-      "integrity": "sha512-+FnSWZIAvFHbsNVmUxhEqWiaOiPMcfum1GQzlWCg/wLigVtshOsjXHyEFfmt6cFK6+HkS3QOJBv6/3OPumbBfw==",
-      "dev": true
-    },
-    "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
-    },
-    "node_modules/end-of-stream": {
-      "version": "1.4.4",
-      "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz",
-      "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==",
-      "dev": true,
-      "dependencies": {
-        "once": "^1.4.0"
-      }
-    },
-    "node_modules/enquirer": {
-      "version": "2.4.1",
-      "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.4.1.tgz",
-      "integrity": "sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ==",
-      "dev": true,
-      "dependencies": {
-        "ansi-colors": "^4.1.1",
-        "strip-ansi": "^6.0.1"
-      },
-      "engines": {
-        "node": ">=8.6"
-      }
-    },
-    "node_modules/entities": {
-      "version": "4.5.0",
-      "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
-      "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==",
-      "engines": {
-        "node": ">=0.12"
-      },
-      "funding": {
-        "url": "https://github.com/fb55/entities?sponsor=1"
-      }
-    },
-    "node_modules/es-define-property": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz",
-      "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==",
-      "dev": true,
-      "dependencies": {
-        "get-intrinsic": "^1.2.4"
-      },
-      "engines": {
-        "node": ">= 0.4"
-      }
-    },
-    "node_modules/es-errors": {
-      "version": "1.3.0",
-      "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz",
-      "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
-      "dev": true,
-      "engines": {
-        "node": ">= 0.4"
-      }
-    },
-    "node_modules/esbuild": {
-      "version": "0.20.2",
-      "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.20.2.tgz",
-      "integrity": "sha512-WdOOppmUNU+IbZ0PaDiTst80zjnrOkyJNHoKupIcVyU8Lvla3Ugx94VzkQ32Ijqd7UhHJy75gNWDMUekcrSJ6g==",
-      "dev": true,
-      "hasInstallScript": true,
-      "bin": {
-        "esbuild": "bin/esbuild"
-      },
-      "engines": {
-        "node": ">=12"
-      },
-      "optionalDependencies": {
-        "@esbuild/aix-ppc64": "0.20.2",
-        "@esbuild/android-arm": "0.20.2",
-        "@esbuild/android-arm64": "0.20.2",
-        "@esbuild/android-x64": "0.20.2",
-        "@esbuild/darwin-arm64": "0.20.2",
-        "@esbuild/darwin-x64": "0.20.2",
-        "@esbuild/freebsd-arm64": "0.20.2",
-        "@esbuild/freebsd-x64": "0.20.2",
-        "@esbuild/linux-arm": "0.20.2",
-        "@esbuild/linux-arm64": "0.20.2",
-        "@esbuild/linux-ia32": "0.20.2",
-        "@esbuild/linux-loong64": "0.20.2",
-        "@esbuild/linux-mips64el": "0.20.2",
-        "@esbuild/linux-ppc64": "0.20.2",
-        "@esbuild/linux-riscv64": "0.20.2",
-        "@esbuild/linux-s390x": "0.20.2",
-        "@esbuild/linux-x64": "0.20.2",
-        "@esbuild/netbsd-x64": "0.20.2",
-        "@esbuild/openbsd-x64": "0.20.2",
-        "@esbuild/sunos-x64": "0.20.2",
-        "@esbuild/win32-arm64": "0.20.2",
-        "@esbuild/win32-ia32": "0.20.2",
-        "@esbuild/win32-x64": "0.20.2"
-      }
-    },
-    "node_modules/escalade": {
-      "version": "3.1.2",
-      "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz",
-      "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==",
-      "dev": true,
-      "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,
-      "engines": {
-        "node": ">=10"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/eslint": {
-      "version": "8.57.0",
-      "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.0.tgz",
-      "integrity": "sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==",
-      "dev": true,
-      "dependencies": {
-        "@eslint-community/eslint-utils": "^4.2.0",
-        "@eslint-community/regexpp": "^4.6.1",
-        "@eslint/eslintrc": "^2.1.4",
-        "@eslint/js": "8.57.0",
-        "@humanwhocodes/config-array": "^0.11.14",
-        "@humanwhocodes/module-importer": "^1.0.1",
-        "@nodelib/fs.walk": "^1.2.8",
-        "@ungap/structured-clone": "^1.2.0",
-        "ajv": "^6.12.4",
-        "chalk": "^4.0.0",
-        "cross-spawn": "^7.0.2",
-        "debug": "^4.3.2",
-        "doctrine": "^3.0.0",
-        "escape-string-regexp": "^4.0.0",
-        "eslint-scope": "^7.2.2",
-        "eslint-visitor-keys": "^3.4.3",
-        "espree": "^9.6.1",
-        "esquery": "^1.4.2",
-        "esutils": "^2.0.2",
-        "fast-deep-equal": "^3.1.3",
-        "file-entry-cache": "^6.0.1",
-        "find-up": "^5.0.0",
-        "glob-parent": "^6.0.2",
-        "globals": "^13.19.0",
-        "graphemer": "^1.4.0",
-        "ignore": "^5.2.0",
-        "imurmurhash": "^0.1.4",
-        "is-glob": "^4.0.0",
-        "is-path-inside": "^3.0.3",
-        "js-yaml": "^4.1.0",
-        "json-stable-stringify-without-jsonify": "^1.0.1",
-        "levn": "^0.4.1",
-        "lodash.merge": "^4.6.2",
-        "minimatch": "^3.1.2",
-        "natural-compare": "^1.4.0",
-        "optionator": "^0.9.3",
-        "strip-ansi": "^6.0.1",
-        "text-table": "^0.2.0"
-      },
-      "bin": {
-        "eslint": "bin/eslint.js"
-      },
-      "engines": {
-        "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
-      },
-      "funding": {
-        "url": "https://opencollective.com/eslint"
-      }
-    },
-    "node_modules/eslint-config-prettier": {
-      "version": "9.1.0",
-      "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-9.1.0.tgz",
-      "integrity": "sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw==",
-      "dev": true,
-      "bin": {
-        "eslint-config-prettier": "bin/cli.js"
-      },
-      "peerDependencies": {
-        "eslint": ">=7.0.0"
-      }
-    },
-    "node_modules/eslint-plugin-cypress": {
-      "version": "2.15.2",
-      "resolved": "https://registry.npmjs.org/eslint-plugin-cypress/-/eslint-plugin-cypress-2.15.2.tgz",
-      "integrity": "sha512-CtcFEQTDKyftpI22FVGpx8bkpKyYXBlNge6zSo0pl5/qJvBAnzaD76Vu2AsP16d6mTj478Ldn2mhgrWV+Xr0vQ==",
-      "dev": true,
-      "dependencies": {
-        "globals": "^13.20.0"
-      },
-      "peerDependencies": {
-        "eslint": ">= 3.2.1"
-      }
-    },
-    "node_modules/eslint-plugin-prettier": {
-      "version": "5.1.3",
-      "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-5.1.3.tgz",
-      "integrity": "sha512-C9GCVAs4Eq7ZC/XFQHITLiHJxQngdtraXaM+LoUFoFp/lHNl2Zn8f3WQbe9HvTBBQ9YnKFB0/2Ajdqwo5D1EAw==",
-      "dev": true,
-      "dependencies": {
-        "prettier-linter-helpers": "^1.0.0",
-        "synckit": "^0.8.6"
-      },
-      "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.25.0",
-      "resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-9.25.0.tgz",
-      "integrity": "sha512-tDWlx14bVe6Bs+Nnh3IGrD+hb11kf2nukfm6jLsmJIhmiRQ1SUaksvwY9U5MvPB0pcrg0QK0xapQkfITs3RKOA==",
-      "dev": true,
-      "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.0",
-        "vue-eslint-parser": "^9.4.2",
-        "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-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,
-      "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/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,
-      "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,
-      "dependencies": {
-        "balanced-match": "^1.0.0",
-        "concat-map": "0.0.1"
-      }
-    },
-    "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,
-      "dependencies": {
-        "brace-expansion": "^1.1.7"
-      },
-      "engines": {
-        "node": "*"
-      }
-    },
-    "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,
-      "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/esquery": {
-      "version": "1.5.0",
-      "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz",
-      "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==",
-      "dev": true,
-      "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==",
-      "dev": true,
-      "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==",
-      "dev": true,
-      "engines": {
-        "node": ">=4.0"
-      }
-    },
-    "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,
-      "dependencies": {
-        "@types/estree": "^1.0.0"
-      }
-    },
-    "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,
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/event-stream": {
-      "version": "3.3.4",
-      "resolved": "https://registry.npmjs.org/event-stream/-/event-stream-3.3.4.tgz",
-      "integrity": "sha512-QHpkERcGsR0T7Qm3HNJSyXKEEj8AHNxkY3PK8TS2KJvQ7NiSHe3DDpwVKKtoYprL/AreyzFBeIkBIWChAqn60g==",
-      "dev": true,
-      "dependencies": {
-        "duplexer": "~0.1.1",
-        "from": "~0",
-        "map-stream": "~0.1.0",
-        "pause-stream": "0.0.11",
-        "split": "0.3",
-        "stream-combiner": "~0.0.4",
-        "through": "~2.3.1"
-      }
-    },
-    "node_modules/eventemitter2": {
-      "version": "6.4.7",
-      "resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-6.4.7.tgz",
-      "integrity": "sha512-tYUSVOGeQPKt/eC1ABfhHy5Xd96N3oIijJvN3O9+TsC28T5V9yX9oEfEK5faP0EFSNVOG97qtAS68GBrQB2hDg==",
-      "dev": true
-    },
-    "node_modules/execa": {
-      "version": "4.1.0",
-      "resolved": "https://registry.npmjs.org/execa/-/execa-4.1.0.tgz",
-      "integrity": "sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA==",
-      "dev": true,
-      "dependencies": {
-        "cross-spawn": "^7.0.0",
-        "get-stream": "^5.0.0",
-        "human-signals": "^1.1.1",
-        "is-stream": "^2.0.0",
-        "merge-stream": "^2.0.0",
-        "npm-run-path": "^4.0.0",
-        "onetime": "^5.1.0",
-        "signal-exit": "^3.0.2",
-        "strip-final-newline": "^2.0.0"
-      },
-      "engines": {
-        "node": ">=10"
-      },
-      "funding": {
-        "url": "https://github.com/sindresorhus/execa?sponsor=1"
-      }
-    },
-    "node_modules/executable": {
-      "version": "4.1.1",
-      "resolved": "https://registry.npmjs.org/executable/-/executable-4.1.1.tgz",
-      "integrity": "sha512-8iA79xD3uAch729dUG8xaaBBFGaEa0wdD2VkYLFHwlqosEj/jT66AzcreRDSgV7ehnNLBW2WR5jIXwGKjVdTLg==",
-      "dev": true,
-      "dependencies": {
-        "pify": "^2.2.0"
-      },
-      "engines": {
-        "node": ">=4"
-      }
-    },
-    "node_modules/extend": {
-      "version": "3.0.2",
-      "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
-      "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==",
-      "dev": true
-    },
-    "node_modules/extract-zip": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz",
-      "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==",
-      "dev": true,
-      "dependencies": {
-        "debug": "^4.1.1",
-        "get-stream": "^5.1.0",
-        "yauzl": "^2.10.0"
-      },
-      "bin": {
-        "extract-zip": "cli.js"
-      },
-      "engines": {
-        "node": ">= 10.17.0"
-      },
-      "optionalDependencies": {
-        "@types/yauzl": "^2.9.1"
-      }
-    },
-    "node_modules/extsprintf": {
-      "version": "1.3.0",
-      "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz",
-      "integrity": "sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==",
-      "dev": true,
-      "engines": [
-        "node >=0.6.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==",
-      "dev": true
-    },
-    "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
-    },
-    "node_modules/fast-glob": {
-      "version": "3.3.2",
-      "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz",
-      "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==",
-      "dev": true,
-      "dependencies": {
-        "@nodelib/fs.stat": "^2.0.2",
-        "@nodelib/fs.walk": "^1.2.3",
-        "glob-parent": "^5.1.2",
-        "merge2": "^1.3.0",
-        "micromatch": "^4.0.4"
-      },
-      "engines": {
-        "node": ">=8.6.0"
-      }
-    },
-    "node_modules/fast-glob/node_modules/glob-parent": {
-      "version": "5.1.2",
-      "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
-      "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
-      "dev": true,
-      "dependencies": {
-        "is-glob": "^4.0.1"
-      },
-      "engines": {
-        "node": ">= 6"
-      }
-    },
-    "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
-    },
-    "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
-    },
-    "node_modules/fastq": {
-      "version": "1.17.1",
-      "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz",
-      "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==",
-      "dev": true,
-      "dependencies": {
-        "reusify": "^1.0.4"
-      }
-    },
-    "node_modules/fd-slicer": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz",
-      "integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==",
-      "dev": true,
-      "dependencies": {
-        "pend": "~1.2.0"
-      }
-    },
-    "node_modules/figures": {
-      "version": "3.2.0",
-      "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz",
-      "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==",
-      "dev": true,
-      "dependencies": {
-        "escape-string-regexp": "^1.0.5"
-      },
-      "engines": {
-        "node": ">=8"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/figures/node_modules/escape-string-regexp": {
-      "version": "1.0.5",
-      "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
-      "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==",
-      "dev": true,
-      "engines": {
-        "node": ">=0.8.0"
-      }
-    },
-    "node_modules/file-entry-cache": {
-      "version": "6.0.1",
-      "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz",
-      "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==",
-      "dev": true,
-      "dependencies": {
-        "flat-cache": "^3.0.4"
-      },
-      "engines": {
-        "node": "^10.12.0 || >=12.0.0"
-      }
-    },
-    "node_modules/fill-range": {
-      "version": "7.0.1",
-      "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
-      "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
-      "dev": 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,
-      "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": "3.2.0",
-      "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz",
-      "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==",
-      "dev": true,
-      "dependencies": {
-        "flatted": "^3.2.9",
-        "keyv": "^4.5.3",
-        "rimraf": "^3.0.2"
-      },
-      "engines": {
-        "node": "^10.12.0 || >=12.0.0"
-      }
-    },
-    "node_modules/flatted": {
-      "version": "3.3.1",
-      "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz",
-      "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==",
-      "dev": true
-    },
-    "node_modules/follow-redirects": {
-      "version": "1.15.6",
-      "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz",
-      "integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==",
-      "dev": true,
-      "funding": [
-        {
-          "type": "individual",
-          "url": "https://github.com/sponsors/RubenVerborgh"
-        }
-      ],
-      "engines": {
-        "node": ">=4.0"
-      },
-      "peerDependenciesMeta": {
-        "debug": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/foreground-child": {
-      "version": "3.1.1",
-      "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.1.1.tgz",
-      "integrity": "sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==",
-      "dev": true,
-      "dependencies": {
-        "cross-spawn": "^7.0.0",
-        "signal-exit": "^4.0.1"
-      },
-      "engines": {
-        "node": ">=14"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/isaacs"
-      }
-    },
-    "node_modules/foreground-child/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,
-      "engines": {
-        "node": ">=14"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/isaacs"
-      }
-    },
-    "node_modules/forever-agent": {
-      "version": "0.6.1",
-      "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz",
-      "integrity": "sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==",
-      "dev": true,
-      "engines": {
-        "node": "*"
-      }
-    },
-    "node_modules/form-data": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz",
-      "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==",
-      "dev": true,
-      "dependencies": {
-        "asynckit": "^0.4.0",
-        "combined-stream": "^1.0.8",
-        "mime-types": "^2.1.12"
-      },
-      "engines": {
-        "node": ">= 6"
-      }
-    },
-    "node_modules/fraction.js": {
-      "version": "4.3.7",
-      "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.7.tgz",
-      "integrity": "sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==",
-      "dev": true,
-      "engines": {
-        "node": "*"
-      },
-      "funding": {
-        "type": "patreon",
-        "url": "https://github.com/sponsors/rawify"
-      }
-    },
-    "node_modules/from": {
-      "version": "0.1.7",
-      "resolved": "https://registry.npmjs.org/from/-/from-0.1.7.tgz",
-      "integrity": "sha512-twe20eF1OxVxp/ML/kq2p1uc6KvFK/+vs8WjEbeKmV2He22MKm7YF2ANIt+EOqhJ5L3K/SuuPhk0hWQDjOM23g==",
-      "dev": true
-    },
-    "node_modules/fs-extra": {
-      "version": "9.1.0",
-      "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz",
-      "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==",
-      "dev": true,
-      "dependencies": {
-        "at-least-node": "^1.0.0",
-        "graceful-fs": "^4.2.0",
-        "jsonfile": "^6.0.1",
-        "universalify": "^2.0.0"
-      },
-      "engines": {
-        "node": ">=10"
-      }
-    },
-    "node_modules/fs.realpath": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
-      "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==",
-      "dev": true
-    },
-    "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,
-      "optional": true,
-      "os": [
-        "darwin"
-      ],
-      "engines": {
-        "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
-      }
-    },
-    "node_modules/function-bind": {
-      "version": "1.1.2",
-      "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
-      "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
-      "dev": true,
-      "funding": {
-        "url": "https://github.com/sponsors/ljharb"
-      }
-    },
-    "node_modules/get-func-name": {
-      "version": "2.0.2",
-      "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.2.tgz",
-      "integrity": "sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==",
-      "dev": true,
-      "engines": {
-        "node": "*"
-      }
-    },
-    "node_modules/get-intrinsic": {
-      "version": "1.2.4",
-      "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz",
-      "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==",
-      "dev": true,
-      "dependencies": {
-        "es-errors": "^1.3.0",
-        "function-bind": "^1.1.2",
-        "has-proto": "^1.0.1",
-        "has-symbols": "^1.0.3",
-        "hasown": "^2.0.0"
-      },
-      "engines": {
-        "node": ">= 0.4"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/ljharb"
-      }
-    },
-    "node_modules/get-stream": {
-      "version": "5.2.0",
-      "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz",
-      "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==",
-      "dev": true,
-      "dependencies": {
-        "pump": "^3.0.0"
-      },
-      "engines": {
-        "node": ">=8"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/getos": {
-      "version": "3.2.1",
-      "resolved": "https://registry.npmjs.org/getos/-/getos-3.2.1.tgz",
-      "integrity": "sha512-U56CfOK17OKgTVqozZjUKNdkfEv6jk5WISBJ8SHoagjE6L69zOwl3Z+O8myjY9MEW3i2HPWQBt/LTbCgcC973Q==",
-      "dev": true,
-      "dependencies": {
-        "async": "^3.2.0"
-      }
-    },
-    "node_modules/getpass": {
-      "version": "0.1.7",
-      "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz",
-      "integrity": "sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==",
-      "dev": true,
-      "dependencies": {
-        "assert-plus": "^1.0.0"
-      }
-    },
-    "node_modules/glob": {
-      "version": "10.3.12",
-      "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.12.tgz",
-      "integrity": "sha512-TCNv8vJ+xz4QiqTpfOJA7HvYv+tNIRHKfUWw/q+v2jdgN4ebz+KY9tGx5J4rHP0o84mNP+ApH66HRX8us3Khqg==",
-      "dev": true,
-      "dependencies": {
-        "foreground-child": "^3.1.0",
-        "jackspeak": "^2.3.6",
-        "minimatch": "^9.0.1",
-        "minipass": "^7.0.4",
-        "path-scurry": "^1.10.2"
-      },
-      "bin": {
-        "glob": "dist/esm/bin.mjs"
-      },
-      "engines": {
-        "node": ">=16 || 14 >=14.17"
-      },
-      "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,
-      "dependencies": {
-        "is-glob": "^4.0.3"
-      },
-      "engines": {
-        "node": ">=10.13.0"
-      }
-    },
-    "node_modules/global-dirs": {
-      "version": "3.0.1",
-      "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-3.0.1.tgz",
-      "integrity": "sha512-NBcGGFbBA9s1VzD41QXDG+3++t9Mn5t1FpLdhESY6oKY4gYTFpX4wO3sqGUa0Srjtbfj3szX0RnemmrVRUdULA==",
-      "dev": true,
-      "dependencies": {
-        "ini": "2.0.0"
-      },
-      "engines": {
-        "node": ">=10"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "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,
-      "dependencies": {
-        "type-fest": "^0.20.2"
-      },
-      "engines": {
-        "node": ">=8"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/globby": {
-      "version": "11.1.0",
-      "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz",
-      "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==",
-      "dev": true,
-      "dependencies": {
-        "array-union": "^2.1.0",
-        "dir-glob": "^3.0.1",
-        "fast-glob": "^3.2.9",
-        "ignore": "^5.2.0",
-        "merge2": "^1.4.1",
-        "slash": "^3.0.0"
-      },
-      "engines": {
-        "node": ">=10"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/gopd": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz",
-      "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==",
-      "dev": true,
-      "dependencies": {
-        "get-intrinsic": "^1.1.3"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/ljharb"
-      }
-    },
-    "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==",
-      "dev": true
-    },
-    "node_modules/graphemer": {
-      "version": "1.4.0",
-      "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz",
-      "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==",
-      "dev": true
-    },
-    "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==",
-      "dev": true,
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/has-property-descriptors": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz",
-      "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==",
-      "dev": true,
-      "dependencies": {
-        "es-define-property": "^1.0.0"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/ljharb"
-      }
-    },
-    "node_modules/has-proto": {
-      "version": "1.0.3",
-      "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz",
-      "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==",
-      "dev": true,
-      "engines": {
-        "node": ">= 0.4"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/ljharb"
-      }
-    },
-    "node_modules/has-symbols": {
-      "version": "1.0.3",
-      "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz",
-      "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==",
-      "dev": true,
-      "engines": {
-        "node": ">= 0.4"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/ljharb"
-      }
-    },
-    "node_modules/hasown": {
-      "version": "2.0.2",
-      "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
-      "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
-      "dev": true,
-      "dependencies": {
-        "function-bind": "^1.1.2"
-      },
-      "engines": {
-        "node": ">= 0.4"
-      }
-    },
-    "node_modules/he": {
-      "version": "1.2.0",
-      "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz",
-      "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==",
-      "dev": true,
-      "bin": {
-        "he": "bin/he"
-      }
-    },
-    "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,
-      "dependencies": {
-        "whatwg-encoding": "^3.1.1"
-      },
-      "engines": {
-        "node": ">=18"
-      }
-    },
-    "node_modules/html-escaper": {
-      "version": "2.0.2",
-      "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz",
-      "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==",
-      "dev": true
-    },
-    "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,
-      "dependencies": {
-        "agent-base": "^7.1.0",
-        "debug": "^4.3.4"
-      },
-      "engines": {
-        "node": ">= 14"
-      }
-    },
-    "node_modules/http-signature": {
-      "version": "1.3.6",
-      "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.3.6.tgz",
-      "integrity": "sha512-3adrsD6zqo4GsTqtO7FyrejHNv+NgiIfAfv68+jVlFmSr9OGy7zrxONceFRLKvnnZA5jbxQBX1u9PpB6Wi32Gw==",
-      "dev": true,
-      "dependencies": {
-        "assert-plus": "^1.0.0",
-        "jsprim": "^2.0.2",
-        "sshpk": "^1.14.1"
-      },
-      "engines": {
-        "node": ">=0.10"
-      }
-    },
-    "node_modules/https-proxy-agent": {
-      "version": "7.0.4",
-      "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.4.tgz",
-      "integrity": "sha512-wlwpilI7YdjSkWaQ/7omYBMTliDcmCN8OLihO6I9B86g06lMyAoqgoDpV0XqoaPOKj+0DIdAvnsWfyAAhmimcg==",
-      "dev": true,
-      "dependencies": {
-        "agent-base": "^7.0.2",
-        "debug": "4"
-      },
-      "engines": {
-        "node": ">= 14"
-      }
-    },
-    "node_modules/human-signals": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz",
-      "integrity": "sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==",
-      "dev": true,
-      "engines": {
-        "node": ">=8.12.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,
-      "dependencies": {
-        "safer-buffer": ">= 2.1.2 < 3.0.0"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/ieee754": {
-      "version": "1.2.1",
-      "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
-      "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==",
-      "dev": true,
-      "funding": [
-        {
-          "type": "github",
-          "url": "https://github.com/sponsors/feross"
-        },
-        {
-          "type": "patreon",
-          "url": "https://www.patreon.com/feross"
-        },
-        {
-          "type": "consulting",
-          "url": "https://feross.org/support"
-        }
-      ]
-    },
-    "node_modules/ignore": {
-      "version": "5.3.1",
-      "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz",
-      "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==",
-      "dev": true,
-      "engines": {
-        "node": ">= 4"
-      }
-    },
-    "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,
-      "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,
-      "engines": {
-        "node": ">=0.8.19"
-      }
-    },
-    "node_modules/indent-string": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz",
-      "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==",
-      "dev": true,
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/inflight": {
-      "version": "1.0.6",
-      "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
-      "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
-      "dev": true,
-      "dependencies": {
-        "once": "^1.3.0",
-        "wrappy": "1"
-      }
-    },
-    "node_modules/inherits": {
-      "version": "2.0.4",
-      "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
-      "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
-      "dev": true
-    },
-    "node_modules/ini": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/ini/-/ini-2.0.0.tgz",
-      "integrity": "sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA==",
-      "dev": true,
-      "engines": {
-        "node": ">=10"
-      }
-    },
-    "node_modules/is-binary-path": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
-      "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
-      "dev": true,
-      "dependencies": {
-        "binary-extensions": "^2.0.0"
-      },
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/is-buffer": {
-      "version": "2.0.5",
-      "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz",
-      "integrity": "sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==",
-      "dev": true,
-      "funding": [
-        {
-          "type": "github",
-          "url": "https://github.com/sponsors/feross"
-        },
-        {
-          "type": "patreon",
-          "url": "https://www.patreon.com/feross"
-        },
-        {
-          "type": "consulting",
-          "url": "https://feross.org/support"
-        }
-      ],
-      "engines": {
-        "node": ">=4"
-      }
-    },
-    "node_modules/is-ci": {
-      "version": "3.0.1",
-      "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-3.0.1.tgz",
-      "integrity": "sha512-ZYvCgrefwqoQ6yTyYUbQu64HsITZ3NfKX1lzaEYdkTDcfKzzCI/wthRRYKkdjHKFVgNiXKAKm65Zo1pk2as/QQ==",
-      "dev": true,
-      "dependencies": {
-        "ci-info": "^3.2.0"
-      },
-      "bin": {
-        "is-ci": "bin.js"
-      }
-    },
-    "node_modules/is-core-module": {
-      "version": "2.13.1",
-      "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz",
-      "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==",
-      "dev": true,
-      "dependencies": {
-        "hasown": "^2.0.0"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/ljharb"
-      }
-    },
-    "node_modules/is-extglob": {
-      "version": "2.1.1",
-      "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
-      "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
-      "dev": true,
-      "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,
-      "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==",
-      "dev": true,
-      "dependencies": {
-        "is-extglob": "^2.1.1"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/is-installed-globally": {
-      "version": "0.4.0",
-      "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.4.0.tgz",
-      "integrity": "sha512-iwGqO3J21aaSkC7jWnHP/difazwS7SFeIqxv6wEtLU8Y5KlzFTjyqcSIT0d8s4+dDhKytsk9PJZ2BkS5eZwQRQ==",
-      "dev": true,
-      "dependencies": {
-        "global-dirs": "^3.0.0",
-        "is-path-inside": "^3.0.2"
-      },
-      "engines": {
-        "node": ">=10"
-      },
-      "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==",
-      "dev": true,
-      "engines": {
-        "node": ">=0.12.0"
-      }
-    },
-    "node_modules/is-path-inside": {
-      "version": "3.0.3",
-      "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz",
-      "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==",
-      "dev": true,
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "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
-    },
-    "node_modules/is-stream": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz",
-      "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==",
-      "dev": true,
-      "engines": {
-        "node": ">=8"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/is-typedarray": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
-      "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==",
-      "dev": true
-    },
-    "node_modules/is-unicode-supported": {
-      "version": "0.1.0",
-      "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz",
-      "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==",
-      "dev": true,
-      "engines": {
-        "node": ">=10"
-      },
-      "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
-    },
-    "node_modules/isstream": {
-      "version": "0.1.2",
-      "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz",
-      "integrity": "sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==",
-      "dev": true
-    },
-    "node_modules/istanbul-lib-coverage": {
-      "version": "3.2.2",
-      "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz",
-      "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==",
-      "dev": true,
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/istanbul-lib-report": {
-      "version": "3.0.1",
-      "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz",
-      "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==",
-      "dev": true,
-      "dependencies": {
-        "istanbul-lib-coverage": "^3.0.0",
-        "make-dir": "^4.0.0",
-        "supports-color": "^7.1.0"
-      },
-      "engines": {
-        "node": ">=10"
-      }
-    },
-    "node_modules/istanbul-lib-report/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,
-      "dependencies": {
-        "has-flag": "^4.0.0"
-      },
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/istanbul-lib-source-maps": {
-      "version": "5.0.4",
-      "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-5.0.4.tgz",
-      "integrity": "sha512-wHOoEsNJTVltaJp8eVkm8w+GVkVNHT2YDYo53YdzQEL2gWm1hBX5cGFR9hQJtuGLebidVX7et3+dmDZrmclduw==",
-      "dev": true,
-      "dependencies": {
-        "@jridgewell/trace-mapping": "^0.3.23",
-        "debug": "^4.1.1",
-        "istanbul-lib-coverage": "^3.0.0"
-      },
-      "engines": {
-        "node": ">=10"
-      }
-    },
-    "node_modules/istanbul-reports": {
-      "version": "3.1.7",
-      "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.7.tgz",
-      "integrity": "sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==",
-      "dev": true,
-      "dependencies": {
-        "html-escaper": "^2.0.0",
-        "istanbul-lib-report": "^3.0.0"
-      },
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/jackspeak": {
-      "version": "2.3.6",
-      "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-2.3.6.tgz",
-      "integrity": "sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==",
-      "dev": true,
-      "dependencies": {
-        "@isaacs/cliui": "^8.0.2"
-      },
-      "engines": {
-        "node": ">=14"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/isaacs"
-      },
-      "optionalDependencies": {
-        "@pkgjs/parseargs": "^0.11.0"
-      }
-    },
-    "node_modules/jiti": {
-      "version": "1.21.0",
-      "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.0.tgz",
-      "integrity": "sha512-gFqAIbuKyyso/3G2qhiO2OM6shY6EPP/R0+mkDbyspxKazh8BXDC5FiFsUjlczgdNz/vfra0da2y+aHrusLG/Q==",
-      "dev": true,
-      "bin": {
-        "jiti": "bin/jiti.js"
-      }
-    },
-    "node_modules/joi": {
-      "version": "17.13.0",
-      "resolved": "https://registry.npmjs.org/joi/-/joi-17.13.0.tgz",
-      "integrity": "sha512-9qcrTyoBmFZRNHeVP4edKqIUEgFzq7MHvTNSDuHSqkpOPtiBkgNgcmTSqmiw1kw9tdKaiddvIDv/eCJDxmqWCA==",
-      "dev": true,
-      "dependencies": {
-        "@hapi/hoek": "^9.3.0",
-        "@hapi/topo": "^5.1.0",
-        "@sideway/address": "^4.1.5",
-        "@sideway/formula": "^3.0.1",
-        "@sideway/pinpoint": "^2.0.0"
-      }
-    },
-    "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,
-      "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,
-      "engines": {
-        "node": ">=14"
-      }
-    },
-    "node_modules/js-tokens": {
-      "version": "9.0.0",
-      "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-9.0.0.tgz",
-      "integrity": "sha512-WriZw1luRMlmV3LGJaR6QOJjWwgLUTf89OwT2lUOyjX2dJGBwgmIkbcz+7WFZjrZM635JOIR517++e/67CP9dQ==",
-      "dev": true
-    },
-    "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,
-      "dependencies": {
-        "argparse": "^2.0.1"
-      },
-      "bin": {
-        "js-yaml": "bin/js-yaml.js"
-      }
-    },
-    "node_modules/jsbn": {
-      "version": "0.1.1",
-      "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz",
-      "integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==",
-      "dev": true
-    },
-    "node_modules/jsdom": {
-      "version": "24.0.0",
-      "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-24.0.0.tgz",
-      "integrity": "sha512-UDS2NayCvmXSXVP6mpTj+73JnNQadZlr9N68189xib2tx5Mls7swlTNao26IoHv46BZJFvXygyRtyXd1feAk1A==",
-      "dev": true,
-      "dependencies": {
-        "cssstyle": "^4.0.1",
-        "data-urls": "^5.0.0",
-        "decimal.js": "^10.4.3",
-        "form-data": "^4.0.0",
-        "html-encoding-sniffer": "^4.0.0",
-        "http-proxy-agent": "^7.0.0",
-        "https-proxy-agent": "^7.0.2",
-        "is-potential-custom-element-name": "^1.0.1",
-        "nwsapi": "^2.2.7",
-        "parse5": "^7.1.2",
-        "rrweb-cssom": "^0.6.0",
-        "saxes": "^6.0.0",
-        "symbol-tree": "^3.2.4",
-        "tough-cookie": "^4.1.3",
-        "w3c-xmlserializer": "^5.0.0",
-        "webidl-conversions": "^7.0.0",
-        "whatwg-encoding": "^3.1.1",
-        "whatwg-mimetype": "^4.0.0",
-        "whatwg-url": "^14.0.0",
-        "ws": "^8.16.0",
-        "xml-name-validator": "^5.0.0"
-      },
-      "engines": {
-        "node": ">=18"
-      },
-      "peerDependencies": {
-        "canvas": "^2.11.2"
-      },
-      "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,
-      "engines": {
-        "node": ">=18"
-      }
-    },
-    "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
-    },
-    "node_modules/json-parse-even-better-errors": {
-      "version": "3.0.1",
-      "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-3.0.1.tgz",
-      "integrity": "sha512-aatBvbL26wVUCLmbWdCpeu9iF5wOyWpagiKkInA+kfws3sWdBrTnsvN2CKcyCYyUrc7rebNBlK6+kteg7ksecg==",
-      "dev": true,
-      "engines": {
-        "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
-      }
-    },
-    "node_modules/json-schema": {
-      "version": "0.4.0",
-      "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz",
-      "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==",
-      "dev": true
-    },
-    "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
-    },
-    "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
-    },
-    "node_modules/json-stringify-safe": {
-      "version": "5.0.1",
-      "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
-      "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==",
-      "dev": true
-    },
-    "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,
-      "dependencies": {
-        "universalify": "^2.0.0"
-      },
-      "optionalDependencies": {
-        "graceful-fs": "^4.1.6"
-      }
-    },
-    "node_modules/jsprim": {
-      "version": "2.0.2",
-      "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-2.0.2.tgz",
-      "integrity": "sha512-gqXddjPqQ6G40VdnI6T6yObEC+pDNvyP95wdQhkWkg7crHH3km5qP1FsOXEkzEQwnz6gz5qGTn1c2Y52wP3OyQ==",
-      "dev": true,
-      "engines": [
-        "node >=0.6.0"
-      ],
-      "dependencies": {
-        "assert-plus": "1.0.0",
-        "extsprintf": "1.3.0",
-        "json-schema": "0.4.0",
-        "verror": "1.10.0"
-      }
-    },
-    "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,
-      "dependencies": {
-        "json-buffer": "3.0.1"
-      }
-    },
-    "node_modules/lazy-ass": {
-      "version": "1.6.0",
-      "resolved": "https://registry.npmjs.org/lazy-ass/-/lazy-ass-1.6.0.tgz",
-      "integrity": "sha512-cc8oEVoctTvsFZ/Oje/kGnHbpWHYBe8IAJe4C0QNc3t8uM/0Y8+erSz/7Y1ALuXTEZTMvxXwO6YbX1ey3ujiZw==",
-      "dev": true,
-      "engines": {
-        "node": "> 0.8"
-      }
-    },
-    "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,
-      "dependencies": {
-        "prelude-ls": "^1.2.1",
-        "type-check": "~0.4.0"
-      },
-      "engines": {
-        "node": ">= 0.8.0"
-      }
-    },
-    "node_modules/lilconfig": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz",
-      "integrity": "sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==",
-      "dev": true,
-      "engines": {
-        "node": ">=10"
-      }
-    },
-    "node_modules/lines-and-columns": {
-      "version": "1.2.4",
-      "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz",
-      "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==",
-      "dev": true
-    },
-    "node_modules/listr2": {
-      "version": "3.14.0",
-      "resolved": "https://registry.npmjs.org/listr2/-/listr2-3.14.0.tgz",
-      "integrity": "sha512-TyWI8G99GX9GjE54cJ+RrNMcIFBfwMPxc3XTFiAYGN4s10hWROGtOg7+O6u6LE3mNkyld7RSLE6nrKBvTfcs3g==",
-      "dev": true,
-      "dependencies": {
-        "cli-truncate": "^2.1.0",
-        "colorette": "^2.0.16",
-        "log-update": "^4.0.0",
-        "p-map": "^4.0.0",
-        "rfdc": "^1.3.0",
-        "rxjs": "^7.5.1",
-        "through": "^2.3.8",
-        "wrap-ansi": "^7.0.0"
-      },
-      "engines": {
-        "node": ">=10.0.0"
-      },
-      "peerDependencies": {
-        "enquirer": ">= 2.3.0 < 3"
-      },
-      "peerDependenciesMeta": {
-        "enquirer": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/listr2/node_modules/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,
-      "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/local-pkg": {
-      "version": "0.5.0",
-      "resolved": "https://registry.npmjs.org/local-pkg/-/local-pkg-0.5.0.tgz",
-      "integrity": "sha512-ok6z3qlYyCDS4ZEU27HaU6x/xZa9Whf8jD4ptH5UZTQYZVYeb9bnZ3ojVhiJNLiXK1Hfc0GNbLXcmZ5plLDDBg==",
-      "dev": true,
-      "dependencies": {
-        "mlly": "^1.4.2",
-        "pkg-types": "^1.0.3"
-      },
-      "engines": {
-        "node": ">=14"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/antfu"
-      }
-    },
-    "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,
-      "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
-    },
-    "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
-    },
-    "node_modules/lodash.once": {
-      "version": "4.1.1",
-      "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz",
-      "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==",
-      "dev": true
-    },
-    "node_modules/log-symbols": {
-      "version": "4.1.0",
-      "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz",
-      "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==",
-      "dev": true,
-      "dependencies": {
-        "chalk": "^4.1.0",
-        "is-unicode-supported": "^0.1.0"
-      },
-      "engines": {
-        "node": ">=10"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/log-update": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/log-update/-/log-update-4.0.0.tgz",
-      "integrity": "sha512-9fkkDevMefjg0mmzWFBW8YkFP91OrizzkW3diF7CpG+S2EYdy4+TVfGwz1zeF8x7hCx1ovSPTOE9Ngib74qqUg==",
-      "dev": true,
-      "dependencies": {
-        "ansi-escapes": "^4.3.0",
-        "cli-cursor": "^3.1.0",
-        "slice-ansi": "^4.0.0",
-        "wrap-ansi": "^6.2.0"
-      },
-      "engines": {
-        "node": ">=10"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/log-update/node_modules/slice-ansi": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz",
-      "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==",
-      "dev": true,
-      "dependencies": {
-        "ansi-styles": "^4.0.0",
-        "astral-regex": "^2.0.0",
-        "is-fullwidth-code-point": "^3.0.0"
-      },
-      "engines": {
-        "node": ">=10"
-      },
-      "funding": {
-        "url": "https://github.com/chalk/slice-ansi?sponsor=1"
-      }
-    },
-    "node_modules/log-update/node_modules/wrap-ansi": {
-      "version": "6.2.0",
-      "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz",
-      "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==",
-      "dev": true,
-      "dependencies": {
-        "ansi-styles": "^4.0.0",
-        "string-width": "^4.1.0",
-        "strip-ansi": "^6.0.0"
-      },
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/loupe": {
-      "version": "2.3.7",
-      "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.7.tgz",
-      "integrity": "sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==",
-      "dev": true,
-      "dependencies": {
-        "get-func-name": "^2.0.1"
-      }
-    },
-    "node_modules/lru-cache": {
-      "version": "10.2.0",
-      "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.2.0.tgz",
-      "integrity": "sha512-2bIM8x+VAf6JT4bKAljS1qUWgMsqZRPGJS6FSahIMPVvctcNhyVp7AJu7quxOW9jwkryBReKZY5tY5JYv2n/7Q==",
-      "dev": true,
-      "engines": {
-        "node": "14 || >=16.14"
-      }
-    },
-    "node_modules/magic-string": {
-      "version": "0.30.10",
-      "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.10.tgz",
-      "integrity": "sha512-iIRwTIf0QKV3UAnYK4PU8uiEc4SRh5jX0mwpIwETPpHdhVM4f53RSwS/vXvN1JhGX+Cs7B8qIq3d6AH49O5fAQ==",
-      "dependencies": {
-        "@jridgewell/sourcemap-codec": "^1.4.15"
-      }
-    },
-    "node_modules/magicast": {
-      "version": "0.3.4",
-      "resolved": "https://registry.npmjs.org/magicast/-/magicast-0.3.4.tgz",
-      "integrity": "sha512-TyDF/Pn36bBji9rWKHlZe+PZb6Mx5V8IHCSxk7X4aljM4e/vyDvZZYwHewdVaqiA0nb3ghfHU/6AUpDxWoER2Q==",
-      "dev": true,
-      "dependencies": {
-        "@babel/parser": "^7.24.4",
-        "@babel/types": "^7.24.0",
-        "source-map-js": "^1.2.0"
-      }
-    },
-    "node_modules/make-dir": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz",
-      "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==",
-      "dev": true,
-      "dependencies": {
-        "semver": "^7.5.3"
-      },
-      "engines": {
-        "node": ">=10"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/map-stream": {
-      "version": "0.1.0",
-      "resolved": "https://registry.npmjs.org/map-stream/-/map-stream-0.1.0.tgz",
-      "integrity": "sha512-CkYQrPYZfWnu/DAmVCpTSX/xHpKZ80eKh2lAkyA6AJTef6bW+6JpbQZN5rofum7da+SyN1bi5ctTm+lTfcCW3g==",
-      "dev": true
-    },
-    "node_modules/memorystream": {
-      "version": "0.3.1",
-      "resolved": "https://registry.npmjs.org/memorystream/-/memorystream-0.3.1.tgz",
-      "integrity": "sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw==",
-      "dev": true,
-      "engines": {
-        "node": ">= 0.10.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==",
-      "dev": true
-    },
-    "node_modules/merge2": {
-      "version": "1.4.1",
-      "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
-      "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==",
-      "dev": true,
-      "engines": {
-        "node": ">= 8"
-      }
-    },
-    "node_modules/micromatch": {
-      "version": "4.0.5",
-      "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz",
-      "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==",
-      "dev": true,
-      "dependencies": {
-        "braces": "^3.0.2",
-        "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==",
-      "dev": true,
-      "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==",
-      "dev": true,
-      "dependencies": {
-        "mime-db": "1.52.0"
-      },
-      "engines": {
-        "node": ">= 0.6"
-      }
-    },
-    "node_modules/mimic-fn": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz",
-      "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==",
-      "dev": true,
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/minimatch": {
-      "version": "9.0.4",
-      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.4.tgz",
-      "integrity": "sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==",
-      "dev": true,
-      "dependencies": {
-        "brace-expansion": "^2.0.1"
-      },
-      "engines": {
-        "node": ">=16 || 14 >=14.17"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/isaacs"
-      }
-    },
-    "node_modules/minimist": {
-      "version": "1.2.8",
-      "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz",
-      "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==",
-      "dev": true,
-      "funding": {
-        "url": "https://github.com/sponsors/ljharb"
-      }
-    },
-    "node_modules/minipass": {
-      "version": "7.0.4",
-      "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz",
-      "integrity": "sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==",
-      "dev": true,
-      "engines": {
-        "node": ">=16 || 14 >=14.17"
-      }
-    },
-    "node_modules/mlly": {
-      "version": "1.6.1",
-      "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.6.1.tgz",
-      "integrity": "sha512-vLgaHvaeunuOXHSmEbZ9izxPx3USsk8KCQ8iC+aTlp5sKRSoZvwhHh5L9VbKSaVC6sJDqbyohIS76E2VmHIPAA==",
-      "dev": true,
-      "dependencies": {
-        "acorn": "^8.11.3",
-        "pathe": "^1.1.2",
-        "pkg-types": "^1.0.3",
-        "ufo": "^1.3.2"
-      }
-    },
-    "node_modules/ms": {
-      "version": "2.1.2",
-      "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
-      "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
-      "dev": true
-    },
-    "node_modules/muggle-string": {
-      "version": "0.4.1",
-      "resolved": "https://registry.npmjs.org/muggle-string/-/muggle-string-0.4.1.tgz",
-      "integrity": "sha512-VNTrAak/KhO2i8dqqnqnAHOa3cYBwXEZe9h+D5h/1ZqFSTEFHdM65lR7RoIqq3tBBYavsOXV84NoHXZ0AkPyqQ==",
-      "dev": true
-    },
-    "node_modules/mz": {
-      "version": "2.7.0",
-      "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz",
-      "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==",
-      "dev": true,
-      "dependencies": {
-        "any-promise": "^1.0.0",
-        "object-assign": "^4.0.1",
-        "thenify-all": "^1.0.0"
-      }
-    },
-    "node_modules/nanoid": {
-      "version": "3.3.7",
-      "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz",
-      "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==",
-      "funding": [
-        {
-          "type": "github",
-          "url": "https://github.com/sponsors/ai"
-        }
-      ],
-      "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
-    },
-    "node_modules/node-releases": {
-      "version": "2.0.14",
-      "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz",
-      "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==",
-      "dev": true
-    },
-    "node_modules/nopt": {
-      "version": "7.2.0",
-      "resolved": "https://registry.npmjs.org/nopt/-/nopt-7.2.0.tgz",
-      "integrity": "sha512-CVDtwCdhYIvnAzFoJ6NJ6dX3oga9/HyciQDnG1vQDjSLMeKLJ4A93ZqYKDrgYSr1FBY5/hMYC+2VCi24pgpkGA==",
-      "dev": true,
-      "dependencies": {
-        "abbrev": "^2.0.0"
-      },
-      "bin": {
-        "nopt": "bin/nopt.js"
-      },
-      "engines": {
-        "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
-      }
-    },
-    "node_modules/normalize-path": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
-      "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
-      "dev": true,
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/normalize-range": {
-      "version": "0.1.2",
-      "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz",
-      "integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==",
-      "dev": true,
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/npm-normalize-package-bin": {
-      "version": "3.0.1",
-      "resolved": "https://registry.npmjs.org/npm-normalize-package-bin/-/npm-normalize-package-bin-3.0.1.tgz",
-      "integrity": "sha512-dMxCf+zZ+3zeQZXKxmyuCKlIDPGuv8EF940xbkC4kQVDTtqoh6rJFO+JTKSA6/Rwi0getWmtuy4Itup0AMcaDQ==",
-      "dev": true,
-      "engines": {
-        "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
-      }
-    },
-    "node_modules/npm-run-all2": {
-      "version": "6.1.2",
-      "resolved": "https://registry.npmjs.org/npm-run-all2/-/npm-run-all2-6.1.2.tgz",
-      "integrity": "sha512-WwwnS8Ft+RpXve6T2EIEVpFLSqN+ORHRvgNk3H9N62SZXjmzKoRhMFg3I17TK3oMaAEr+XFbRirWS2Fn3BCPSg==",
-      "dev": true,
-      "dependencies": {
-        "ansi-styles": "^6.2.1",
-        "cross-spawn": "^7.0.3",
-        "memorystream": "^0.3.1",
-        "minimatch": "^9.0.0",
-        "pidtree": "^0.6.0",
-        "read-package-json-fast": "^3.0.2",
-        "shell-quote": "^1.7.3"
-      },
-      "bin": {
-        "npm-run-all": "bin/npm-run-all/index.js",
-        "npm-run-all2": "bin/npm-run-all/index.js",
-        "run-p": "bin/run-p/index.js",
-        "run-s": "bin/run-s/index.js"
-      },
-      "engines": {
-        "node": "^14.18.0 || >=16.0.0",
-        "npm": ">= 8"
-      }
-    },
-    "node_modules/npm-run-all2/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,
-      "engines": {
-        "node": ">=12"
-      },
-      "funding": {
-        "url": "https://github.com/chalk/ansi-styles?sponsor=1"
-      }
-    },
-    "node_modules/npm-run-path": {
-      "version": "4.0.1",
-      "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz",
-      "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==",
-      "dev": true,
-      "dependencies": {
-        "path-key": "^3.0.0"
-      },
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "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,
-      "dependencies": {
-        "boolbase": "^1.0.0"
-      },
-      "funding": {
-        "url": "https://github.com/fb55/nth-check?sponsor=1"
-      }
-    },
-    "node_modules/nwsapi": {
-      "version": "2.2.9",
-      "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.9.tgz",
-      "integrity": "sha512-2f3F0SEEer8bBu0dsNCFF50N0cTThV1nWFYcEYFZttdW0lDAoybv9cQoK7X7/68Z89S7FoRrVjP1LPX4XRf9vg==",
-      "dev": true
-    },
-    "node_modules/object-assign": {
-      "version": "4.1.1",
-      "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
-      "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==",
-      "dev": true,
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/object-hash": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz",
-      "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==",
-      "dev": true,
-      "engines": {
-        "node": ">= 6"
-      }
-    },
-    "node_modules/object-inspect": {
-      "version": "1.13.1",
-      "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz",
-      "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==",
-      "dev": true,
-      "funding": {
-        "url": "https://github.com/sponsors/ljharb"
-      }
-    },
-    "node_modules/once": {
-      "version": "1.4.0",
-      "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
-      "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
-      "dev": true,
-      "dependencies": {
-        "wrappy": "1"
-      }
-    },
-    "node_modules/onetime": {
-      "version": "5.1.2",
-      "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz",
-      "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==",
-      "dev": true,
-      "dependencies": {
-        "mimic-fn": "^2.1.0"
-      },
-      "engines": {
-        "node": ">=6"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/optionator": {
-      "version": "0.9.3",
-      "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz",
-      "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==",
-      "dev": true,
-      "dependencies": {
-        "@aashutoshrathi/word-wrap": "^1.2.3",
-        "deep-is": "^0.1.3",
-        "fast-levenshtein": "^2.0.6",
-        "levn": "^0.4.1",
-        "prelude-ls": "^1.2.1",
-        "type-check": "^0.4.0"
-      },
-      "engines": {
-        "node": ">= 0.8.0"
-      }
-    },
-    "node_modules/ospath": {
-      "version": "1.2.2",
-      "resolved": "https://registry.npmjs.org/ospath/-/ospath-1.2.2.tgz",
-      "integrity": "sha512-o6E5qJV5zkAbIDNhGSIlyOhScKXgQrSRMilfph0clDfM0nEnBOlKlH4sWDmG95BW/CvwNz0vmm7dJVtU2KlMiA==",
-      "dev": true
-    },
-    "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,
-      "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,
-      "dependencies": {
-        "p-limit": "^3.0.2"
-      },
-      "engines": {
-        "node": ">=10"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/p-map": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz",
-      "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==",
-      "dev": true,
-      "dependencies": {
-        "aggregate-error": "^3.0.0"
-      },
-      "engines": {
-        "node": ">=10"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "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,
-      "dependencies": {
-        "callsites": "^3.0.0"
-      },
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/parse5": {
-      "version": "7.1.2",
-      "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.1.2.tgz",
-      "integrity": "sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==",
-      "dev": true,
-      "dependencies": {
-        "entities": "^4.4.0"
-      },
-      "funding": {
-        "url": "https://github.com/inikulin/parse5?sponsor=1"
-      }
-    },
-    "node_modules/path-browserify": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz",
-      "integrity": "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==",
-      "dev": true
-    },
-    "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,
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/path-is-absolute": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
-      "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==",
-      "dev": true,
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "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,
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/path-parse": {
-      "version": "1.0.7",
-      "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
-      "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
-      "dev": true
-    },
-    "node_modules/path-scurry": {
-      "version": "1.10.2",
-      "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.10.2.tgz",
-      "integrity": "sha512-7xTavNy5RQXnsjANvVvMkEjvloOinkAjv/Z6Ildz9v2RinZ4SBKTWFOVRbaF8p0vpHnyjV/UwNDdKuUv6M5qcA==",
-      "dev": true,
-      "dependencies": {
-        "lru-cache": "^10.2.0",
-        "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0"
-      },
-      "engines": {
-        "node": ">=16 || 14 >=14.17"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/isaacs"
-      }
-    },
-    "node_modules/path-type": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz",
-      "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==",
-      "dev": true,
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "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
-    },
-    "node_modules/pathval": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz",
-      "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==",
-      "dev": true,
-      "engines": {
-        "node": "*"
-      }
-    },
-    "node_modules/pause-stream": {
-      "version": "0.0.11",
-      "resolved": "https://registry.npmjs.org/pause-stream/-/pause-stream-0.0.11.tgz",
-      "integrity": "sha512-e3FBlXLmN/D1S+zHzanP4E/4Z60oFAa3O051qt1pxa7DEJWKAyil6upYVXCWadEnuoqa4Pkc9oUx9zsxYeRv8A==",
-      "dev": true,
-      "dependencies": {
-        "through": "~2.3"
-      }
-    },
-    "node_modules/pend": {
-      "version": "1.2.0",
-      "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz",
-      "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==",
-      "dev": true
-    },
-    "node_modules/performance-now": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
-      "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==",
-      "dev": true
-    },
-    "node_modules/picocolors": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
-      "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ=="
-    },
-    "node_modules/picomatch": {
-      "version": "2.3.1",
-      "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
-      "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
-      "dev": true,
-      "engines": {
-        "node": ">=8.6"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/jonschlinkert"
-      }
-    },
-    "node_modules/pidtree": {
-      "version": "0.6.0",
-      "resolved": "https://registry.npmjs.org/pidtree/-/pidtree-0.6.0.tgz",
-      "integrity": "sha512-eG2dWTVw5bzqGRztnHExczNxt5VGsE6OwTeCG3fdUf9KBsZzO3R5OIIIzWR+iZA0NtZ+RDVdaoE2dK1cn6jH4g==",
-      "dev": true,
-      "bin": {
-        "pidtree": "bin/pidtree.js"
-      },
-      "engines": {
-        "node": ">=0.10"
-      }
-    },
-    "node_modules/pify": {
-      "version": "2.3.0",
-      "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
-      "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==",
-      "dev": true,
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/pinia": {
-      "version": "2.1.7",
-      "resolved": "https://registry.npmjs.org/pinia/-/pinia-2.1.7.tgz",
-      "integrity": "sha512-+C2AHFtcFqjPih0zpYuvof37SFxMQ7OEG2zV9jRI12i9BOy3YQVAHwdKtyyc8pDcDyIc33WCIsZaCFWU7WWxGQ==",
-      "dependencies": {
-        "@vue/devtools-api": "^6.5.0",
-        "vue-demi": ">=0.14.5"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/posva"
-      },
-      "peerDependencies": {
-        "@vue/composition-api": "^1.4.0",
-        "typescript": ">=4.4.4",
-        "vue": "^2.6.14 || ^3.3.0"
-      },
-      "peerDependenciesMeta": {
-        "@vue/composition-api": {
-          "optional": true
-        },
-        "typescript": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/pinia/node_modules/vue-demi": {
-      "version": "0.14.7",
-      "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.7.tgz",
-      "integrity": "sha512-EOG8KXDQNwkJILkx/gPcoL/7vH+hORoBaKgGe+6W7VFMvCYJfmF2dGbvgDroVnI8LU7/kTu8mbjRZGBU1z9NTA==",
-      "hasInstallScript": true,
-      "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/pirates": {
-      "version": "4.0.6",
-      "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.6.tgz",
-      "integrity": "sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==",
-      "dev": true,
-      "engines": {
-        "node": ">= 6"
-      }
-    },
-    "node_modules/pkg-types": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-1.1.0.tgz",
-      "integrity": "sha512-/RpmvKdxKf8uILTtoOhAgf30wYbP2Qw+L9p3Rvshx1JZVX+XQNZQFjlbmGHEGIm4CkVPlSn+NXmIM8+9oWQaSA==",
-      "dev": true,
-      "dependencies": {
-        "confbox": "^0.1.7",
-        "mlly": "^1.6.1",
-        "pathe": "^1.1.2"
-      }
-    },
-    "node_modules/postcss": {
-      "version": "8.4.38",
-      "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.38.tgz",
-      "integrity": "sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==",
-      "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"
-        }
-      ],
-      "dependencies": {
-        "nanoid": "^3.3.7",
-        "picocolors": "^1.0.0",
-        "source-map-js": "^1.2.0"
-      },
-      "engines": {
-        "node": "^10 || ^12 || >=14"
-      }
-    },
-    "node_modules/postcss-import": {
-      "version": "15.1.0",
-      "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-15.1.0.tgz",
-      "integrity": "sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==",
-      "dev": true,
-      "dependencies": {
-        "postcss-value-parser": "^4.0.0",
-        "read-cache": "^1.0.0",
-        "resolve": "^1.1.7"
-      },
-      "engines": {
-        "node": ">=14.0.0"
-      },
-      "peerDependencies": {
-        "postcss": "^8.0.0"
-      }
-    },
-    "node_modules/postcss-js": {
-      "version": "4.0.1",
-      "resolved": "https://registry.npmjs.org/postcss-js/-/postcss-js-4.0.1.tgz",
-      "integrity": "sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==",
-      "dev": true,
-      "dependencies": {
-        "camelcase-css": "^2.0.1"
-      },
-      "engines": {
-        "node": "^12 || ^14 || >= 16"
-      },
-      "funding": {
-        "type": "opencollective",
-        "url": "https://opencollective.com/postcss/"
-      },
-      "peerDependencies": {
-        "postcss": "^8.4.21"
-      }
-    },
-    "node_modules/postcss-load-config": {
-      "version": "4.0.2",
-      "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-4.0.2.tgz",
-      "integrity": "sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ==",
-      "dev": true,
-      "funding": [
-        {
-          "type": "opencollective",
-          "url": "https://opencollective.com/postcss/"
-        },
-        {
-          "type": "github",
-          "url": "https://github.com/sponsors/ai"
-        }
-      ],
-      "dependencies": {
-        "lilconfig": "^3.0.0",
-        "yaml": "^2.3.4"
-      },
-      "engines": {
-        "node": ">= 14"
-      },
-      "peerDependencies": {
-        "postcss": ">=8.0.9",
-        "ts-node": ">=9.0.0"
-      },
-      "peerDependenciesMeta": {
-        "postcss": {
-          "optional": true
-        },
-        "ts-node": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/postcss-load-config/node_modules/lilconfig": {
-      "version": "3.1.1",
-      "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.1.tgz",
-      "integrity": "sha512-O18pf7nyvHTckunPWCV1XUNXU1piu01y2b7ATJ0ppkUkk8ocqVWBrYjJBCwHDjD/ZWcfyrA0P4gKhzWGi5EINQ==",
-      "dev": true,
-      "engines": {
-        "node": ">=14"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/antonk52"
-      }
-    },
-    "node_modules/postcss-nested": {
-      "version": "6.0.1",
-      "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.0.1.tgz",
-      "integrity": "sha512-mEp4xPMi5bSWiMbsgoPfcP74lsWLHkQbZc3sY+jWYd65CUwXrUaTp0fmNpa01ZcETKlIgUdFN/MpS2xZtqL9dQ==",
-      "dev": true,
-      "dependencies": {
-        "postcss-selector-parser": "^6.0.11"
-      },
-      "engines": {
-        "node": ">=12.0"
-      },
-      "funding": {
-        "type": "opencollective",
-        "url": "https://opencollective.com/postcss/"
-      },
-      "peerDependencies": {
-        "postcss": "^8.2.14"
-      }
-    },
-    "node_modules/postcss-selector-parser": {
-      "version": "6.0.16",
-      "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.16.tgz",
-      "integrity": "sha512-A0RVJrX+IUkVZbW3ClroRWurercFhieevHB38sr2+l9eUClMqome3LmEmnhlNy+5Mr2EYN6B2Kaw9wYdd+VHiw==",
-      "dev": true,
-      "dependencies": {
-        "cssesc": "^3.0.0",
-        "util-deprecate": "^1.0.2"
-      },
-      "engines": {
-        "node": ">=4"
-      }
-    },
-    "node_modules/postcss-value-parser": {
-      "version": "4.2.0",
-      "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz",
-      "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==",
-      "dev": true
-    },
-    "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,
-      "engines": {
-        "node": ">= 0.8.0"
-      }
-    },
-    "node_modules/prettier": {
-      "version": "3.2.5",
-      "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.2.5.tgz",
-      "integrity": "sha512-3/GWa9aOC0YeD7LUfvOG2NiDyhOWRvt1k+rcKhOuYnMY24iiCphgneUfJDyFXd6rZCAnuLBv6UeAULtrhT/F4A==",
-      "dev": 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,
-      "dependencies": {
-        "fast-diff": "^1.1.2"
-      },
-      "engines": {
-        "node": ">=6.0.0"
-      }
-    },
-    "node_modules/pretty-bytes": {
-      "version": "5.6.0",
-      "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.6.0.tgz",
-      "integrity": "sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg==",
-      "dev": true,
-      "engines": {
-        "node": ">=6"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/pretty-format": {
-      "version": "29.7.0",
-      "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz",
-      "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==",
-      "dev": true,
-      "dependencies": {
-        "@jest/schemas": "^29.6.3",
-        "ansi-styles": "^5.0.0",
-        "react-is": "^18.0.0"
-      },
-      "engines": {
-        "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
-      }
-    },
-    "node_modules/pretty-format/node_modules/ansi-styles": {
-      "version": "5.2.0",
-      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
-      "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
-      "dev": true,
-      "engines": {
-        "node": ">=10"
-      },
-      "funding": {
-        "url": "https://github.com/chalk/ansi-styles?sponsor=1"
-      }
-    },
-    "node_modules/process": {
-      "version": "0.11.10",
-      "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz",
-      "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==",
-      "dev": true,
-      "engines": {
-        "node": ">= 0.6.0"
-      }
-    },
-    "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
-    },
-    "node_modules/proxy-from-env": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
-      "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==",
-      "dev": true
-    },
-    "node_modules/ps-tree": {
-      "version": "1.2.0",
-      "resolved": "https://registry.npmjs.org/ps-tree/-/ps-tree-1.2.0.tgz",
-      "integrity": "sha512-0VnamPPYHl4uaU/nSFeZZpR21QAWRz+sRv4iW9+v/GS/J5U5iZB5BNN6J0RMoOvdx2gWM2+ZFMIm58q24e4UYA==",
-      "dev": true,
-      "dependencies": {
-        "event-stream": "=3.3.4"
-      },
-      "bin": {
-        "ps-tree": "bin/ps-tree.js"
-      },
-      "engines": {
-        "node": ">= 0.10"
-      }
-    },
-    "node_modules/psl": {
-      "version": "1.9.0",
-      "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz",
-      "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==",
-      "dev": true
-    },
-    "node_modules/pump": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
-      "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==",
-      "dev": true,
-      "dependencies": {
-        "end-of-stream": "^1.1.0",
-        "once": "^1.3.1"
-      }
-    },
-    "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,
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/qs": {
-      "version": "6.10.4",
-      "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.4.tgz",
-      "integrity": "sha512-OQiU+C+Ds5qiH91qh/mg0w+8nwQuLjM4F4M/PbmhDOoYehPh+Fb0bDjtR1sOvy7YKxvj28Y/M0PhP5uVX0kB+g==",
-      "dev": true,
-      "dependencies": {
-        "side-channel": "^1.0.4"
-      },
-      "engines": {
-        "node": ">=0.6"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/ljharb"
-      }
-    },
-    "node_modules/querystringify": {
-      "version": "2.2.0",
-      "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz",
-      "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==",
-      "dev": true
-    },
-    "node_modules/queue-microtask": {
-      "version": "1.2.3",
-      "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
-      "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==",
-      "dev": true,
-      "funding": [
-        {
-          "type": "github",
-          "url": "https://github.com/sponsors/feross"
-        },
-        {
-          "type": "patreon",
-          "url": "https://www.patreon.com/feross"
-        },
-        {
-          "type": "consulting",
-          "url": "https://feross.org/support"
-        }
-      ]
-    },
-    "node_modules/react-is": {
-      "version": "18.2.0",
-      "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz",
-      "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==",
-      "dev": true
-    },
-    "node_modules/read-cache": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz",
-      "integrity": "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==",
-      "dev": true,
-      "dependencies": {
-        "pify": "^2.3.0"
-      }
-    },
-    "node_modules/read-package-json-fast": {
-      "version": "3.0.2",
-      "resolved": "https://registry.npmjs.org/read-package-json-fast/-/read-package-json-fast-3.0.2.tgz",
-      "integrity": "sha512-0J+Msgym3vrLOUB3hzQCuZHII0xkNGCtz/HJH9xZshwv9DbDwkw1KaE3gx/e2J5rpEY5rtOy6cyhKOPrkP7FZw==",
-      "dev": true,
-      "dependencies": {
-        "json-parse-even-better-errors": "^3.0.0",
-        "npm-normalize-package-bin": "^3.0.0"
-      },
-      "engines": {
-        "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
-      }
-    },
-    "node_modules/readdirp": {
-      "version": "3.6.0",
-      "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
-      "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
-      "dev": true,
-      "dependencies": {
-        "picomatch": "^2.2.1"
-      },
-      "engines": {
-        "node": ">=8.10.0"
-      }
-    },
-    "node_modules/request-progress": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/request-progress/-/request-progress-3.0.0.tgz",
-      "integrity": "sha512-MnWzEHHaxHO2iWiQuHrUPBi/1WeBf5PkxQqNyNvLl9VAYSdXkP8tQ3pBSeCPD+yw0v0Aq1zosWLz0BdeXpWwZg==",
-      "dev": true,
-      "dependencies": {
-        "throttleit": "^1.0.0"
-      }
-    },
-    "node_modules/requires-port": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz",
-      "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==",
-      "dev": true
-    },
-    "node_modules/resolve": {
-      "version": "1.22.8",
-      "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz",
-      "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==",
-      "dev": true,
-      "dependencies": {
-        "is-core-module": "^2.13.0",
-        "path-parse": "^1.0.7",
-        "supports-preserve-symlinks-flag": "^1.0.0"
-      },
-      "bin": {
-        "resolve": "bin/resolve"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/ljharb"
-      }
-    },
-    "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,
-      "engines": {
-        "node": ">=4"
-      }
-    },
-    "node_modules/restore-cursor": {
-      "version": "3.1.0",
-      "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz",
-      "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==",
-      "dev": true,
-      "dependencies": {
-        "onetime": "^5.1.0",
-        "signal-exit": "^3.0.2"
-      },
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/reusify": {
-      "version": "1.0.4",
-      "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz",
-      "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==",
-      "dev": true,
-      "engines": {
-        "iojs": ">=1.0.0",
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/rfdc": {
-      "version": "1.3.1",
-      "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.3.1.tgz",
-      "integrity": "sha512-r5a3l5HzYlIC68TpmYKlxWjmOP6wiPJ1vWv2HeLhNsRZMrCkxeqxiHlQ21oXmQ4F3SiryXBHhAD7JZqvOJjFmg==",
-      "dev": true
-    },
-    "node_modules/rimraf": {
-      "version": "3.0.2",
-      "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
-      "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
-      "dev": true,
-      "dependencies": {
-        "glob": "^7.1.3"
-      },
-      "bin": {
-        "rimraf": "bin.js"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/isaacs"
-      }
-    },
-    "node_modules/rimraf/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,
-      "dependencies": {
-        "balanced-match": "^1.0.0",
-        "concat-map": "0.0.1"
-      }
-    },
-    "node_modules/rimraf/node_modules/glob": {
-      "version": "7.2.3",
-      "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
-      "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
-      "dev": true,
-      "dependencies": {
-        "fs.realpath": "^1.0.0",
-        "inflight": "^1.0.4",
-        "inherits": "2",
-        "minimatch": "^3.1.1",
-        "once": "^1.3.0",
-        "path-is-absolute": "^1.0.0"
-      },
-      "engines": {
-        "node": "*"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/isaacs"
-      }
-    },
-    "node_modules/rimraf/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,
-      "dependencies": {
-        "brace-expansion": "^1.1.7"
-      },
-      "engines": {
-        "node": "*"
-      }
-    },
-    "node_modules/rollup": {
-      "version": "4.16.4",
-      "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.16.4.tgz",
-      "integrity": "sha512-kuaTJSUbz+Wsb2ATGvEknkI12XV40vIiHmLuFlejoo7HtDok/O5eDDD0UpCVY5bBX5U5RYo8wWP83H7ZsqVEnA==",
-      "dev": true,
-      "dependencies": {
-        "@types/estree": "1.0.5"
-      },
-      "bin": {
-        "rollup": "dist/bin/rollup"
-      },
-      "engines": {
-        "node": ">=18.0.0",
-        "npm": ">=8.0.0"
-      },
-      "optionalDependencies": {
-        "@rollup/rollup-android-arm-eabi": "4.16.4",
-        "@rollup/rollup-android-arm64": "4.16.4",
-        "@rollup/rollup-darwin-arm64": "4.16.4",
-        "@rollup/rollup-darwin-x64": "4.16.4",
-        "@rollup/rollup-linux-arm-gnueabihf": "4.16.4",
-        "@rollup/rollup-linux-arm-musleabihf": "4.16.4",
-        "@rollup/rollup-linux-arm64-gnu": "4.16.4",
-        "@rollup/rollup-linux-arm64-musl": "4.16.4",
-        "@rollup/rollup-linux-powerpc64le-gnu": "4.16.4",
-        "@rollup/rollup-linux-riscv64-gnu": "4.16.4",
-        "@rollup/rollup-linux-s390x-gnu": "4.16.4",
-        "@rollup/rollup-linux-x64-gnu": "4.16.4",
-        "@rollup/rollup-linux-x64-musl": "4.16.4",
-        "@rollup/rollup-win32-arm64-msvc": "4.16.4",
-        "@rollup/rollup-win32-ia32-msvc": "4.16.4",
-        "@rollup/rollup-win32-x64-msvc": "4.16.4",
-        "fsevents": "~2.3.2"
-      }
-    },
-    "node_modules/rrweb-cssom": {
-      "version": "0.6.0",
-      "resolved": "https://registry.npmjs.org/rrweb-cssom/-/rrweb-cssom-0.6.0.tgz",
-      "integrity": "sha512-APM0Gt1KoXBz0iIkkdB/kfvGOwC4UuJFeG/c+yV7wSc7q96cG/kJ0HiYCnzivD9SB53cLV1MlHFNfOuPaadYSw==",
-      "dev": true
-    },
-    "node_modules/run-parallel": {
-      "version": "1.2.0",
-      "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
-      "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==",
-      "dev": true,
-      "funding": [
-        {
-          "type": "github",
-          "url": "https://github.com/sponsors/feross"
-        },
-        {
-          "type": "patreon",
-          "url": "https://www.patreon.com/feross"
-        },
-        {
-          "type": "consulting",
-          "url": "https://feross.org/support"
-        }
-      ],
-      "dependencies": {
-        "queue-microtask": "^1.2.2"
-      }
-    },
-    "node_modules/rxjs": {
-      "version": "7.8.1",
-      "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz",
-      "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==",
-      "dev": true,
-      "dependencies": {
-        "tslib": "^2.1.0"
-      }
-    },
-    "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==",
-      "dev": true,
-      "funding": [
-        {
-          "type": "github",
-          "url": "https://github.com/sponsors/feross"
-        },
-        {
-          "type": "patreon",
-          "url": "https://www.patreon.com/feross"
-        },
-        {
-          "type": "consulting",
-          "url": "https://feross.org/support"
-        }
-      ]
-    },
-    "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
-    },
-    "node_modules/saxes": {
-      "version": "6.0.0",
-      "resolved": "https://registry.npmjs.org/saxes/-/saxes-6.0.0.tgz",
-      "integrity": "sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==",
-      "dev": true,
-      "dependencies": {
-        "xmlchars": "^2.2.0"
-      },
-      "engines": {
-        "node": ">=v12.22.7"
-      }
-    },
-    "node_modules/semver": {
-      "version": "7.6.0",
-      "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz",
-      "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==",
-      "dev": true,
-      "dependencies": {
-        "lru-cache": "^6.0.0"
-      },
-      "bin": {
-        "semver": "bin/semver.js"
-      },
-      "engines": {
-        "node": ">=10"
-      }
-    },
-    "node_modules/semver/node_modules/lru-cache": {
-      "version": "6.0.0",
-      "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
-      "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
-      "dev": true,
-      "dependencies": {
-        "yallist": "^4.0.0"
-      },
-      "engines": {
-        "node": ">=10"
-      }
-    },
-    "node_modules/set-function-length": {
-      "version": "1.2.2",
-      "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz",
-      "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==",
-      "dev": true,
-      "dependencies": {
-        "define-data-property": "^1.1.4",
-        "es-errors": "^1.3.0",
-        "function-bind": "^1.1.2",
-        "get-intrinsic": "^1.2.4",
-        "gopd": "^1.0.1",
-        "has-property-descriptors": "^1.0.2"
-      },
-      "engines": {
-        "node": ">= 0.4"
-      }
-    },
-    "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,
-      "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,
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/shell-quote": {
-      "version": "1.8.1",
-      "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.1.tgz",
-      "integrity": "sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA==",
-      "dev": true,
-      "funding": {
-        "url": "https://github.com/sponsors/ljharb"
-      }
-    },
-    "node_modules/side-channel": {
-      "version": "1.0.6",
-      "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz",
-      "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==",
-      "dev": true,
-      "dependencies": {
-        "call-bind": "^1.0.7",
-        "es-errors": "^1.3.0",
-        "get-intrinsic": "^1.2.4",
-        "object-inspect": "^1.13.1"
-      },
-      "engines": {
-        "node": ">= 0.4"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/ljharb"
-      }
-    },
-    "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
-    },
-    "node_modules/signal-exit": {
-      "version": "3.0.7",
-      "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz",
-      "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==",
-      "dev": true
-    },
-    "node_modules/slash": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
-      "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==",
-      "dev": true,
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/slice-ansi": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-3.0.0.tgz",
-      "integrity": "sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ==",
-      "dev": true,
-      "dependencies": {
-        "ansi-styles": "^4.0.0",
-        "astral-regex": "^2.0.0",
-        "is-fullwidth-code-point": "^3.0.0"
-      },
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/sortablejs": {
-      "version": "1.14.0",
-      "resolved": "https://registry.npmjs.org/sortablejs/-/sortablejs-1.14.0.tgz",
-      "integrity": "sha512-pBXvQCs5/33fdN1/39pPL0NZF20LeRbLQ5jtnheIPN9JQAaufGjKdWduZn4U7wCtVuzKhmRkI0DFYHYRbB2H1w=="
-    },
-    "node_modules/source-map-js": {
-      "version": "1.2.0",
-      "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz",
-      "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==",
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/split": {
-      "version": "0.3.3",
-      "resolved": "https://registry.npmjs.org/split/-/split-0.3.3.tgz",
-      "integrity": "sha512-wD2AeVmxXRBoX44wAycgjVpMhvbwdI2aZjCkvfNcH1YqHQvJVa1duWc73OyVGJUc05fhFaTZeQ/PYsrmyH0JVA==",
-      "dev": true,
-      "dependencies": {
-        "through": "2"
-      },
-      "engines": {
-        "node": "*"
-      }
-    },
-    "node_modules/sshpk": {
-      "version": "1.18.0",
-      "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.18.0.tgz",
-      "integrity": "sha512-2p2KJZTSqQ/I3+HX42EpYOa2l3f8Erv8MWKsy2I9uf4wA7yFIkXRffYdsx86y6z4vHtV8u7g+pPlr8/4ouAxsQ==",
-      "dev": true,
-      "dependencies": {
-        "asn1": "~0.2.3",
-        "assert-plus": "^1.0.0",
-        "bcrypt-pbkdf": "^1.0.0",
-        "dashdash": "^1.12.0",
-        "ecc-jsbn": "~0.1.1",
-        "getpass": "^0.1.1",
-        "jsbn": "~0.1.0",
-        "safer-buffer": "^2.0.2",
-        "tweetnacl": "~0.14.0"
-      },
-      "bin": {
-        "sshpk-conv": "bin/sshpk-conv",
-        "sshpk-sign": "bin/sshpk-sign",
-        "sshpk-verify": "bin/sshpk-verify"
-      },
-      "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
-    },
-    "node_modules/start-server-and-test": {
-      "version": "2.0.3",
-      "resolved": "https://registry.npmjs.org/start-server-and-test/-/start-server-and-test-2.0.3.tgz",
-      "integrity": "sha512-QsVObjfjFZKJE6CS6bSKNwWZCKBG6975/jKRPPGFfFh+yOQglSeGXiNWjzgQNXdphcBI9nXbyso9tPfX4YAUhg==",
-      "dev": true,
-      "dependencies": {
-        "arg": "^5.0.2",
-        "bluebird": "3.7.2",
-        "check-more-types": "2.24.0",
-        "debug": "4.3.4",
-        "execa": "5.1.1",
-        "lazy-ass": "1.6.0",
-        "ps-tree": "1.2.0",
-        "wait-on": "7.2.0"
-      },
-      "bin": {
-        "server-test": "src/bin/start.js",
-        "start-server-and-test": "src/bin/start.js",
-        "start-test": "src/bin/start.js"
-      },
-      "engines": {
-        "node": ">=16"
-      }
-    },
-    "node_modules/start-server-and-test/node_modules/execa": {
-      "version": "5.1.1",
-      "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz",
-      "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==",
-      "dev": true,
-      "dependencies": {
-        "cross-spawn": "^7.0.3",
-        "get-stream": "^6.0.0",
-        "human-signals": "^2.1.0",
-        "is-stream": "^2.0.0",
-        "merge-stream": "^2.0.0",
-        "npm-run-path": "^4.0.1",
-        "onetime": "^5.1.2",
-        "signal-exit": "^3.0.3",
-        "strip-final-newline": "^2.0.0"
-      },
-      "engines": {
-        "node": ">=10"
-      },
-      "funding": {
-        "url": "https://github.com/sindresorhus/execa?sponsor=1"
-      }
-    },
-    "node_modules/start-server-and-test/node_modules/get-stream": {
-      "version": "6.0.1",
-      "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz",
-      "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==",
-      "dev": true,
-      "engines": {
-        "node": ">=10"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/start-server-and-test/node_modules/human-signals": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz",
-      "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==",
-      "dev": true,
-      "engines": {
-        "node": ">=10.17.0"
-      }
-    },
-    "node_modules/std-env": {
-      "version": "3.7.0",
-      "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.7.0.tgz",
-      "integrity": "sha512-JPbdCEQLj1w5GilpiHAx3qJvFndqybBysA3qUOnznweH4QbNYUsW/ea8QzSrnh0vNsezMMw5bcVool8lM0gwzg==",
-      "dev": true
-    },
-    "node_modules/stream-combiner": {
-      "version": "0.0.4",
-      "resolved": "https://registry.npmjs.org/stream-combiner/-/stream-combiner-0.0.4.tgz",
-      "integrity": "sha512-rT00SPnTVyRsaSz5zgSPma/aHSOic5U1prhYdRy5HS2kTZviFpmDgzilbtsJsxiroqACmayynDN/9VzIbX5DOw==",
-      "dev": true,
-      "dependencies": {
-        "duplexer": "~0.1.1"
-      }
-    },
-    "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,
-      "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": {
-      "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,
-      "dependencies": {
-        "emoji-regex": "^8.0.0",
-        "is-fullwidth-code-point": "^3.0.0",
-        "strip-ansi": "^6.0.1"
-      },
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "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,
-      "dependencies": {
-        "ansi-regex": "^5.0.1"
-      },
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "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,
-      "dependencies": {
-        "ansi-regex": "^5.0.1"
-      },
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/strip-final-newline": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz",
-      "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==",
-      "dev": true,
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "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,
-      "engines": {
-        "node": ">=8"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/strip-literal": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/strip-literal/-/strip-literal-2.1.0.tgz",
-      "integrity": "sha512-Op+UycaUt/8FbN/Z2TWPBLge3jWrP3xj10f3fnYxf052bKuS3EKs1ZQcVGjnEMdsNVAM+plXRdmjrZ/KgG3Skw==",
-      "dev": true,
-      "dependencies": {
-        "js-tokens": "^9.0.0"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/antfu"
-      }
-    },
-    "node_modules/sucrase": {
-      "version": "3.35.0",
-      "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.35.0.tgz",
-      "integrity": "sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==",
-      "dev": true,
-      "dependencies": {
-        "@jridgewell/gen-mapping": "^0.3.2",
-        "commander": "^4.0.0",
-        "glob": "^10.3.10",
-        "lines-and-columns": "^1.1.6",
-        "mz": "^2.7.0",
-        "pirates": "^4.0.1",
-        "ts-interface-checker": "^0.1.9"
-      },
-      "bin": {
-        "sucrase": "bin/sucrase",
-        "sucrase-node": "bin/sucrase-node"
-      },
-      "engines": {
-        "node": ">=16 || 14 >=14.17"
-      }
-    },
-    "node_modules/sucrase/node_modules/commander": {
-      "version": "4.1.1",
-      "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz",
-      "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==",
-      "dev": true,
-      "engines": {
-        "node": ">= 6"
-      }
-    },
-    "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==",
-      "dev": true,
-      "dependencies": {
-        "has-flag": "^4.0.0"
-      },
-      "engines": {
-        "node": ">=10"
-      },
-      "funding": {
-        "url": "https://github.com/chalk/supports-color?sponsor=1"
-      }
-    },
-    "node_modules/supports-preserve-symlinks-flag": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
-      "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==",
-      "dev": true,
-      "engines": {
-        "node": ">= 0.4"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/ljharb"
-      }
-    },
-    "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
-    },
-    "node_modules/synckit": {
-      "version": "0.8.8",
-      "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.8.8.tgz",
-      "integrity": "sha512-HwOKAP7Wc5aRGYdKH+dw0PRRpbO841v2DENBtjnR5HFWoiNByAl7vrx3p0G/rCyYXQsrxqtX48TImFtPcIHSpQ==",
-      "dev": true,
-      "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/tailwindcss": {
-      "version": "3.4.3",
-      "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.3.tgz",
-      "integrity": "sha512-U7sxQk/n397Bmx4JHbJx/iSOOv5G+II3f1kpLpY2QeUv5DcPdcTsYLlusZfq1NthHS1c1cZoyFmmkex1rzke0A==",
-      "dev": true,
-      "dependencies": {
-        "@alloc/quick-lru": "^5.2.0",
-        "arg": "^5.0.2",
-        "chokidar": "^3.5.3",
-        "didyoumean": "^1.2.2",
-        "dlv": "^1.1.3",
-        "fast-glob": "^3.3.0",
-        "glob-parent": "^6.0.2",
-        "is-glob": "^4.0.3",
-        "jiti": "^1.21.0",
-        "lilconfig": "^2.1.0",
-        "micromatch": "^4.0.5",
-        "normalize-path": "^3.0.0",
-        "object-hash": "^3.0.0",
-        "picocolors": "^1.0.0",
-        "postcss": "^8.4.23",
-        "postcss-import": "^15.1.0",
-        "postcss-js": "^4.0.1",
-        "postcss-load-config": "^4.0.1",
-        "postcss-nested": "^6.0.1",
-        "postcss-selector-parser": "^6.0.11",
-        "resolve": "^1.22.2",
-        "sucrase": "^3.32.0"
-      },
-      "bin": {
-        "tailwind": "lib/cli.js",
-        "tailwindcss": "lib/cli.js"
-      },
-      "engines": {
-        "node": ">=14.0.0"
-      }
-    },
-    "node_modules/test-exclude": {
-      "version": "6.0.0",
-      "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz",
-      "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==",
-      "dev": true,
-      "dependencies": {
-        "@istanbuljs/schema": "^0.1.2",
-        "glob": "^7.1.4",
-        "minimatch": "^3.0.4"
-      },
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/test-exclude/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,
-      "dependencies": {
-        "balanced-match": "^1.0.0",
-        "concat-map": "0.0.1"
-      }
-    },
-    "node_modules/test-exclude/node_modules/glob": {
-      "version": "7.2.3",
-      "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
-      "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
-      "dev": true,
-      "dependencies": {
-        "fs.realpath": "^1.0.0",
-        "inflight": "^1.0.4",
-        "inherits": "2",
-        "minimatch": "^3.1.1",
-        "once": "^1.3.0",
-        "path-is-absolute": "^1.0.0"
-      },
-      "engines": {
-        "node": "*"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/isaacs"
-      }
-    },
-    "node_modules/test-exclude/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,
-      "dependencies": {
-        "brace-expansion": "^1.1.7"
-      },
-      "engines": {
-        "node": "*"
-      }
-    },
-    "node_modules/text-table": {
-      "version": "0.2.0",
-      "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
-      "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==",
-      "dev": true
-    },
-    "node_modules/thenify": {
-      "version": "3.3.1",
-      "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz",
-      "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==",
-      "dev": true,
-      "dependencies": {
-        "any-promise": "^1.0.0"
-      }
-    },
-    "node_modules/thenify-all": {
-      "version": "1.6.0",
-      "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz",
-      "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==",
-      "dev": true,
-      "dependencies": {
-        "thenify": ">= 3.1.0 < 4"
-      },
-      "engines": {
-        "node": ">=0.8"
-      }
-    },
-    "node_modules/throttleit": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/throttleit/-/throttleit-1.0.1.tgz",
-      "integrity": "sha512-vDZpf9Chs9mAdfY046mcPt8fg5QSZr37hEH4TXYBnDF+izxgrbRGUAAaBvIk/fJm9aOFCGFd1EsNg5AZCbnQCQ==",
-      "dev": true,
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/through": {
-      "version": "2.3.8",
-      "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
-      "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==",
-      "dev": true
-    },
-    "node_modules/tinybench": {
-      "version": "2.8.0",
-      "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.8.0.tgz",
-      "integrity": "sha512-1/eK7zUnIklz4JUUlL+658n58XO2hHLQfSk1Zf2LKieUjxidN16eKFEoDEfjHc3ohofSSqK3X5yO6VGb6iW8Lw==",
-      "dev": true
-    },
-    "node_modules/tinypool": {
-      "version": "0.8.4",
-      "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-0.8.4.tgz",
-      "integrity": "sha512-i11VH5gS6IFeLY3gMBQ00/MmLncVP7JLXOw1vlgkytLmJK7QnEr7NXf0LBdxfmNPAeyetukOk0bOYrJrFGjYJQ==",
-      "dev": true,
-      "engines": {
-        "node": ">=14.0.0"
-      }
-    },
-    "node_modules/tinyspy": {
-      "version": "2.2.1",
-      "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-2.2.1.tgz",
-      "integrity": "sha512-KYad6Vy5VDWV4GH3fjpseMQ/XU2BhIYP7Vzd0LG44qRWm/Yt2WCOTicFdvmgo6gWaqooMQCawTtILVQJupKu7A==",
-      "dev": true,
-      "engines": {
-        "node": ">=14.0.0"
-      }
-    },
-    "node_modules/tmp": {
-      "version": "0.2.3",
-      "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.3.tgz",
-      "integrity": "sha512-nZD7m9iCPC5g0pYmcaxogYKggSfLsdxl8of3Q/oIbqCqLLIO9IAF0GWjX1z9NZRHPiXv8Wex4yDCaZsgEw0Y8w==",
-      "dev": true,
-      "engines": {
-        "node": ">=14.14"
-      }
-    },
-    "node_modules/to-fast-properties": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz",
-      "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==",
-      "dev": true,
-      "engines": {
-        "node": ">=4"
-      }
-    },
-    "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==",
-      "dev": true,
-      "dependencies": {
-        "is-number": "^7.0.0"
-      },
-      "engines": {
-        "node": ">=8.0"
-      }
-    },
-    "node_modules/tough-cookie": {
-      "version": "4.1.3",
-      "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.3.tgz",
-      "integrity": "sha512-aX/y5pVRkfRnfmuX+OdbSdXvPe6ieKX/G2s7e98f4poJHnqH3281gDPm/metm6E/WRamfx7WC4HUqkWHfQHprw==",
-      "dev": true,
-      "dependencies": {
-        "psl": "^1.1.33",
-        "punycode": "^2.1.1",
-        "universalify": "^0.2.0",
-        "url-parse": "^1.5.3"
-      },
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/tough-cookie/node_modules/universalify": {
-      "version": "0.2.0",
-      "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz",
-      "integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==",
-      "dev": true,
-      "engines": {
-        "node": ">= 4.0.0"
-      }
-    },
-    "node_modules/tr46": {
-      "version": "5.0.0",
-      "resolved": "https://registry.npmjs.org/tr46/-/tr46-5.0.0.tgz",
-      "integrity": "sha512-tk2G5R2KRwBd+ZN0zaEXpmzdKyOYksXwywulIX95MBODjSzMIuQnQ3m8JxgbhnL1LeVo7lqQKsYa1O3Htl7K5g==",
-      "dev": true,
-      "dependencies": {
-        "punycode": "^2.3.1"
-      },
-      "engines": {
-        "node": ">=18"
-      }
-    },
-    "node_modules/ts-api-utils": {
-      "version": "1.3.0",
-      "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.3.0.tgz",
-      "integrity": "sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==",
-      "dev": true,
-      "engines": {
-        "node": ">=16"
-      },
-      "peerDependencies": {
-        "typescript": ">=4.2.0"
-      }
-    },
-    "node_modules/ts-interface-checker": {
-      "version": "0.1.13",
-      "resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz",
-      "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==",
-      "dev": true
-    },
-    "node_modules/tslib": {
-      "version": "2.6.2",
-      "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz",
-      "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==",
-      "dev": true
-    },
-    "node_modules/tunnel-agent": {
-      "version": "0.6.0",
-      "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
-      "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==",
-      "dev": true,
-      "dependencies": {
-        "safe-buffer": "^5.0.1"
-      },
-      "engines": {
-        "node": "*"
-      }
-    },
-    "node_modules/tweetnacl": {
-      "version": "0.14.5",
-      "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
-      "integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==",
-      "dev": true
-    },
-    "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,
-      "dependencies": {
-        "prelude-ls": "^1.2.1"
-      },
-      "engines": {
-        "node": ">= 0.8.0"
-      }
-    },
-    "node_modules/type-detect": {
-      "version": "4.0.8",
-      "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz",
-      "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==",
-      "dev": true,
-      "engines": {
-        "node": ">=4"
-      }
-    },
-    "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,
-      "engines": {
-        "node": ">=10"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/typescript": {
-      "version": "5.4.5",
-      "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.5.tgz",
-      "integrity": "sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==",
-      "devOptional": true,
-      "bin": {
-        "tsc": "bin/tsc",
-        "tsserver": "bin/tsserver"
-      },
-      "engines": {
-        "node": ">=14.17"
-      }
-    },
-    "node_modules/ufo": {
-      "version": "1.5.3",
-      "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.5.3.tgz",
-      "integrity": "sha512-Y7HYmWaFwPUmkoQCUIAYpKqkOf+SbVj/2fJJZ4RJMCfZp0rTGwRbzQD+HghfnhKOjL9E01okqz+ncJskGYfBNw==",
-      "dev": true
-    },
-    "node_modules/undici-types": {
-      "version": "5.26.5",
-      "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz",
-      "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==",
-      "dev": true
-    },
-    "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,
-      "engines": {
-        "node": ">= 10.0.0"
-      }
-    },
-    "node_modules/untildify": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/untildify/-/untildify-4.0.0.tgz",
-      "integrity": "sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw==",
-      "dev": true,
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/update-browserslist-db": {
-      "version": "1.0.13",
-      "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz",
-      "integrity": "sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==",
-      "dev": true,
-      "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"
-        }
-      ],
-      "dependencies": {
-        "escalade": "^3.1.1",
-        "picocolors": "^1.0.0"
-      },
-      "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,
-      "dependencies": {
-        "punycode": "^2.1.0"
-      }
-    },
-    "node_modules/url-parse": {
-      "version": "1.5.10",
-      "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz",
-      "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==",
-      "dev": true,
-      "dependencies": {
-        "querystringify": "^2.1.1",
-        "requires-port": "^1.0.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
-    },
-    "node_modules/uuid": {
-      "version": "8.3.2",
-      "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
-      "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==",
-      "dev": true,
-      "bin": {
-        "uuid": "dist/bin/uuid"
-      }
-    },
-    "node_modules/verror": {
-      "version": "1.10.0",
-      "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz",
-      "integrity": "sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==",
-      "dev": true,
-      "engines": [
-        "node >=0.6.0"
-      ],
-      "dependencies": {
-        "assert-plus": "^1.0.0",
-        "core-util-is": "1.0.2",
-        "extsprintf": "^1.2.0"
-      }
-    },
-    "node_modules/vite": {
-      "version": "5.2.10",
-      "resolved": "https://registry.npmjs.org/vite/-/vite-5.2.10.tgz",
-      "integrity": "sha512-PAzgUZbP7msvQvqdSD+ErD5qGnSFiGOoWmV5yAKUEI0kdhjbH6nMWVyZQC/hSc4aXwc0oJ9aEdIiF9Oje0JFCw==",
-      "dev": true,
-      "dependencies": {
-        "esbuild": "^0.20.1",
-        "postcss": "^8.4.38",
-        "rollup": "^4.13.0"
-      },
-      "bin": {
-        "vite": "bin/vite.js"
-      },
-      "engines": {
-        "node": "^18.0.0 || >=20.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",
-        "less": "*",
-        "lightningcss": "^1.21.0",
-        "sass": "*",
-        "stylus": "*",
-        "sugarss": "*",
-        "terser": "^5.4.0"
-      },
-      "peerDependenciesMeta": {
-        "@types/node": {
-          "optional": true
-        },
-        "less": {
-          "optional": true
-        },
-        "lightningcss": {
-          "optional": true
-        },
-        "sass": {
-          "optional": true
-        },
-        "stylus": {
-          "optional": true
-        },
-        "sugarss": {
-          "optional": true
-        },
-        "terser": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/vite-node": {
-      "version": "1.5.1",
-      "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-1.5.1.tgz",
-      "integrity": "sha512-HNpfV7BrAsjkYVNWIcPleJwvJmydJqqJRrRbpoQ/U7QDwJKyEzNa4g5aYg8MjXJyKsk29IUCcMLFRcsEvqUIsA==",
-      "dev": true,
-      "dependencies": {
-        "cac": "^6.7.14",
-        "debug": "^4.3.4",
-        "pathe": "^1.1.1",
-        "picocolors": "^1.0.0",
-        "vite": "^5.0.0"
-      },
-      "bin": {
-        "vite-node": "vite-node.mjs"
-      },
-      "engines": {
-        "node": "^18.0.0 || >=20.0.0"
-      },
-      "funding": {
-        "url": "https://opencollective.com/vitest"
-      }
-    },
-    "node_modules/vitest": {
-      "version": "1.5.1",
-      "resolved": "https://registry.npmjs.org/vitest/-/vitest-1.5.1.tgz",
-      "integrity": "sha512-3GvBMpoRnUNbZRX1L3mJCv3Ou3NAobb4dM48y8k9ZGwDofePpclTOyO+lqJFKSQpubH1V8tEcAEw/Y3mJKGJQQ==",
-      "dev": true,
-      "dependencies": {
-        "@vitest/expect": "1.5.1",
-        "@vitest/runner": "1.5.1",
-        "@vitest/snapshot": "1.5.1",
-        "@vitest/spy": "1.5.1",
-        "@vitest/utils": "1.5.1",
-        "acorn-walk": "^8.3.2",
-        "chai": "^4.3.10",
-        "debug": "^4.3.4",
-        "execa": "^8.0.1",
-        "local-pkg": "^0.5.0",
-        "magic-string": "^0.30.5",
-        "pathe": "^1.1.1",
-        "picocolors": "^1.0.0",
-        "std-env": "^3.5.0",
-        "strip-literal": "^2.0.0",
-        "tinybench": "^2.5.1",
-        "tinypool": "^0.8.3",
-        "vite": "^5.0.0",
-        "vite-node": "1.5.1",
-        "why-is-node-running": "^2.2.2"
-      },
-      "bin": {
-        "vitest": "vitest.mjs"
-      },
-      "engines": {
-        "node": "^18.0.0 || >=20.0.0"
-      },
-      "funding": {
-        "url": "https://opencollective.com/vitest"
-      },
-      "peerDependencies": {
-        "@edge-runtime/vm": "*",
-        "@types/node": "^18.0.0 || >=20.0.0",
-        "@vitest/browser": "1.5.1",
-        "@vitest/ui": "1.5.1",
-        "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/execa": {
-      "version": "8.0.1",
-      "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz",
-      "integrity": "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==",
-      "dev": true,
-      "dependencies": {
-        "cross-spawn": "^7.0.3",
-        "get-stream": "^8.0.1",
-        "human-signals": "^5.0.0",
-        "is-stream": "^3.0.0",
-        "merge-stream": "^2.0.0",
-        "npm-run-path": "^5.1.0",
-        "onetime": "^6.0.0",
-        "signal-exit": "^4.1.0",
-        "strip-final-newline": "^3.0.0"
-      },
-      "engines": {
-        "node": ">=16.17"
-      },
-      "funding": {
-        "url": "https://github.com/sindresorhus/execa?sponsor=1"
-      }
-    },
-    "node_modules/vitest/node_modules/get-stream": {
-      "version": "8.0.1",
-      "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz",
-      "integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==",
-      "dev": true,
-      "engines": {
-        "node": ">=16"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/vitest/node_modules/human-signals": {
-      "version": "5.0.0",
-      "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz",
-      "integrity": "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==",
-      "dev": true,
-      "engines": {
-        "node": ">=16.17.0"
-      }
-    },
-    "node_modules/vitest/node_modules/is-stream": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz",
-      "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==",
-      "dev": true,
-      "engines": {
-        "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/vitest/node_modules/mimic-fn": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz",
-      "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==",
-      "dev": true,
-      "engines": {
-        "node": ">=12"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/vitest/node_modules/npm-run-path": {
-      "version": "5.3.0",
-      "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.3.0.tgz",
-      "integrity": "sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==",
-      "dev": true,
-      "dependencies": {
-        "path-key": "^4.0.0"
-      },
-      "engines": {
-        "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/vitest/node_modules/onetime": {
-      "version": "6.0.0",
-      "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz",
-      "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==",
-      "dev": true,
-      "dependencies": {
-        "mimic-fn": "^4.0.0"
-      },
-      "engines": {
-        "node": ">=12"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/vitest/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,
-      "engines": {
-        "node": ">=12"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/vitest/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,
-      "engines": {
-        "node": ">=14"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/isaacs"
-      }
-    },
-    "node_modules/vitest/node_modules/strip-final-newline": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz",
-      "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==",
-      "dev": true,
-      "engines": {
-        "node": ">=12"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/vue": {
-      "version": "3.4.25",
-      "resolved": "https://registry.npmjs.org/vue/-/vue-3.4.25.tgz",
-      "integrity": "sha512-HWyDqoBHMgav/OKiYA2ZQg+kjfMgLt/T0vg4cbIF7JbXAjDexRf5JRg+PWAfrAkSmTd2I8aPSXtooBFWHB98cg==",
-      "dependencies": {
-        "@vue/compiler-dom": "3.4.25",
-        "@vue/compiler-sfc": "3.4.25",
-        "@vue/runtime-dom": "3.4.25",
-        "@vue/server-renderer": "3.4.25",
-        "@vue/shared": "3.4.25"
-      },
-      "peerDependencies": {
-        "typescript": "*"
-      },
-      "peerDependenciesMeta": {
-        "typescript": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/vue-component-type-helpers": {
-      "version": "2.0.14",
-      "resolved": "https://registry.npmjs.org/vue-component-type-helpers/-/vue-component-type-helpers-2.0.14.tgz",
-      "integrity": "sha512-DInfgOyXlMyliyqAAD9frK28tTfch0+tMi4qoWJcZlRxUf+NFAtraJBnAsKLep+FOyLMiajkhfyEb3xLK08i7w==",
-      "dev": true
-    },
-    "node_modules/vue-eslint-parser": {
-      "version": "9.4.2",
-      "resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-9.4.2.tgz",
-      "integrity": "sha512-Ry9oiGmCAK91HrKMtCrKFWmSFWvYkpGglCeFAIqDdr9zdXmMMpJOmUJS7WWsW7fX81h6mwHmUZCQQ1E0PkSwYQ==",
-      "dev": true,
-      "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-router": {
-      "version": "4.3.2",
-      "resolved": "https://registry.npmjs.org/vue-router/-/vue-router-4.3.2.tgz",
-      "integrity": "sha512-hKQJ1vDAZ5LVkKEnHhmm1f9pMiWIBNGF5AwU67PdH7TyXCj/a4hTccuUuYCAMgJK6rO/NVYtQIEN3yL8CECa7Q==",
-      "dependencies": {
-        "@vue/devtools-api": "^6.5.1"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/posva"
-      },
-      "peerDependencies": {
-        "vue": "^3.2.0"
-      }
-    },
-    "node_modules/vue-template-compiler": {
-      "version": "2.7.16",
-      "resolved": "https://registry.npmjs.org/vue-template-compiler/-/vue-template-compiler-2.7.16.tgz",
-      "integrity": "sha512-AYbUWAJHLGGQM7+cNTELw+KsOG9nl2CnSv467WobS5Cv9uk3wFcnr1Etsz2sEIHEZvw1U+o9mRlEO6QbZvUPGQ==",
-      "dev": true,
-      "dependencies": {
-        "de-indent": "^1.0.2",
-        "he": "^1.2.0"
-      }
-    },
-    "node_modules/vue-tsc": {
-      "version": "2.0.14",
-      "resolved": "https://registry.npmjs.org/vue-tsc/-/vue-tsc-2.0.14.tgz",
-      "integrity": "sha512-DgAO3U1cnCHOUO7yB35LENbkapeRsBZ7Ugq5hGz/QOHny0+1VQN8eSwSBjYbjLVPfvfw6EY7sNPjbuHHUhckcg==",
-      "dev": true,
-      "dependencies": {
-        "@volar/typescript": "2.2.0-alpha.10",
-        "@vue/language-core": "2.0.14",
-        "semver": "^7.5.4"
-      },
-      "bin": {
-        "vue-tsc": "bin/vue-tsc.js"
-      },
-      "peerDependencies": {
-        "typescript": "*"
-      }
-    },
-    "node_modules/vuedraggable": {
-      "version": "4.1.0",
-      "resolved": "https://registry.npmjs.org/vuedraggable/-/vuedraggable-4.1.0.tgz",
-      "integrity": "sha512-FU5HCWBmsf20GpP3eudURW3WdWTKIbEIQxh9/8GE806hydR9qZqRRxRE3RjqX7PkuLuMQG/A7n3cfj9rCEchww==",
-      "dependencies": {
-        "sortablejs": "1.14.0"
-      },
-      "peerDependencies": {
-        "vue": "^3.0.1"
-      }
-    },
-    "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,
-      "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,
-      "engines": {
-        "node": ">=18"
-      }
-    },
-    "node_modules/wait-on": {
-      "version": "7.2.0",
-      "resolved": "https://registry.npmjs.org/wait-on/-/wait-on-7.2.0.tgz",
-      "integrity": "sha512-wCQcHkRazgjG5XoAq9jbTMLpNIjoSlZslrJ2+N9MxDsGEv1HnFoVjOCexL0ESva7Y9cu350j+DWADdk54s4AFQ==",
-      "dev": true,
-      "dependencies": {
-        "axios": "^1.6.1",
-        "joi": "^17.11.0",
-        "lodash": "^4.17.21",
-        "minimist": "^1.2.8",
-        "rxjs": "^7.8.1"
-      },
-      "bin": {
-        "wait-on": "bin/wait-on"
-      },
-      "engines": {
-        "node": ">=12.0.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,
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/whatwg-encoding": {
-      "version": "3.1.1",
-      "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-3.1.1.tgz",
-      "integrity": "sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==",
-      "dev": true,
-      "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,
-      "engines": {
-        "node": ">=18"
-      }
-    },
-    "node_modules/whatwg-url": {
-      "version": "14.0.0",
-      "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-14.0.0.tgz",
-      "integrity": "sha512-1lfMEm2IEr7RIV+f4lUNPOqfFL+pO+Xw3fJSqmjX9AbXcXcYOkCe1P6+9VBZB6n94af16NfZf+sSk0JCBZC9aw==",
-      "dev": true,
-      "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,
-      "dependencies": {
-        "isexe": "^2.0.0"
-      },
-      "bin": {
-        "node-which": "bin/node-which"
-      },
-      "engines": {
-        "node": ">= 8"
-      }
-    },
-    "node_modules/why-is-node-running": {
-      "version": "2.2.2",
-      "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.2.2.tgz",
-      "integrity": "sha512-6tSwToZxTOcotxHeA+qGCq1mVzKR3CwcJGmVcY+QE8SHy6TnpFnh8PAvPNHYr7EcuVeG0QSMxtYCuO1ta/G/oA==",
-      "dev": true,
-      "dependencies": {
-        "siginfo": "^2.0.0",
-        "stackback": "0.0.2"
-      },
-      "bin": {
-        "why-is-node-running": "cli.js"
-      },
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "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,
-      "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,
-      "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/node_modules/ansi-regex": {
-      "version": "6.0.1",
-      "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz",
-      "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==",
-      "dev": true,
-      "engines": {
-        "node": ">=12"
-      },
-      "funding": {
-        "url": "https://github.com/chalk/ansi-regex?sponsor=1"
-      }
-    },
-    "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,
-      "engines": {
-        "node": ">=12"
-      },
-      "funding": {
-        "url": "https://github.com/chalk/ansi-styles?sponsor=1"
-      }
-    },
-    "node_modules/wrap-ansi/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
-    },
-    "node_modules/wrap-ansi/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,
-      "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/wrap-ansi/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,
-      "dependencies": {
-        "ansi-regex": "^6.0.1"
-      },
-      "engines": {
-        "node": ">=12"
-      },
-      "funding": {
-        "url": "https://github.com/chalk/strip-ansi?sponsor=1"
-      }
-    },
-    "node_modules/wrappy": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
-      "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
-      "dev": true
-    },
-    "node_modules/ws": {
-      "version": "8.16.0",
-      "resolved": "https://registry.npmjs.org/ws/-/ws-8.16.0.tgz",
-      "integrity": "sha512-HS0c//TP7Ina87TfiPUz1rQzMhHrl/SG2guqRcTOIUYD2q8uhUdNHZYJUaQ8aTGPzCh+c6oawMKW35nFl1dxyQ==",
-      "dev": true,
-      "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,
-      "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
-    },
-    "node_modules/yallist": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
-      "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
-      "dev": true
-    },
-    "node_modules/yaml": {
-      "version": "2.4.1",
-      "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.4.1.tgz",
-      "integrity": "sha512-pIXzoImaqmfOrL7teGUBt/T7ZDnyeGBWyXQBvOVhLkWLN37GXv8NMLK406UY6dS51JfcQHsmcW5cJ441bHg6Lg==",
-      "dev": true,
-      "bin": {
-        "yaml": "bin.mjs"
-      },
-      "engines": {
-        "node": ">= 14"
-      }
-    },
-    "node_modules/yauzl": {
-      "version": "2.10.0",
-      "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz",
-      "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==",
-      "dev": true,
-      "dependencies": {
-        "buffer-crc32": "~0.2.3",
-        "fd-slicer": "~1.1.0"
-      }
-    },
-    "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,
-      "engines": {
-        "node": ">=10"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    }
-  }
-}
diff --git a/package.json b/package.json
deleted file mode 100644
index be13c2a5d3e4a0451de2749309b751fd1a3e17b4..0000000000000000000000000000000000000000
--- a/package.json
+++ /dev/null
@@ -1,60 +0,0 @@
-{
-  "name": "idatt2106_2024_02_frontend",
-  "version": "0.0.0",
-  "private": true,
-  "type": "module",
-  "scripts": {
-    "dev": "vite",
-    "build": "run-p type-check \"build-only {@}\" --",
-    "preview": "vite preview",
-    "test:unit": "vitest",
-    "test:e2e": "start-server-and-test 'vite dev --port 4173' :4173 'cypress run --e2e'",
-    "test:e2e:dev": "start-server-and-test 'vite dev --port 4173' :4173 'cypress open --e2e'",
-    "build-only": "vite build",
-    "type-check": "vue-tsc --build --force",
-    "lint": "eslint . --ext .vue,.js,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts --fix --ignore-path .gitignore",
-    "test:coverage": "vitest run --coverage --environment jsdom",
-    "format": "prettier --write src/",
-    "format-test": "prettier --check src/"
-  },
-  "dependencies": {
-    "animejs": "^3.2.2",
-    "canvas-confetti": "^1.9.2",
-    "pinia": "^2.1.7",
-    "vue": "^3.4.21",
-    "vue-router": "^4.3.1",
-    "vuedraggable": "^4.1.0"
-  },
-  "devDependencies": {
-    "@rushstack/eslint-patch": "^1.8.0",
-    "@tsconfig/node20": "^20.1.4",
-    "@types/animejs": "^3.1.12",
-    "@types/canvas-confetti": "^1.6.4",
-    "@types/jsdom": "^21.1.6",
-    "@types/node": "^20.12.5",
-    "@typescript-eslint/eslint-plugin": "^7.7.0",
-    "@typescript-eslint/parser": "^7.7.0",
-    "@vitejs/plugin-vue": "^5.0.4",
-    "@vitest/coverage-v8": "^1.5.0",
-    "@vue/eslint-config-prettier": "^9.0.0",
-    "@vue/eslint-config-typescript": "^13.0.0",
-    "@vue/test-utils": "^2.4.5",
-    "@vue/tsconfig": "^0.5.1",
-    "autoprefixer": "^10.4.19",
-    "axios-mock-adapter": "^1.22.0",
-    "cypress": "^13.7.3",
-    "eslint": "^8.57.0",
-    "eslint-plugin-cypress": "^2.15.1",
-    "eslint-plugin-vue": "^9.23.0",
-    "jsdom": "^24.0.0",
-    "npm-run-all2": "^6.1.2",
-    "postcss": "^8.4.38",
-    "prettier": "^3.2.5",
-    "start-server-and-test": "^2.0.3",
-    "tailwindcss": "^3.4.3",
-    "typescript": "~5.4.0",
-    "vite": "^5.2.8",
-    "vitest": "^1.4.0",
-    "vue-tsc": "^2.0.11"
-  }
-}
diff --git a/postcss.config.js b/postcss.config.js
deleted file mode 100644
index 2e7af2b7f1a6f391da1631d93968a9d487ba977d..0000000000000000000000000000000000000000
--- a/postcss.config.js
+++ /dev/null
@@ -1,6 +0,0 @@
-export default {
-  plugins: {
-    tailwindcss: {},
-    autoprefixer: {},
-  },
-}
diff --git a/public/favicon.png b/public/favicon.png
deleted file mode 100644
index fac8de3bf283197bf71ebb8d839b12a5b34263ac..0000000000000000000000000000000000000000
Binary files a/public/favicon.png and /dev/null differ
diff --git a/src/App.vue b/src/App.vue
deleted file mode 100644
index 6cd1e8f97ea32c80831eb29c2ff51bc86c2722ac..0000000000000000000000000000000000000000
--- a/src/App.vue
+++ /dev/null
@@ -1,42 +0,0 @@
-<script setup lang="ts">
-import NavBarComponent from '@/components/NavBarComponent.vue'
-import { RouterView, useRoute } from 'vue-router'
-import { computed } from 'vue'
-
-const route = useRoute()
-
-const showNavBar = computed(() => {
-    return !(
-        route.path == '/' ||
-        route.path == '/registrer' ||
-        route.path == '/logginn' ||
-        route.path == '/forgotPassword' ||
-        route.path.startsWith('/konfigurasjon')
-    )
-})
-</script>
-
-<template>
-    <NavBarComponent v-if="showNavBar" />
-
-    <main class="mb-10">
-        <RouterView />
-    </main>
-</template>
-
-<style>
-nav {
-    display: flex;
-    justify-content: center;
-    gap: 1rem;
-    margin: 1rem 0;
-}
-
-nav a.router-link-exact-active {
-    color: var(--color-text);
-}
-
-nav a.router-link-exact-active:hover {
-    background-color: transparent;
-}
-</style>
diff --git a/src/assets/base.css b/src/assets/base.css
deleted file mode 100644
index 3474f444941f8de331422c1d5f2561ddd56854e7..0000000000000000000000000000000000000000
--- a/src/assets/base.css
+++ /dev/null
@@ -1,59 +0,0 @@
-@import url('https://fonts.googleapis.com/css2?family=Karla:wght@400;700&display=swap');
-
-:root {
-    --black: #363739;
-    --white: #ffffff;
-    --grey: #cbcbcb;
-    --light-grey: #f2f2f2;
-    --green: #95e35d;
-    --red: #ef9691;
-    --light-green: #b3f385;
-
-    --bright: #f7da7c;
-
-    --accent1: #f4bab9;
-    --accent2: #95e35d;
-    --accent3: #ef9691;
-}
-
-:root {
-    --color-background: var(--white);
-    --color-text: var(--black);
-    --color-button: var(--green);
-    --color-button-disabled: var(--grey);
-    --color-nav-hover: var(--light-grey);
-    --color-button-hover: var(--light-green);
-
-    --color-link: var(--accent3);
-    --color-border: var(--black);
-
-    --section-gap: 160px;
-}
-
-@media (prefers-color-scheme: dark) {
-    :root {
-        /* TODO: add dark mode colors */
-    }
-}
-
-*,
-*::before,
-*::after {
-    box-sizing: border-box;
-    margin: 0;
-    font-weight: normal;
-}
-
-body {
-    min-height: 100vh;
-    color: var(--color-text);
-    background: var(--color-background);
-    transition:
-        color 0.5s,
-        background-color 0.5s;
-    line-height: 1.6;
-    font-family: 'Karla', sans-serif;
-    text-rendering: optimizeLegibility;
-    -webkit-font-smoothing: antialiased;
-    -moz-osx-font-smoothing: grayscale;
-}
diff --git a/src/assets/bioAuthFace.png b/src/assets/bioAuthFace.png
deleted file mode 100644
index b03bb5d400029bcbc6d7bea9f5657da31e3e63a0..0000000000000000000000000000000000000000
Binary files a/src/assets/bioAuthFace.png and /dev/null differ
diff --git a/src/assets/bioAuthTouch.png b/src/assets/bioAuthTouch.png
deleted file mode 100644
index 363627b9c744b2a8dcabc9d2a69485d055045f43..0000000000000000000000000000000000000000
Binary files a/src/assets/bioAuthTouch.png and /dev/null differ
diff --git a/src/assets/coffee.png b/src/assets/coffee.png
deleted file mode 100644
index 425ef51ab494a199c6fa075adce42e48cf35a44f..0000000000000000000000000000000000000000
Binary files a/src/assets/coffee.png and /dev/null differ
diff --git a/src/assets/completed.png b/src/assets/completed.png
deleted file mode 100644
index 943dca5a129d1c703c037cfcceac092276de40d4..0000000000000000000000000000000000000000
Binary files a/src/assets/completed.png and /dev/null differ
diff --git a/src/assets/cowboySpare.gif b/src/assets/cowboySpare.gif
deleted file mode 100644
index ff0d6f0b3d077811bd1871ad7c7889fd11a7164c..0000000000000000000000000000000000000000
Binary files a/src/assets/cowboySpare.gif and /dev/null differ
diff --git a/src/assets/finishLine.png b/src/assets/finishLine.png
deleted file mode 100644
index f30b5a30213062013638f6e275673d65d0640777..0000000000000000000000000000000000000000
Binary files a/src/assets/finishLine.png and /dev/null differ
diff --git a/src/assets/frozenStreak.png b/src/assets/frozenStreak.png
deleted file mode 100644
index 9d60b296b4432f7ea2f469b0309c1ebae9b5699f..0000000000000000000000000000000000000000
Binary files a/src/assets/frozenStreak.png and /dev/null differ
diff --git a/src/assets/gaming.png b/src/assets/gaming.png
deleted file mode 100644
index b02ffa01a3b3a7267925a1eeb8084ac70c2f132c..0000000000000000000000000000000000000000
Binary files a/src/assets/gaming.png and /dev/null differ
diff --git a/src/assets/golfSpare.gif b/src/assets/golfSpare.gif
deleted file mode 100644
index b67cad84e2dc45e7b95d31b665eae3af1ebc3eb9..0000000000000000000000000000000000000000
Binary files a/src/assets/golfSpare.gif and /dev/null differ
diff --git a/src/assets/head.png b/src/assets/head.png
deleted file mode 100644
index 0e6edb76b40cb4f25b9fa7eef99734d0d7bb90d3..0000000000000000000000000000000000000000
Binary files a/src/assets/head.png and /dev/null differ
diff --git a/src/assets/hjelp.png b/src/assets/hjelp.png
deleted file mode 100644
index c2e97a63818d4786f5128ae3934508da0ce46d76..0000000000000000000000000000000000000000
Binary files a/src/assets/hjelp.png and /dev/null differ
diff --git a/src/assets/hotAirBalloonSpare.gif b/src/assets/hotAirBalloonSpare.gif
deleted file mode 100644
index 78f999f0295efdd779e47f0e74cb33bcd1e8a1ba..0000000000000000000000000000000000000000
Binary files a/src/assets/hotAirBalloonSpare.gif and /dev/null differ
diff --git a/src/assets/litt.png b/src/assets/litt.png
deleted file mode 100644
index 6add972367e016606dbea3a785abd0cc8b398134..0000000000000000000000000000000000000000
Binary files a/src/assets/litt.png and /dev/null differ
diff --git a/src/assets/lock.png b/src/assets/lock.png
deleted file mode 100644
index d4598c4c7e310202edd3b81af5edc13fcecdaf76..0000000000000000000000000000000000000000
Binary files a/src/assets/lock.png and /dev/null differ
diff --git a/src/assets/logo.svg b/src/assets/logo.svg
deleted file mode 100644
index 7565660356e5b3723c9c33d508b830c9cfbea29f..0000000000000000000000000000000000000000
--- a/src/assets/logo.svg
+++ /dev/null
@@ -1 +0,0 @@
-<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 261.76 226.69"><path d="M161.096.001l-30.225 52.351L100.647.001H-.005l130.877 226.688L261.749.001z" fill="#41b883"/><path d="M161.096.001l-30.225 52.351L100.647.001H52.346l78.526 136.01L209.398.001z" fill="#34495e"/></svg>
diff --git a/src/assets/main.css b/src/assets/main.css
deleted file mode 100644
index fb3adbdedd532ef58ec23cf3738f192b8852b7c4..0000000000000000000000000000000000000000
--- a/src/assets/main.css
+++ /dev/null
@@ -1,83 +0,0 @@
-@import './base.css';
-
-@tailwind base;
-@tailwind components;
-@tailwind utilities;
-
-#app {
-    margin: 0 auto auto auto;
-    width: 100%;
-    font-weight: normal;
-
-    display: flex;
-    flex-direction: column;
-}
-
-h1,
-h2,
-h3 {
-    font-weight: bold;
-}
-
-h1 {
-    font-size: 2.5rem;
-    margin-bottom: 1rem;
-}
-
-h2 {
-    font-size: 2rem;
-    margin-bottom: 1rem;
-}
-
-h3 {
-    font-size: 1.5rem;
-    margin-bottom: 1rem;
-}
-
-button {
-    background-color: var(--color-button);
-    color: var(--color-text);
-    border-color: transparent;
-    padding: 0.2rem 1rem;
-    border-radius: 1rem;
-    cursor: pointer;
-    transition: 0.4s;
-}
-
-button:disabled {
-    background-color: var(--color-button-disabled);
-    cursor: not-allowed;
-}
-button:hover {
-    background-color: var(--color-button-hover);
-    transition: 0.7s;
-}
-
-a {
-    text-decoration: none;
-    color: var(--color-text);
-    font-weight: bold;
-    transition: 0.4s;
-}
-
-input {
-    border: 1px solid var(--color-border);
-    padding: 0.5rem 1rem;
-    border-radius: 2rem;
-}
-
-textarea {
-    border: 1px solid var(--color-border);
-    padding: 0.5rem;
-    border-radius: 1rem;
-}
-
-@media (hover: hover) {
-    a:hover {
-        background-color: var(--color-nav-hover);
-        transition: 0.5s;
-        text-decoration: none;
-        padding: 3px 3px;
-        border-radius: 8px;
-    }
-}
diff --git a/src/assets/mat.png b/src/assets/mat.png
deleted file mode 100644
index 4c1dff6b49b35761785ab5eb0d1ba6997925995c..0000000000000000000000000000000000000000
Binary files a/src/assets/mat.png and /dev/null differ
diff --git a/src/assets/nose.png b/src/assets/nose.png
deleted file mode 100644
index 2845ed5555b18c3c03e97d1c193dad506bc63852..0000000000000000000000000000000000000000
Binary files a/src/assets/nose.png and /dev/null differ
diff --git a/src/assets/passe.png b/src/assets/passe.png
deleted file mode 100644
index 7ce43e9f28288fe4b8d8a2c9372d9cf8e8269fb7..0000000000000000000000000000000000000000
Binary files a/src/assets/passe.png and /dev/null differ
diff --git a/src/assets/pending.png b/src/assets/pending.png
deleted file mode 100644
index 3eb5be6856258672869a652316bc9363cb0e236e..0000000000000000000000000000000000000000
Binary files a/src/assets/pending.png and /dev/null differ
diff --git a/src/assets/penger.png b/src/assets/penger.png
deleted file mode 100644
index 9588e23b80536441ee8f2703d4459c8557ff361a..0000000000000000000000000000000000000000
Binary files a/src/assets/penger.png and /dev/null differ
diff --git a/src/assets/pig.png b/src/assets/pig.png
deleted file mode 100644
index 0a10f0f9dabc23d2d2db0654c465448024bd9a66..0000000000000000000000000000000000000000
Binary files a/src/assets/pig.png and /dev/null differ
diff --git a/src/assets/pigSteps.png b/src/assets/pigSteps.png
deleted file mode 100644
index 45309466a7ec3d8b163f5ca4e74671750fc628f2..0000000000000000000000000000000000000000
Binary files a/src/assets/pigSteps.png and /dev/null differ
diff --git a/src/assets/sleepingSpare.gif b/src/assets/sleepingSpare.gif
deleted file mode 100644
index 3ea7d3dcc3f1efaa6c9eb90fa75f70bd9b8856ff..0000000000000000000000000000000000000000
Binary files a/src/assets/sleepingSpare.gif and /dev/null differ
diff --git a/src/assets/snacks.png b/src/assets/snacks.png
deleted file mode 100644
index 45ad39383c62ca25334634bd5747bccab7a4dac3..0000000000000000000000000000000000000000
Binary files a/src/assets/snacks.png and /dev/null differ
diff --git a/src/assets/spare.png b/src/assets/spare.png
deleted file mode 100644
index fe48be94be6ede6652ce0a94d50f581710d7ef07..0000000000000000000000000000000000000000
Binary files a/src/assets/spare.png and /dev/null differ
diff --git a/src/assets/spareSti.png b/src/assets/spareSti.png
deleted file mode 100644
index 90765d5805679e487b8bbdce11d620e7a7a137fb..0000000000000000000000000000000000000000
Binary files a/src/assets/spareSti.png and /dev/null differ
diff --git a/src/assets/spare_og_sti.png b/src/assets/spare_og_sti.png
deleted file mode 100644
index 9716e1ab8e85e9302c7d616e17f486d610855ed3..0000000000000000000000000000000000000000
Binary files a/src/assets/spare_og_sti.png and /dev/null differ
diff --git a/src/assets/start.png b/src/assets/start.png
deleted file mode 100644
index 16b9d574fcf47a1b740dc177c68b35bc45b637cf..0000000000000000000000000000000000000000
Binary files a/src/assets/start.png and /dev/null differ
diff --git a/src/assets/start_page/fly.png b/src/assets/start_page/fly.png
deleted file mode 100644
index 7a0e912c5f15b835f5a84e0d23a024889271d0f8..0000000000000000000000000000000000000000
Binary files a/src/assets/start_page/fly.png and /dev/null differ
diff --git a/src/assets/start_page/skyer.png b/src/assets/start_page/skyer.png
deleted file mode 100644
index 3519c8e0487cdc271167ee1ce3fb3860641e6e23..0000000000000000000000000000000000000000
Binary files a/src/assets/start_page/skyer.png and /dev/null differ
diff --git a/src/assets/start_page/sti.png b/src/assets/start_page/sti.png
deleted file mode 100644
index f9e5dc7e9fb2fc9eddffb78da135fab557846433..0000000000000000000000000000000000000000
Binary files a/src/assets/start_page/sti.png and /dev/null differ
diff --git a/src/assets/start_page/strand.png b/src/assets/start_page/strand.png
deleted file mode 100644
index 597dc0f8398b5d408cae890bb4a8b45f522879f2..0000000000000000000000000000000000000000
Binary files a/src/assets/start_page/strand.png and /dev/null differ
diff --git a/src/assets/store.png b/src/assets/store.png
deleted file mode 100644
index 54bfd38639ed5e7b57f220bf7330750b08e74544..0000000000000000000000000000000000000000
Binary files a/src/assets/store.png and /dev/null differ
diff --git a/src/assets/streak.png b/src/assets/streak.png
deleted file mode 100644
index 16a0e93231f89c033cfb25938f0a97b1fccbeae6..0000000000000000000000000000000000000000
Binary files a/src/assets/streak.png and /dev/null differ
diff --git a/src/assets/streakFlame.png b/src/assets/streakFlame.png
deleted file mode 100644
index 196614ff02ea39e9679190af3a8d0096661a6442..0000000000000000000000000000000000000000
Binary files a/src/assets/streakFlame.png and /dev/null differ
diff --git a/src/assets/varsel.png b/src/assets/varsel.png
deleted file mode 100644
index 2e8c6538317c5812731abefa426216f8a0244698..0000000000000000000000000000000000000000
Binary files a/src/assets/varsel.png and /dev/null differ
diff --git a/src/components/ButtonAddGoalOrChallenge.vue b/src/components/ButtonAddGoalOrChallenge.vue
deleted file mode 100644
index 3516e5c8e1f65d73e58c032fa5c0cd5209dc6404..0000000000000000000000000000000000000000
--- a/src/components/ButtonAddGoalOrChallenge.vue
+++ /dev/null
@@ -1,44 +0,0 @@
-<template>
-    <button
-        class="w-full max-w-60 max-h-12 font-bold py-2 rounded-full flex items-center justify-start pl-4 space-x-2 focus:outline-none focus:ring-2 focus:ring-green-700 focus:ring-opacity-50 shadow-md transition duration-300 ease-in-out text-xs md:text-sm lg:text-base"
-        @click="routeToGoalOrChallenge"
-    >
-        <svg
-            xmlns="http://www.w3.org/2000/svg"
-            fill="none"
-            viewBox="0 0 24 24"
-            stroke="currentColor"
-            class="w-6 h-6"
-        >
-            <path
-                stroke-linecap="round"
-                stroke-linejoin="round"
-                stroke-width="2"
-                d="M12 4v16m8-8H4"
-            />
-        </svg>
-        <span class="truncate">{{ btnText }}</span>
-    </button>
-</template>
-
-<script setup lang="ts">
-import { defineProps, ref } from 'vue'
-import { useRouter } from 'vue-router'
-
-interface Props {
-    buttonText: string
-    type: 'goal' | 'challenge'
-}
-const router = useRouter()
-
-const props = defineProps<Props>()
-const btnText = ref(props.buttonText)
-
-const routeToGoalOrChallenge = () => {
-    if (props.type === 'goal') {
-        router.push('/sparemaal')
-    } else {
-        router.push('/spareutfordringer')
-    }
-}
-</script>
diff --git a/src/components/ButtonDIsplayStreak.vue b/src/components/ButtonDIsplayStreak.vue
deleted file mode 100644
index e5043e4fb746882e19dac98ed5cb8c42de707c1e..0000000000000000000000000000000000000000
--- a/src/components/ButtonDIsplayStreak.vue
+++ /dev/null
@@ -1,76 +0,0 @@
-<template>
-    <div class="flex flex-col items-center">
-        <Span class="text-sm text-bold">STREAK</Span>
-        <button @click="toggleStreakCard" class="bg-transparent">
-            <img src="@/assets/streak.png" alt="streak" class="mx-auto w-12 h-12" />
-        </button>
-
-        <div
-            v-if="displayStreakCard"
-            class="w-96 h-64 duration-500 group overflow-hidden absolute top-32 rounded bg-white-800 text-neutral-50 p-4 flex flex-col justify-evenly"
-        >
-            <div
-                class="absolute blur opacity-40 duration-500 group-hover:blur-none w-72 h-72 rounded-full group-hover:translate-x-12 group-hover:translate-y-12 bg-green-100 right-1 -bottom-24"
-            ></div>
-            <div
-                class="absolute blur opacity-40 duration-500 group-hover:blur-none w-12 h-12 rounded-full group-hover:translate-x-12 group-hover:translate-y-2 bg-green-300 right-12 bottom-12"
-            ></div>
-            <div
-                class="absolute blur opacity-40 duration-500 group-hover:blur-none w-36 h-36 rounded-full group-hover:translate-x-12 group-hover:-translate-y-12 bg-green-500 right-1 -top-12"
-            ></div>
-            <div
-                class="absolute blur opacity-40 duration-500 group-hover:blur-none w-24 h-24 bg-green-400 rounded-full group-hover:-translate-x-12"
-            ></div>
-            <div class="z-10 flex flex-col justify-evenly w-full h-full px-4">
-                <span class="text-2xl font-bold text-black"
-                    >{{ currentStreak }}{{ currentStreak === 1 ? ' dag' : ' dager' }} streak</span
-                >
-                <p class="text-black text-1xl font-bold">
-                    {{
-                        currentStreak > 0
-                            ? 'Bra jobba du har spart i ' + currentStreak + ' dager!'
-                            : 'Du har ikke gjort noe i dag. Gjør noe nå for å starte en streak!'
-                    }}
-                </p>
-                <!-- Row component with horizontal padding and auto margins for centering -->
-                <div
-                    class="flex flex-row justify-content-between items-center h-20 w-full mx-auto bg-black-400 gap-4"
-                >
-                    <div class="flex flex-1 overflow-x-auto">
-                        <div v-for="index in 6" :key="index" class="min-w-max mx-auto">
-                            <div class="flex flex-col items-center">
-                                <span class="text-black"
-                                    >Dag {{ currentStreak - ((currentStreak % 7) - index) }}</span
-                                >
-                                <!-- Conditional rendering for streak images -->
-                                <img
-                                    v-if="index - 1 < currentStreak % 7"
-                                    src="@/assets/streak.png"
-                                    alt="challenge completed"
-                                    class="max-h-8 max-w-8"
-                                />
-                                <img
-                                    v-else
-                                    src="@/assets/streak.png"
-                                    alt="challenge not completed"
-                                    class="max-h-8 max-w-8 grayscale"
-                                />
-                            </div>
-                        </div>
-                    </div>
-                </div>
-            </div>
-        </div>
-    </div>
-</template>
-
-<script setup lang="ts">
-import { ref } from 'vue'
-
-const displayStreakCard = ref(false)
-const currentStreak = ref(20)
-
-function toggleStreakCard() {
-    displayStreakCard.value = !displayStreakCard.value
-}
-</script>
diff --git a/src/components/CardChallenge.vue b/src/components/CardChallenge.vue
deleted file mode 100644
index b2349e03b0c33535a4d0a25512e8543ea7b4a967..0000000000000000000000000000000000000000
--- a/src/components/CardChallenge.vue
+++ /dev/null
@@ -1,36 +0,0 @@
-<script lang="ts" setup>
-import { computed, type PropType } from 'vue'
-import ProgressBar from '@/components/ProgressBar.vue'
-import router from '@/router'
-import type { Challenge } from '@/types/challenge'
-
-const props = defineProps({
-    challengeInstance: {
-        type: Object as PropType<Challenge>,
-        required: true
-    }
-})
-
-const challengeInstance = props.challengeInstance
-const displayDate = computed(() => challengeInstance.due?.slice(0, 16).split('T').join(' '))
-const isCompleted = computed(() => challengeInstance.completedOn != null)
-
-const handleCardClick = () => {
-    router.push({ name: 'view-challenge', params: { id: challengeInstance.id } })
-}
-</script>
-
-<template>
-    <div
-        :class="{ 'bg-green-200 cursor-default': isCompleted }"
-        class="border-2 border-black rounded-xl p-4 flex flex-col items-center gap-2 cursor-pointer w-52 overflow-hidden"
-        @click="handleCardClick"
-    >
-        <h3 class="my-0 mx-6">{{ challengeInstance.title }}</h3>
-        <p>{{ challengeInstance.saved }}kr / {{ challengeInstance.target }}kr</p>
-        <ProgressBar :completion="challengeInstance.completion" />
-        <p>{{ displayDate }}</p>
-    </div>
-</template>
-
-<style scoped></style>
diff --git a/src/components/CardGoal.vue b/src/components/CardGoal.vue
deleted file mode 100644
index f04058b90dc740d2ec1d11b132f3cd6639344005..0000000000000000000000000000000000000000
--- a/src/components/CardGoal.vue
+++ /dev/null
@@ -1,42 +0,0 @@
-<script lang="ts" setup>
-import type { Goal } from '@/types/goal'
-import { computed, type PropType } from 'vue'
-import ProgressBar from '@/components/ProgressBar.vue'
-import router from '@/router'
-
-const props = defineProps({
-    goalInstance: {
-        type: Object as PropType<Goal>,
-        required: true
-    },
-    isClickable: {
-        type: Boolean,
-        default: true
-    }
-})
-
-const goalInstance = props.goalInstance
-const displayDate = computed(() => goalInstance.due?.slice(0, 16).split('T').join(' '))
-const isCompleted = computed(() => goalInstance.completedOn != null)
-
-const handleCardClick = () => {
-    if (props.isClickable) {
-        router.push({ name: 'view-goal', params: { id: goalInstance.id } })
-    }
-}
-</script>
-
-<template>
-    <div
-        :class="{ 'bg-green-200 cursor-default': isCompleted }"
-        class="border-2 border-black rounded-xl p-4 flex flex-col items-center gap-2 cursor-pointer w-52 overflow-hidden"
-        @click="handleCardClick"
-    >
-        <h3 class="my-0 mx-6">{{ goalInstance.title }}</h3>
-        <p>{{ goalInstance.saved }}kr / {{ goalInstance.target }}kr</p>
-        <ProgressBar :completion="goalInstance.completion" />
-        <p>{{ displayDate }}</p>
-    </div>
-</template>
-
-<style scoped></style>
diff --git a/src/components/ContinueButtonComponent.vue b/src/components/ContinueButtonComponent.vue
deleted file mode 100644
index 54a0825553b94e865ab72579d7e64c5400fed7fa..0000000000000000000000000000000000000000
--- a/src/components/ContinueButtonComponent.vue
+++ /dev/null
@@ -1,26 +0,0 @@
-<template>
-    <button
-        :class="{ 'opacity-60 cursor-not-allowed': disabled }"
-        :disabled="disabled"
-        @click="handleClick"
-        class="p-3 px-20 text-lg rounded-lg cursor-pointer transition-all font-bold bg-[var(--green)] hover:brightness-90 active:brightness-75"
-    >
-        Fortsett
-    </button>
-</template>
-
-<script setup lang="ts">
-import { defineEmits, defineProps } from 'vue'
-
-const props = defineProps({
-    disabled: Boolean
-})
-
-const emit = defineEmits(['click'])
-
-const handleClick = () => {
-    if (!props.disabled) {
-        emit('click')
-    }
-}
-</script>
diff --git a/src/components/FormLogin.vue b/src/components/FormLogin.vue
deleted file mode 100644
index 363580072249635f9a74c6a5e1e9ec0eac6cbdc3..0000000000000000000000000000000000000000
--- a/src/components/FormLogin.vue
+++ /dev/null
@@ -1,178 +0,0 @@
-<script lang="ts" setup>
-import { computed, ref, watch } from 'vue'
-import { useUserStore } from '@/stores/userStore'
-import ModalComponent from '@/components/ModalComponent.vue'
-import axios from 'axios'
-
-const username = ref<string>('')
-const password = ref<string>('')
-const showPassword = ref<boolean>(false)
-const errorMessage = ref<string>('')
-const isModalOpen = ref<boolean>(false)
-const resetEmail = ref<string>('')
-const emailRegex = /^[a-zA-Z0-9_+&*-]+(?:\.[a-zA-Z0-9_+&*-]+)*@(?:[a-zA-Z0-9-]+\.)+[a-zA-Z]{2,7}$/
-
-const userStore = useUserStore()
-
-const isEmailValid = computed(() => emailRegex.test(resetEmail.value))
-const isSendingEmail = ref(false)
-const successMessage = ref<string>('')
-const modalErrorMessage = ref<string>('')
-
-const submitForm = () => {
-    userStore.login(username.value, password.value)
-}
-
-const bioLogin = () => {
-    userStore.bioLogin(username.value)
-}
-
-const toggleShowPassword = () => {
-    showPassword.value = !showPassword.value
-}
-
-const openForgotPasswordModal = (event: MouseEvent) => {
-    event.preventDefault()
-    isModalOpen.value = true
-}
-
-const submitReset = async () => {
-    isSendingEmail.value = true
-    modalErrorMessage.value = ''
-    successMessage.value = ''
-    try {
-        const response = await axios.post(
-            'http://localhost:8080/forgotPassword/changePasswordRequest',
-            {
-                email: resetEmail.value
-            }
-        )
-        successMessage.value =
-            'E-posten er sendt. Vennligst sjekk innboksen din for instrukser. OBS: E-posten kan havne i spam-mappen'
-        isSendingEmail.value = false
-        setTimeout(() => {
-            isModalOpen.value = false
-            successMessage.value = ''
-        }, 5000)
-    } catch (error) {
-        console.error(error)
-        modalErrorMessage.value = 'Noe gikk galt. Vennligst prøv igjen.'
-        isSendingEmail.value = false
-    }
-}
-
-const closeModal = () => {
-    isModalOpen.value = false
-    isSendingEmail.value = false
-    modalErrorMessage.value = ''
-    resetEmail.value = ''
-    successMessage.value = ''
-}
-
-watch(
-    () => userStore.errorMessage,
-    (newValue: string) => {
-        errorMessage.value = newValue
-    }
-)
-</script>
-
-<template>
-    <div class="flex flex-col justify-center gap-5 w-full">
-        <div class="flex flex-col">
-            <p class="mx-4">Brukernavn</p>
-            <input
-                v-model="username"
-                name="username"
-                placeholder="Skriv inn brukernavn"
-                type="text"
-            />
-        </div>
-        <div class="flex flex-col">
-            <p class="mx-4">Passord</p>
-            <div class="relative">
-                <input
-                    name="password"
-                    v-model="password"
-                    :type="showPassword ? 'text' : 'password'"
-                    class="w-full"
-                    placeholder="Skriv inn passord"
-                />
-                <button
-                    class="absolute right-0 top-1 bg-transparent hover:bg-transparent"
-                    @click="toggleShowPassword"
-                >
-                    {{ showPassword ? '🔓' : '🔒' }}
-                </button>
-                <a
-                    @click="openForgotPasswordModal"
-                    class="transition-none absolute right-3 top-10 hover:underline hover:bg-transparent text-[#ef9691] hover:transition-none hover:p-0 cursor-pointer"
-                    >Glemt passord?</a
-                >
-            </div>
-        </div>
-        <div class="flex flex-row gap-5">
-            <button
-                name="submit"
-                :disabled="'' == username.valueOf() || '' == password.valueOf()"
-                class="grow-0"
-                @click="submitForm"
-            >
-                Logg inn
-            </button>
-            <p>{{ errorMessage }}</p>
-            <button @click="bioLogin">biologin</button>
-        </div>
-    </div>
-    <modal-component
-        :title="'Glemt passord'"
-        :message="'Vennligst skriv inn e-posten din for å endre passordet.'"
-        :is-modal-open="isModalOpen"
-        @close="closeModal"
-    >
-        <template v-slot:input>
-            <div v-if="isSendingEmail" class="flex justify-center items-center">
-                <div
-                    class="p-3 animate-spin drop-shadow-2xl bg-gradient-to-r from-lime-500 from-30% to-green-600 to-90% md:w-18 md:h-20 h-20 w-20 aspect-square rounded-full"
-                >
-                    <div class="rounded-full h-full w-full bg-slate-100 background-blur-md"></div>
-                </div>
-            </div>
-            <div v-else-if="successMessage">
-                <p class="text-green-500 text-center">{{ successMessage }}</p>
-            </div>
-            <div v-else-if="modalErrorMessage">
-                <p class="text-red-500 text-center">{{ modalErrorMessage }}</p>
-                <button
-                    @click="closeModal"
-                    class="active-button font-bold py-2 px-4 w-1/2 mt-4 border-2 disabled:border-transparent"
-                >
-                    Lukk
-                </button>
-            </div>
-            <div v-else>
-                <input
-                    type="email"
-                    v-model="resetEmail"
-                    class="border border-gray-300 p-2 w-full mb-7"
-                    placeholder="Skriv e-postadressen din her"
-                />
-                <div class="flex gap-5 mt-4">
-                    <button
-                        :disabled="!isEmailValid"
-                        @click="submitReset"
-                        class="active-button font-bold py-2 px-4 w-1/2 border-2 disabled:border-transparent"
-                    >
-                        Send mail
-                    </button>
-                    <button
-                        @click="closeModal"
-                        class="active-button font-bold py-2 px-4 w-1/2 border-2 disabled:border-transparent"
-                    >
-                        Lukk
-                    </button>
-                </div>
-            </div>
-        </template>
-    </modal-component>
-</template>
diff --git a/src/components/FormRegister.vue b/src/components/FormRegister.vue
deleted file mode 100644
index 750dad0a7838f216daeb68e021d402c9bf255789..0000000000000000000000000000000000000000
--- a/src/components/FormRegister.vue
+++ /dev/null
@@ -1,154 +0,0 @@
-<script lang="ts" setup>
-import { computed, ref, watch } from 'vue'
-import { useUserStore } from '@/stores/userStore'
-import ToolTip from '@/components/ToolTip.vue'
-
-const firstname = ref<string>('')
-const lastname = ref<string>('')
-const email = ref<string>('')
-const username = ref<string>('')
-const password = ref<string>('')
-const confirm = ref<string>('')
-
-const showPassword = ref<boolean>(false)
-const errorMessage = ref<string>('')
-
-const userStore = useUserStore()
-
-const nameRegex = /^[æÆøØåÅa-zA-Z,.'-][æÆøØåÅa-zA-Z ,.'-]{1,29}$/
-const emailRegex =
-    /^[æÆøØåÅa-zA-Z0-9_+&*-]+(?:\.[æÆøØåÅa-zA-Z0-9_+&*-]+)*@(?:[æÆøØåÅa-zA-Z0-9-]+\.)+[æÆøØåÅa-zA-Z]{2,7}$/
-const usernameRegex = /^[ÆØÅæøåA-Za-z][æÆøØåÅA-Za-z0-9_]{2,29}$/
-const passwordRegex = /^(?=.*[0-9])(?=.*[a-zæøå])(?=.*[ÆØÅA-Z])(?=.*[@#$%^&+=!])(?=\S+$).{8,30}$/
-
-const isFirstNameValid = computed(() => nameRegex.test(firstname.value) && firstname.value)
-const isLastNameValid = computed(() => nameRegex.test(lastname.value) && lastname.value)
-const isEmailValid = computed(() => emailRegex.test(email.value))
-const isUsernameValid = computed(() => usernameRegex.test(username.value))
-const isPasswordValid = computed(() => passwordRegex.test(password.value))
-
-const isFormInvalid = computed(
-    () =>
-        [isFirstNameValid, isLastNameValid, isEmailValid, isUsernameValid, isPasswordValid].some(
-            (v) => !v.value
-        ) || password.value !== confirm.value
-)
-
-const submitForm = () => {
-    userStore.register(firstname.value, lastname.value, email.value, username.value, password.value)
-}
-
-const toggleShowPassword = () => {
-    showPassword.value = !showPassword.value
-}
-
-watch(
-    () => userStore.errorMessage,
-    (newValue: string) => {
-        errorMessage.value = newValue
-    }
-)
-</script>
-
-<template>
-    <div class="flex flex-col justify-center gap-5 w-full">
-        <div class="flex flex-col">
-            <div class="flex flex-row justify-between mx-4">
-                <p>Fornavn*</p>
-                <ToolTip
-                    :message="'Must include only letters, spaces, commas, apostrophes, periods, and hyphens. 1-30 characters long'"
-                />
-            </div>
-            <input
-                v-model="firstname"
-                name="firstname"
-                :class="{ 'bg-green-200': isFirstNameValid }"
-                placeholder="Skriv inn fornavn"
-                type="text"
-            />
-        </div>
-        <div class="flex flex-col">
-            <div class="flex flex-row justify-between mx-4">
-                <p>Etternavn*</p>
-                <ToolTip
-                    :message="'Must include only letters, spaces, commas, apostrophes, periods, and hyphens. 1-30 characters long'"
-                />
-            </div>
-            <input
-                v-model="lastname"
-                name="lastname"
-                :class="{ 'bg-green-200': isLastNameValid }"
-                placeholder="Skriv inn etternavn"
-                type="text"
-            />
-        </div>
-        <div class="flex flex-col">
-            <div class="flex flex-row justify-between mx-4">
-                <p>E-post*</p>
-                <ToolTip
-                    :message="'Valid email: Starts with Norwegian letters, numbers, or special characters. Includes \@\ followed by a domain. Ends with 2-7 letters.'"
-                />
-            </div>
-            <input
-                v-model="email"
-                name="email"
-                :class="{ 'bg-green-200': isEmailValid }"
-                placeholder="Skriv inn e-post"
-                type="text"
-            />
-        </div>
-        <div class="flex flex-col">
-            <div class="flex flex-row justify-between mx-4">
-                <p>Brukernavn*</p>
-                <ToolTip
-                    :message="'Must start with a letter and can include numbers and underscores. 3-30 characters long.'"
-                />
-            </div>
-            <input
-                v-model="username"
-                name="username"
-                placeholder="Skriv inn brukernavn"
-                type="text"
-                :class="{ 'bg-green-200': isUsernameValid }"
-            />
-        </div>
-        <div class="flex flex-col">
-            <div class="flex flex-row justify-between mx-4">
-                <p>Passord*</p>
-                <ToolTip
-                    :message="'Must be at least 8 characters, including at least one number, one lowercase letter, one uppercase letter, one special character (@#$%^&+=!), and no spaces.'"
-                />
-            </div>
-            <div class="relative">
-                <input
-                    name="password"
-                    v-model="password"
-                    :type="showPassword ? 'text' : 'password'"
-                    placeholder="Skriv inn passord"
-                    class="w-full"
-                    :class="{ 'bg-green-200': isPasswordValid }"
-                />
-                <button
-                    class="absolute right-0 top-1 bg-transparent hover:bg-transparent"
-                    @click="toggleShowPassword"
-                >
-                    {{ showPassword ? '🔓' : '🔒' }}
-                </button>
-            </div>
-            <input
-                v-model="confirm"
-                :class="{ 'bg-green-200': password == confirm && '' !== confirm.valueOf() }"
-                class="mt-2"
-                name="confirm"
-                placeholder="Bekreft passord"
-                type="password"
-            />
-        </div>
-        <div class="flex flex-row gap-5">
-            <button :disabled="isFormInvalid" class="grow-0" name="submit" @click="submitForm">
-                Registrer deg
-            </button>
-            <p>{{ errorMessage }}</p>
-        </div>
-    </div>
-</template>
diff --git a/src/components/InteractiveSpare.vue b/src/components/InteractiveSpare.vue
deleted file mode 100644
index e494738e8df5f7ec5c7a6a22f419b9825f71ccd8..0000000000000000000000000000000000000000
--- a/src/components/InteractiveSpare.vue
+++ /dev/null
@@ -1,181 +0,0 @@
-<template>
-    <ModalComponent :is-modal-open="isModalOpen" @close="isModalOpen = false">
-        <template v-slot:input>
-            <div
-                class="spareDiv flex items-center mr-10 max-w-[60vh] cursor-pointer"
-                :class="{
-                    'flex-row': direction === 'right',
-                    'flex-row-reverse': direction === 'left'
-                }"
-                @click="nextSpeech"
-            >
-                <!-- Image -->
-                <img
-                    :src="spareImageSrc"
-                    :style="{ width: pngSize + 'rem', height: pngSize + 'rem' }"
-                    :class="['object-contain', ...imageClass]"
-                    alt="Spare"
-                    class="w-dynamic h-dynamic object-contain"
-                />
-
-                <!-- Speech Bubble -->
-                <div
-                    v-if="currentSpeech"
-                    :class="`mb-40 inline-block relative w-64 bg-white p-4 rounded-3xl border border-gray-600 tri-right round ${bubbleDirection}`"
-                >
-                    <div class="text-left leading-6">
-                        <p class="speech m-0">{{ currentSpeech }}</p>
-                    </div>
-                </div>
-            </div>
-            <div class="-mb-5 mt-8 text-xs text-gray-500">
-                <p class="justify-center items-center">Trykk for å se hva Spare har å si!</p>
-                <a
-                    @click="clearSpeeches"
-                    class="underline hover:bg-transparent font-normal text-gray-500 cursor-pointer transition-none hover:transition-none hover:p-0"
-                >
-                    Skip
-                </a>
-            </div>
-        </template>
-    </ModalComponent>
-</template>
-
-<script setup lang="ts">
-import { computed, defineProps, ref, watch } from 'vue'
-import spareImageSrc from '@/assets/spare.png'
-import ModalComponent from '@/components/ModalComponent.vue'
-
-interface Props {
-    speech: string[] | null
-    direction: 'left' | 'right'
-    pngSize: number
-    isModalOpen: boolean
-}
-
-const props = defineProps<Props>()
-
-const speech = ref<string[]>(props.speech || [])
-const isModalOpen = ref(props.isModalOpen)
-
-// Watch the speech prop for changes
-watch(
-    () => props.speech,
-    (newVal) => {
-        if (newVal) {
-            // Check if the new value is not null
-            speech.value = newVal // Update the reactive speech array
-            currentSpeechIndex.value = 0 // Reset the speech index
-            isModalOpen.value = true // Open the modal if new speech is available
-        } else {
-            speech.value = [] // Clear the speech array if null is received
-            isModalOpen.value = false // Close the modal if there's no speech
-        }
-    }
-)
-
-const currentSpeechIndex = ref(0)
-const currentSpeech = computed(() => speech.value[currentSpeechIndex.value])
-
-const nextSpeech = () => {
-    if (speech.value.length > 0) {
-        // Remove the currently displayed speech first
-        speech.value.splice(currentSpeechIndex.value, 1)
-
-        // Check if there are any speeches left after removal
-        if (speech.value.length > 0) {
-            // Move to the next speech or reset to the beginning if the current index is out of range
-            currentSpeechIndex.value = currentSpeechIndex.value % speech.value.length
-        } else {
-            // If no speeches left, reset index to indicate no available speech
-            currentSpeechIndex.value = -1
-            // Close the modal if there are no speeches left
-            modalClosed()
-        }
-    }
-}
-
-const imageClass = computed(() => {
-    return [
-        'transform',
-        props.direction === 'right' ? 'scale-x-[-1]' : '' // Flip image if right
-    ]
-})
-
-const bubbleDirection = computed(() => {
-    return props.direction === 'right' ? 'btm-left-in' : 'btm-right-in'
-})
-
-const clearSpeeches = () => {
-    currentSpeechIndex.value = -1
-    modalClosed()
-}
-
-const modalClosed = () => {
-    isModalOpen.value = false
-    currentSpeechIndex.value = -1
-}
-</script>
-<style scoped>
-/* CSS talk bubble */
-
-.border {
-    border: 0.1rem solid black;
-}
-.round {
-    border-radius: 1.875rem;
-    -webkit-border-radius: 1.875rem;
-    -moz-border-radius: 1.875rem;
-}
-
-/*Right triangle, placed bottom left side slightly in*/
-.tri-right.border.btm-left-in:before {
-    content: ' ';
-    position: absolute;
-    width: 0;
-    height: 0;
-    left: 2.3rem;
-    right: auto;
-    top: auto;
-    bottom: -1.5rem;
-    border: 0.7rem solid;
-    border-color: black transparent transparent black;
-}
-.tri-right.btm-left-in:after {
-    content: ' ';
-    position: absolute;
-    width: 0;
-    height: 0;
-    left: 2.375rem;
-    right: auto;
-    top: auto;
-    bottom: -1.25rem;
-    border: 0.75rem solid;
-    border-color: white transparent transparent white;
-}
-
-/*Right triangle, placed bottom right side slightly in*/
-.tri-right.border.btm-right-in:before {
-    content: ' ';
-    position: absolute;
-    width: 0;
-    height: 0;
-    left: auto;
-    right: 2.3rem;
-    top: auto;
-    bottom: -1.5rem;
-    border: 0.7rem solid;
-    border-color: black black transparent transparent;
-}
-.tri-right.btm-right-in:after {
-    content: ' ';
-    position: absolute;
-    width: 0;
-    height: 0;
-    left: auto;
-    right: 2.375rem;
-    bottom: -1.25rem;
-    border: 0.75rem solid;
-    border-color: white white transparent transparent;
-}
-</style>
diff --git a/src/components/ModalComponent.vue b/src/components/ModalComponent.vue
deleted file mode 100644
index f7a6c90f448566d7ab794d525d47afbe586d4666..0000000000000000000000000000000000000000
--- a/src/components/ModalComponent.vue
+++ /dev/null
@@ -1,25 +0,0 @@
-<template>
-    <div
-        v-if="isModalOpen"
-        class="fixed inset-0 bg-black bg-opacity-30 flex justify-center items-center z-50"
-    >
-        <div class="bg-white p-6 rounded-lg shadow-lg max-w-lg w-full text-center">
-            <h2 class="title font-bold mb-4">{{ title }}</h2>
-            <p class="message mb-4">{{ message }}</p>
-
-            <slot name="input"></slot>
-
-            <div class="buttons flex flex-col justify-center items-center gap-3 mt-3 w-full">
-                <slot name="buttons"></slot>
-            </div>
-        </div>
-    </div>
-</template>
-
-<script setup lang="ts">
-defineProps({
-    title: String,
-    message: String,
-    isModalOpen: Boolean
-})
-</script>
diff --git a/src/components/ModalEditAvatar.vue b/src/components/ModalEditAvatar.vue
deleted file mode 100644
index 5474b34e6b346b1206405db3681641638b9f74ff..0000000000000000000000000000000000000000
--- a/src/components/ModalEditAvatar.vue
+++ /dev/null
@@ -1,65 +0,0 @@
-<template>
-    <button @click="openModal" class="text-nowrap">Endre avatar</button>
-    <div
-        v-if="isModalOpen"
-        class="fixed inset-0 bg-black bg-opacity-50 flex justify-center items-center z-50"
-    >
-        <div class="bg-white p-6 rounded-lg shadow-lg max-w-[80vh] h-auto w-full text-center">
-            <h2 class="title">Endre avatar</h2>
-            <div class="avatar-container flex flex-row justify-between items-center my-8">
-                <button @click="cycleArray('prev')">â—€</button>
-                <div class="flex flex-row items-center justify-around">
-                    <img :src="previousAvatar" alt="avatar" class="avatar h-16 w-16" />
-                    <div class="border-4 rounded-full border-green-600 p-8 mx-4">
-                        <img :src="currentAvatar" alt="avatar" class="avatar h-40 w-40" />
-                    </div>
-                    <img :src="nextAvatar" alt="avatar" class="avatar h-16 w-16" />
-                </div>
-                <button @click="cycleArray('next')">â–¶</button>
-            </div>
-            <button @click="saveAvatar" class="save-button">Lagre</button>
-        </div>
-    </div>
-</template>
-
-<script setup lang="ts">
-import { ref } from 'vue'
-
-const isModalOpen = ref(false)
-const avatars = [
-    'src/assets/coffee.png',
-    'src/assets/head.png',
-    'src/assets/nose.png',
-    'src/assets/penger.png',
-    'src/assets/pig.png'
-]
-let currentAvatarIndex = 0
-
-const openModal = () => {
-    isModalOpen.value = !isModalOpen.value
-}
-
-const nextAvatar = ref(avatars[(currentAvatarIndex + 1) % avatars.length])
-const currentAvatar = ref(avatars[currentAvatarIndex])
-const previousAvatar = ref(avatars[(currentAvatarIndex - 1 + avatars.length) % avatars.length])
-
-const cycleArray = (direction: string) => {
-    if (direction === 'prev') {
-        currentAvatarIndex = (currentAvatarIndex - 1 + avatars.length) % avatars.length
-        console.log(currentAvatarIndex)
-        currentAvatar.value = avatars[currentAvatarIndex]
-        previousAvatar.value = avatars[(currentAvatarIndex - 1 + avatars.length) % avatars.length]
-        nextAvatar.value = avatars[(currentAvatarIndex + 1) % avatars.length]
-    } else {
-        currentAvatarIndex = (currentAvatarIndex + 1) % avatars.length
-        currentAvatar.value = avatars[currentAvatarIndex]
-        previousAvatar.value = avatars[(currentAvatarIndex - 1 + avatars.length) % avatars.length]
-        nextAvatar.value = avatars[(currentAvatarIndex + 1) % avatars.length]
-    }
-}
-
-const saveAvatar = () => {
-    localStorage.setItem('avatar', currentAvatar.value)
-    isModalOpen.value = false
-}
-</script>
diff --git a/src/components/NavBarComponent.vue b/src/components/NavBarComponent.vue
deleted file mode 100644
index f73a9e94cf8f39d898f8641c099b9ccc91f0506c..0000000000000000000000000000000000000000
--- a/src/components/NavBarComponent.vue
+++ /dev/null
@@ -1,110 +0,0 @@
-<template>
-    <nav class="flex justify-between items-center min-h-32 text-xl w-full px-3 my-0">
-        <div>
-            <router-link to="/hjem" @click="hamburgerOpen = false">
-                <img
-                    alt="logo"
-                    class="w-40 cursor-pointer transition-transform duration-300 ease-in-out hover:scale-110 hover:opacity-90"
-                    src="@/assets/spareSti.png"
-                />
-            </router-link>
-
-            <div class="flex flex-row justify-center">
-                <img alt="streak" class="w-8 h-8" src="@/assets/streakFlame.png" />
-                <p class="font-bold">Streak</p>
-            </div>
-        </div>
-        <div v-if="!isHamburger" class="flex flex-row gap-10">
-            <router-link active-class="border-b-2" to="/hjem">🏠Hjem</router-link>
-            <router-link active-class="border-b-2" to="/sparemaal">🎯Sparemål</router-link>
-            <router-link active-class="border-b-2" to="/spareutfordringer"
-                >💰Spareutfordringer</router-link
-            >
-            <router-link active-class="border-b-2" to="/profil">🤭Profil</router-link>
-        </div>
-
-        <div v-if="!isHamburger" class="flex justify-center w-40">
-            <button class="focus:ring focus:ring-black-300" @click="openModal">Logg ut</button>
-        </div>
-        <button v-if="isHamburger" @click="toggleMenu">☰</button>
-    </nav>
-
-    <div v-if="hamburgerOpen" class="flex flex-col bg-white border border-slate-300 z-50">
-        <router-link to="/hjem" @click="hamburgerOpen = false">🏠Hjem</router-link>
-        <router-link to="/sparemaal" @click="hamburgerOpen = false">🎯Sparemål</router-link>
-        <router-link to="/spareutfordringer" @click="hamburgerOpen = false"
-            >💰Spareutfordringer</router-link
-        >
-        <router-link to="/profil" @click="hamburgerOpen = false">🤭Profil</router-link>
-        <button class="focus:ring focus:ring-black-300 bg-transparent" @click="openModal">
-            Logg ut
-        </button>
-    </div>
-    <ModalComponent
-        :title="'Vil du logge ut?'"
-        :message="'Er du sikker på at du vil logge ut av SpareSti? Du kan alltid logge inn igjen senere 🕺'"
-        :is-modal-open="isModalOpen"
-        @close="isModalOpen = false"
-    >
-        <template v-slot:buttons>
-            <button
-                @click="logout"
-                class="active-button font-bold py-2 px-4 w-1/2 border-2 disabled:border-transparent"
-            >
-                Logg ut
-            </button>
-            <button
-                @click="closeModal"
-                class="active-button font-bold py-2 px-4 w-1/2 border-2 disabled:border-transparent bg-red-400 hover:bg-red-300"
-            >
-                Avbryt
-            </button>
-        </template>
-    </ModalComponent>
-</template>
-
-<script setup lang="ts">
-import { RouterLink } from 'vue-router'
-import { onMounted, ref } from 'vue'
-import { useUserStore } from '@/stores/userStore'
-import ModalComponent from '@/components/ModalComponent.vue'
-
-const userStore = useUserStore()
-
-const windowWidth = ref(window.innerWidth)
-const hamburgerOpen = ref(false)
-const isHamburger = ref(false)
-const isModalOpen = ref<boolean>(false)
-
-const logout = () => {
-    userStore.logout()
-}
-
-const toggleMenu = () => {
-    hamburgerOpen.value = !hamburgerOpen.value
-}
-
-const updateWindowWidth = () => {
-    windowWidth.value = window.innerWidth
-    if (windowWidth.value < 1150) {
-        isHamburger.value = true
-    } else {
-        isHamburger.value = false
-        hamburgerOpen.value = false
-    }
-}
-
-onMounted(() => {
-    window.addEventListener('resize', updateWindowWidth)
-    updateWindowWidth()
-})
-
-const openModal = (event: MouseEvent) => {
-    event.preventDefault()
-    isModalOpen.value = true
-}
-
-const closeModal = () => {
-    isModalOpen.value = false
-}
-</script>
diff --git a/src/components/PageControl.vue b/src/components/PageControl.vue
deleted file mode 100644
index 3ed526b63868ef5c5270af6045b52f6f53251e70..0000000000000000000000000000000000000000
--- a/src/components/PageControl.vue
+++ /dev/null
@@ -1,34 +0,0 @@
-<script lang="ts" setup>
-defineProps({
-    currentPage: {
-        type: Number,
-        required: true
-    },
-    totalPages: {
-        type: Number,
-        required: true
-    },
-    onPageChange: {
-        type: Function,
-        default: () => {}
-    }
-})
-</script>
-
-<template>
-    <div v-if="totalPages > 0" class="flex justify-center gap-4">
-        <button :disabled="currentPage === 0" @click="onPageChange(currentPage - 1)">
-            Forrige
-        </button>
-        <p>{{ currentPage + 1 }} / {{ totalPages }}</p>
-        <button :disabled="currentPage === totalPages - 1" @click="onPageChange(currentPage + 1)">
-            Neste
-        </button>
-    </div>
-</template>
-
-<style scoped>
-button:disabled:hover {
-    background-color: #cbcbcb;
-}
-</style>
diff --git a/src/components/ProgressBar.vue b/src/components/ProgressBar.vue
deleted file mode 100644
index 770c75b9bbd250fa7c55ae5d4b1cdbd11ea3312b..0000000000000000000000000000000000000000
--- a/src/components/ProgressBar.vue
+++ /dev/null
@@ -1,13 +0,0 @@
-<script lang="ts" setup>
-defineProps({
-    completion: Number
-})
-</script>
-
-<template>
-    <div class="w-full bg-gray-200 rounded-full overflow-hidden">
-        <div :style="{ width: completion + '%' }" class="bg-green-500 h-2 rounded-full"></div>
-    </div>
-</template>
-
-<style scoped></style>
diff --git a/src/components/SavingsPath.vue b/src/components/SavingsPath.vue
index e2d963e7d8cdac633f328c19b09727a679b1ebc3..e0eefe109987a664c2953f47ffc8b0e2583186e4 100644
--- a/src/components/SavingsPath.vue
+++ b/src/components/SavingsPath.vue
@@ -1,6 +1,6 @@
 <template>
     <div
-        class="flex flex-col basis-2/3 max-h-full mx-auto max-w-5/6 md:basis-3/4 md:pr-20 md:max-mr-20"
+        class="flex flex-col basis-2/3 max-h-full mx-auto md:ml-20 md:mr-2 max-w-5/6 md:basis-3/4 md:max-pr-20 md:pr-10 md:max-mr-20"
     >
         <div class="flex justify-center align-center">
             <span
@@ -9,18 +9,28 @@
                 Din Sparesti
             </span>
         </div>
+        <button
+            class="h-auto w-auto absolute flex text-center self-end mr-10 md:mr-20 text-wrap shadow-sm shadow-black sm:top-50 sm:text-xs sm:mr-20 lg:mr-32 top-60 z-50 p-2 text-xs md:text-sm"
+            @click="scrollToFirstUncompleted"
+            v-show="!isAtFirstUncompleted"
+        >
+            Ufullførte utfordringer<br />↓
+        </button>
         <div class="h-1 w-4/6 mx-auto my-2 opacity-10"></div>
         <div
             ref="containerRef"
-            class="container relative mx-auto pt-6 w-4/5 md:w-3/5 no-scrollbar h-full max-h-[60vh] md:max-h-[60v] overflow-y-auto border-2 border-slate-300 rounded-lg bg-white shadow-lg"
+            class="container relative pt-6 w-4/5 bg-cover bg-[center] md:[background-position: center;] mx-auto md:w-4/5 no-scrollbar h-full max-h-[60vh] md:max-h-[60vh] md:min-w-2/5 overflow-y-auto border-2 border-transparent rounded-xl bg-white shadow-lg shadow-slate-400"
+            style="background-image: url('src/assets/backgroundSavingsPath.png')"
         >
             <div>
                 <img src="@/assets/start.png" alt="Spare" class="md:w-1/6 md:h-auto h-20" />
             </div>
+
             <div
                 v-for="(challenge, index) in challenges"
-                :key="challenge.title"
+                :key="challenge.id"
                 class="flex flex-col items-center"
+                :ref="(el) => assignRef(el, challenge, index)"
             >
                 <!-- Challenge Row -->
                 <div
@@ -31,31 +41,44 @@
                     class="flex flex-row w-4/5 gap-8"
                 >
                     <div class="right-auto just">
-                        <img
-                            v-if="index === 3"
-                            src="@/assets/sleepingSpare.gif"
-                            alt="could not load"
-                            class="w-32 h-32 border-2 rounded-lg border-stale-400"
-                        />
-                        <img
-                            v-else-if="index === 1"
-                            src="@/assets/golfSpare.gif"
-                            alt="could not load"
-                            class="w-32 h-32 border-2 rounded-lg border-stale-400"
-                        />
+                        <img-gif-template
+                            :index="index"
+                            :mod-value="1"
+                            url="src/assets/golfSpare.gif"
+                        ></img-gif-template>
+                        <img-gif-template
+                            :index="index"
+                            :mod-value="3"
+                            url="src/assets/sleepingSpare.gif"
+                        ></img-gif-template>
+                        <img-gif-template
+                            :index="index"
+                            :mod-value="5"
+                            url="src/assets/archerSpare.gif"
+                        ></img-gif-template>
                     </div>
                     <!-- Challenge Icon and Details -->
                     <div class="flex">
                         <!-- Challenge Icon -->
-                        <div class="flex flex-col items-center">
-                            <p class="text-center" data-cy="challenge-title">
-                                {{ challenge.title }}
-                            </p>
+                        <div class="flex flex-col items-center gap-4">
+                            <div class="flex flex-row flex-nowrap">
+                                <p
+                                    class="text-center text-wrap text-xs md:text-lg"
+                                    data-cy="challenge-title"
+                                >
+                                    {{ challenge.title }}
+                                </p>
+                                <display-info-for-challenge-or-goal
+                                    :goal="goal"
+                                    :challenge="challenge"
+                                    :is-challenge="true"
+                                ></display-info-for-challenge-or-goal>
+                            </div>
                             <img
                                 @click="editChallenge(challenge)"
                                 :data-cy="'challenge-icon-' + challenge.id"
                                 :src="getChallengeIcon(challenge)"
-                                class="max-w-20 max-h-20 cursor-pointer"
+                                class="max-w-20 max-h-20 cursor-pointer hover:scale-125"
                                 :alt="challenge.title"
                             />
                             <!-- Progress Bar, if the challenge is not complete -->
@@ -65,7 +88,7 @@
                                 "
                                 class="flex-grow w-full mt-2"
                             >
-                                <div class="flex flex-row">
+                                <div class="flex flex-row ml-5 md:ml-10 justify-center">
                                     <div class="flex flex-col">
                                         <div
                                             class="bg-gray-200 rounded-full h-2.5 dark:bg-gray-700"
@@ -80,7 +103,7 @@
                                                 }"
                                             ></div>
                                         </div>
-                                        <div class="text-center">
+                                        <div class="text-center text-xs md:text-base">
                                             {{ challenge.saved }}kr / {{ challenge.target }}kr
                                         </div>
                                     </div>
@@ -95,12 +118,14 @@
                                     </button>
                                 </div>
                             </div>
-                            <span v-else class="text-center">Ferdig: {{ challenge.saved }}</span>
+                            <span v-else class="text-center text-xs md:text-base"
+                                >Ferdig: {{ challenge.saved }}</span
+                            >
                         </div>
                         <!-- Check Icon -->
                         <div
                             v-if="challenge.completion !== undefined && challenge.completion >= 100"
-                            class="max-w-10 max-h-10"
+                            class="md:max-w-10 min-w-4 max-w-6 max-h-6 w-full h-auto md:max-h-10 min-h-4"
                         >
                             <img src="@/assets/completed.png" alt="" />️
                         </div>
@@ -109,18 +134,21 @@
                         </div>
                     </div>
                     <div class="">
-                        <img
-                            v-if="index === 0"
-                            src="@/assets/cowboySpare.gif"
-                            alt="could not load"
-                            class="h-32 w-32 border-2 rounded-lg border-stale-400"
-                        />
-                        <img
-                            v-else-if="index === 2"
-                            src="@/assets/hotAirBalloonSpare.gif"
-                            class="h-32 w-32 border-stale-400 border-2 rounded-lg"
-                            alt="could not load"
-                        />
+                        <img-gif-template
+                            :index="index"
+                            :mod-value="0"
+                            url="src/assets/cowboySpare.gif"
+                        ></img-gif-template>
+                        <img-gif-template
+                            :index="index"
+                            :mod-value="2"
+                            url="src/assets/hotAirBalloonSpare.gif"
+                        ></img-gif-template>
+                        <img-gif-template
+                            :index="index"
+                            :mod-value="4"
+                            url="src/assets/farmerSpare.gif"
+                        ></img-gif-template>
                     </div>
                 </div>
                 <!-- Piggy Steps, centered -->
@@ -155,9 +183,17 @@
         </div>
         <!-- Goal -->
         <div v-if="goal" class="flex flex-row justify-around m-t-2 pt-6 w-full mx-auto">
-            <div class="flex flex-col items-start cursor-pointer" @click="editGoal(goal)">
-                <img :src="getGoalIcon(goal)" class="w-12 h-12 mx-auto" :alt="goal.title" />
-                <div class="text-lg font-bold" data-cy="goal-title">{{ goal.title }}</div>
+            <div class="grid grid-rows-2 grid-flow-col gap 4">
+                <div class="row-span-3 cursor-pointer" @click="editGoal(goal)">
+                    <img :src="getGoalIcon(goal)" class="w-12 h-12 mx-auto" :alt="goal.title" />
+                    <div class="text-lg font-bold" data-cy="goal-title">{{ goal.title }}</div>
+                </div>
+                <display-info-for-challenge-or-goal
+                    class="col-span-2"
+                    :goal="goal"
+                    :challenge="null"
+                    :is-challenge="false"
+                ></display-info-for-challenge-or-goal>
             </div>
             <div class="flex flex-col items-end">
                 <div @click="goToEditGoal" class="cursor-pointer">
@@ -166,7 +202,6 @@
                 <div
                     ref="targetRef"
                     class="bg-yellow-400 px-4 py-1 rounded-full text-black font-bold"
-                    v-if="goal.saved >= goal.target"
                 >
                     {{ goal.saved }}kr / {{ goal.target }}kr
                 </div>
@@ -183,7 +218,16 @@
 </template>
 
 <script setup lang="ts">
-import { nextTick, onMounted, type Ref, ref, watch } from 'vue'
+import {
+    type ComponentPublicInstance,
+    nextTick,
+    onMounted,
+    onUnmounted,
+    reactive,
+    type Ref,
+    ref,
+    watch
+} from 'vue'
 import anime from 'animejs'
 import type { Challenge } from '@/types/challenge'
 import type { Goal } from '@/types/goal'
@@ -191,6 +235,8 @@ import confetti from 'canvas-confetti'
 import { useRouter } from 'vue-router'
 import { useGoalStore } from '@/stores/goalStore'
 import { useChallengeStore } from '@/stores/challengeStore'
+import DisplayInfoForChallengeOrGoal from '@/components/DisplayInfoForChallengeOrGoal.vue'
+import ImgGifTemplate from '@/components/ImgGifTemplate.vue'
 
 const router = useRouter()
 const goalStore = useGoalStore()
@@ -205,6 +251,110 @@ const props = defineProps<Props>()
 const challenges = ref<Challenge[]>(props.challenges)
 const goal = ref<Goal | null | undefined>(props.goal)
 
+onMounted(async () => {
+    await goalStore.getUserGoals()
+    window.addEventListener('resize', handleWindowSizeChange)
+    handleWindowSizeChange()
+    sortChallenges()
+})
+
+const sortChallenges = () => {
+    challenges.value.sort((a, b) => {
+        // First, sort by completion status: non-completed (less than 100) before completed (100)
+        if (a.completion !== 100 && b.completion === 100) {
+            return 1 // 'a' is not completed and 'b' is completed, 'a' should come first
+        } else if (a.completion === 100 && b.completion !== 100) {
+            return -1 // 'a' is completed and 'b' is not, 'b' should come first
+        } else {
+            // Explicitly convert dates to numbers for subtraction
+            const dateA = new Date(a.due).getTime()
+            const dateB = new Date(b.due).getTime()
+            return dateA - dateB
+        }
+    })
+}
+
+const screenSize = ref<number>(window.innerWidth)
+
+onUnmounted(() => {
+    window.removeEventListener('resize', handleWindowSizeChange)
+})
+const handleWindowSizeChange = () => {
+    screenSize.value = window.innerWidth
+}
+
+interface ElementRefs {
+    [key: string]: HTMLElement | undefined
+}
+
+const elementRefs = reactive<ElementRefs>({})
+
+const isAtFirstUncompleted = ref(false) // This state tracks visibility of the button
+const firstUncompletedRef: Ref<HTMLElement | undefined> = ref()
+
+function scrollToFirstUncompleted() {
+    let found = false
+    for (let i = 0; i < challenges.value.length; i++) {
+        if (challenges.value[i].completion! < 100) {
+            const refKey = `uncompleted-${i}`
+            if (elementRefs[refKey]) {
+                elementRefs[refKey]!.scrollIntoView({ behavior: 'smooth', block: 'start' })
+                firstUncompletedRef.value = elementRefs[refKey] // Store the reference
+                found = true
+                isAtFirstUncompleted.value = true
+                break
+            }
+        }
+    }
+    if (!found) {
+        isAtFirstUncompleted.value = false
+    }
+}
+
+onMounted(() => {
+    const container = containerRef.value
+    if (container) {
+        container.addEventListener('scroll', () => {
+            if (!firstUncompletedRef.value) return
+            const containerRect = container.getBoundingClientRect()
+            const firstUncompletedRect = firstUncompletedRef.value.getBoundingClientRect()
+            isAtFirstUncompleted.value = !(
+                firstUncompletedRect.top > containerRect.bottom ||
+                firstUncompletedRect.bottom < containerRect.top
+            )
+        })
+    }
+    scrollToFirstUncompleted()
+})
+
+onUnmounted(() => {
+    const container = containerRef.value
+    if (container) {
+        container.removeEventListener('scroll', () => {
+            // Clean up the scroll listener
+        })
+    }
+})
+
+const assignRef = (
+    el: Element | ComponentPublicInstance | null,
+    challenge: Challenge,
+    index: number
+) => {
+    const refKey = `uncompleted-${index}`
+    if (el instanceof HTMLElement) {
+        // Ensure that el is an HTMLElement
+        if (challenge.completion! < 100) {
+            elementRefs[refKey] = el
+        }
+    } else {
+        // Cleanup if the element is unmounted or not an HTMLElement
+        if (elementRefs[refKey]) {
+            delete elementRefs[refKey]
+        }
+    }
+}
+
 // Utilizing watch to specifically monitor for changes in the props
 watch(
     () => props.goal,
@@ -221,6 +371,7 @@ watch(
     (newChallenges, oldChallenges) => {
         if (newChallenges !== oldChallenges) {
             challenges.value = newChallenges
+            sortChallenges()
         }
     },
     { immediate: true }
@@ -242,15 +393,13 @@ const addSpareUtfordring = () => {
 
 // Increment saved amount
 const incrementSaved = async (challenge: Challenge) => {
-    // Set a default increment amount per purchase
-    challenge.perPurchase = 20
-
     // Safely increment the saved amount, ensuring it exists
     challenge.saved += challenge.perPurchase
 
     // Check if the saved amount meets or exceeds the target
     if (challenge.saved >= challenge.target) {
         challenge.completion = 100
+        await challengeStore.completeUserChallenge(challenge)
     }
 
     // Safely update the goal's saved value, ensuring goal.value exists and is not null
diff --git a/src/components/ToolTip.vue b/src/components/ToolTip.vue
deleted file mode 100644
index ab2e58b9cbd31702490c7612e121f2252c82446f..0000000000000000000000000000000000000000
--- a/src/components/ToolTip.vue
+++ /dev/null
@@ -1,36 +0,0 @@
-<script lang="ts" setup>
-import { ref } from 'vue'
-
-defineProps({
-    message: String
-})
-
-const show = ref(false)
-
-const toggleShow = () => {
-    show.value = !show.value
-}
-</script>
-
-<template>
-    <div class="relative">
-        <div
-            class="cursor-pointer"
-            tabindex="0"
-            @mouseleave="show = false"
-            @mouseover="show = true"
-            @keydown.space.prevent="toggleShow"
-            @keydown.enter.prevent="toggleShow"
-        >
-            (?)
-        </div>
-        <div
-            v-if="show"
-            class="absolute -inset-x-36 z-10 p-2 mt-2 w-40 text-sm bg-gray-100 rounded shadow-lg"
-        >
-            {{ message }}
-        </div>
-    </div>
-</template>
-
-<style scoped></style>
diff --git a/src/components/__tests__/ButtonAddGoalOrChallengeTest.spec.ts b/src/components/__tests__/ButtonAddGoalOrChallengeTest.spec.ts
deleted file mode 100644
index 796c198f8b0dc97d32c41dcab9ee86b2f5fd3027..0000000000000000000000000000000000000000
--- a/src/components/__tests__/ButtonAddGoalOrChallengeTest.spec.ts
+++ /dev/null
@@ -1,26 +0,0 @@
-import { describe, expect, it } from 'vitest'
-import { mount } from '@vue/test-utils'
-import ButtonComponent from '@/components/ButtonAddGoalOrChallenge.vue'
-
-describe('ButtonComponent', () => {
-    it('renders correctly', () => {
-        const wrapper = mount(ButtonComponent, {
-            props: {
-                buttonText: 'Click me',
-                type: 'goal'
-            }
-        })
-        expect(wrapper.exists()).toBe(true)
-    })
-
-    it('displays the correct button text', () => {
-        const wrapper = mount(ButtonComponent, {
-            props: {
-                buttonText: 'Submit',
-                type: 'goal'
-            }
-        })
-        const buttonText = wrapper.find('span.truncate')
-        expect(buttonText.text()).toBe('Submit')
-    })
-})
diff --git a/src/components/__tests__/CardChallengeTest.spec.ts b/src/components/__tests__/CardChallengeTest.spec.ts
deleted file mode 100644
index 726d7e59708b7add55d35ef777e7e90e01248259..0000000000000000000000000000000000000000
--- a/src/components/__tests__/CardChallengeTest.spec.ts
+++ /dev/null
@@ -1,71 +0,0 @@
-import { describe, expect, it } from 'vitest'
-import { mount } from '@vue/test-utils'
-import CardChallenge from '../CardChallenge.vue'
-import type { Challenge } from '../../types/challenge'
-
-describe('CardChallenge', () => {
-    let incompleteWrapper: any
-    let completeWrapper: any
-
-    const incompleteChallenge: Challenge = {
-        id: 1,
-        title: 'Test title',
-        perPurchase: 10,
-        saved: 100,
-        target: 1000,
-        description: 'Test description',
-        due: '2022-01-01T00:00:00Z',
-        createdOn: '2021-01-01T00:00:00Z',
-        type: 'Challenge type',
-        completion: 10
-    }
-
-    const completeChallenge: Challenge = {
-        id: 1,
-        title: 'Test title',
-        perPurchase: 10,
-        saved: 100,
-        target: 1000,
-        description: 'Test description',
-        due: '2022-01-01T00:00:00Z',
-        createdOn: '2021-01-01T00:00:00Z',
-        type: 'Challenge type',
-        completion: 10,
-        completedOn: '2022-01-01T00:00:00Z'
-    }
-
-    const mountIncompletedWrapper = async () => {
-        incompleteWrapper = mount(CardChallenge, {
-            propsData: {
-                challengeInstance: incompleteChallenge
-            }
-        })
-        await incompleteWrapper.vm.$nextTick()
-    }
-
-    const mountCompleteWrapper = async () => {
-        completeWrapper = mount(CardChallenge, {
-            propsData: {
-                challengeInstance: completeChallenge
-            }
-        })
-        await completeWrapper.vm.$nextTick()
-    }
-
-    it('renders correctly', () => {
-        mountIncompletedWrapper()
-        expect(incompleteWrapper.text()).toContain('Test title')
-        expect(incompleteWrapper.text()).toContain('100kr / 1000kr')
-        expect(incompleteWrapper.text()).toContain('2022-01-01 00:00')
-    })
-
-    it('sets isCompleted to false', () => {
-        mountIncompletedWrapper()
-        expect(incompleteWrapper.vm.isCompleted).toBe(false)
-    })
-
-    it('sets isCompleted to true', () => {
-        mountCompleteWrapper()
-        expect(completeWrapper.vm.isCompleted).toBe(true)
-    })
-})
diff --git a/src/components/__tests__/CardGoalTest.spec.ts b/src/components/__tests__/CardGoalTest.spec.ts
deleted file mode 100644
index 1ada562db10c85a49537a0a0833891479848aa42..0000000000000000000000000000000000000000
--- a/src/components/__tests__/CardGoalTest.spec.ts
+++ /dev/null
@@ -1,67 +0,0 @@
-import { describe, expect, it } from 'vitest'
-import { mount } from '@vue/test-utils'
-import CardGoal from '../CardGoal.vue'
-import type { Goal } from '../../types/goal'
-
-describe('CardGoal', () => {
-    let incompleteWrapper: any
-    let completeWrapper: any
-
-    const incompleteGoal: Goal = {
-        id: 1,
-        title: 'Test title',
-        saved: 100,
-        target: 1000,
-        description: 'Test description',
-        due: '2022-01-01T00:00:00Z',
-        createdOn: '2021-01-01T00:00:00Z',
-        completion: 10
-    }
-
-    const completeGoal: Goal = {
-        id: 1,
-        title: 'Test title',
-        saved: 100,
-        target: 1000,
-        description: 'Test description',
-        due: '2022-01-01T00:00:00Z',
-        createdOn: '2021-01-01T00:00:00Z',
-        completion: 10,
-        completedOn: '2022-01-01T00:00:00Z'
-    }
-
-    const mountIncompletedWrapper = async () => {
-        incompleteWrapper = mount(CardGoal, {
-            propsData: {
-                goalInstance: incompleteGoal
-            }
-        })
-        await incompleteWrapper.vm.$nextTick()
-    }
-
-    const mountCompleteWrapper = async () => {
-        completeWrapper = mount(CardGoal, {
-            propsData: {
-                goalInstance: completeGoal
-            }
-        })
-        await completeWrapper.vm.$nextTick()
-    }
-
-    it('renders correctly', () => {
-        mountIncompletedWrapper()
-        expect(incompleteWrapper.text()).toContain('Test title')
-        expect(incompleteWrapper.text()).toContain('100kr / 1000kr')
-        expect(incompleteWrapper.text()).toContain('2022-01-01 00:00')
-    })
-
-    it('sets isCompleted to false', () => {
-        mountIncompletedWrapper()
-        expect(incompleteWrapper.vm.isCompleted).toBe(false)
-    })
-
-    it('sets isCompleted to true', () => {
-        mountCompleteWrapper()
-        expect(completeWrapper.vm.isCompleted).toBe(true)
-    })
-})
diff --git a/src/components/__tests__/ContinueButtonTest.spec.ts b/src/components/__tests__/ContinueButtonTest.spec.ts
deleted file mode 100644
index cc9285c7abb1bfbd9fec3b5b308865068fec964c..0000000000000000000000000000000000000000
--- a/src/components/__tests__/ContinueButtonTest.spec.ts
+++ /dev/null
@@ -1,36 +0,0 @@
-import { describe, expect, it } from 'vitest'
-import { mount } from '@vue/test-utils'
-import ContinueButtonComponent from '@/components/ContinueButtonComponent.vue'
-
-describe('ContinueButtonComponent', () => {
-    it('renders correctly', () => {
-        const wrapper = mount(ContinueButtonComponent)
-        expect(wrapper.text()).toContain('Fortsett')
-    })
-
-    it('is disabled when the `disabled` prop is true', () => {
-        const wrapper = mount(ContinueButtonComponent, {
-            props: { disabled: true }
-        })
-        const button = wrapper.find('button')
-        expect(button.attributes('disabled')).toBeDefined()
-        expect(button.classes()).toContain('opacity-60')
-        expect(button.classes()).toContain('cursor-not-allowed')
-    })
-
-    it('does not emit click event when disabled', async () => {
-        const wrapper = mount(ContinueButtonComponent, {
-            props: { disabled: true }
-        })
-        await wrapper.trigger('click')
-        expect(wrapper.emitted()).not.toHaveProperty('click')
-    })
-
-    it('emits click event when not disabled', async () => {
-        const wrapper = mount(ContinueButtonComponent, {
-            props: { disabled: false }
-        })
-        await wrapper.trigger('click')
-        expect(wrapper.emitted()).toHaveProperty('click')
-    })
-})
diff --git a/src/components/__tests__/FormLoginTest.spec.ts b/src/components/__tests__/FormLoginTest.spec.ts
deleted file mode 100644
index ff05225207f4cb7de16668f3d79caf6afe022bb8..0000000000000000000000000000000000000000
--- a/src/components/__tests__/FormLoginTest.spec.ts
+++ /dev/null
@@ -1,71 +0,0 @@
-import { afterEach, beforeEach, describe, expect, it } from 'vitest'
-import { mount } from '@vue/test-utils'
-import FormLogin from '../FormLogin.vue'
-import { createPinia } from 'pinia'
-import MockAdapter from 'axios-mock-adapter'
-import axios from 'axios'
-
-describe('FormLogin', () => {
-    let wrapper: any
-    let mock: MockAdapter
-
-    beforeEach(() => {
-        wrapper = mount(FormLogin, {
-            global: {
-                plugins: [createPinia()]
-            }
-        })
-
-        mock = new MockAdapter(axios)
-    })
-
-    afterEach(() => {
-        mock.restore()
-    })
-
-    it('renders properly', () => {
-        expect(wrapper.text()).toContain('Brukernavn')
-        expect(wrapper.text()).toContain('Passord')
-        expect(wrapper.text()).toContain('Logg inn')
-
-        expect(wrapper.find('input[type="text"]').exists()).toBe(true)
-        expect(wrapper.find('input[type="password"]').exists()).toBe(true)
-        expect(wrapper.find('button').exists()).toBe(true)
-
-        expect((wrapper.find('input[type="text"]').element as HTMLInputElement).value).toBe('')
-        expect((wrapper.find('input[type="password"]').element as HTMLInputElement).value).toBe('')
-    })
-
-    it('disables button when none inputs are filled', () => {
-        const button = wrapper.findAll('button').find((b: any) => b.text() === 'Logg inn')
-        expect(button.attributes('disabled')).toBeDefined()
-    })
-
-    it('disables button when only username is filled', () => {
-        const button = wrapper.findAll('button').find((b: any) => b.text() === 'Logg inn')
-
-        const inputUsername = wrapper.find('input[type="text"]')
-        inputUsername.setValue('username')
-        expect(button.attributes('disabled')).toBeDefined()
-    })
-
-    it('disables button when only password is filled', () => {
-        const button = wrapper.findAll('button').find((b: any) => b.text() === 'Logg inn')
-
-        const inputPassword = wrapper.find('input[type="password"]')
-        inputPassword.setValue('password')
-        expect(button.attributes('disabled')).toBeDefined()
-    })
-
-    it('enables button when input', async () => {
-        const button = wrapper.findAll('button').find((b: any) => b.text() === 'Logg inn')
-        const inputUsername = wrapper.find('input[type="text"]')
-        const inputPassword = wrapper.find('input[type="password"]')
-
-        inputUsername.setValue('username')
-        inputPassword.setValue('password')
-        await wrapper.vm.$nextTick()
-
-        expect(button.attributes('disabled')).toBeUndefined()
-    })
-})
diff --git a/src/components/__tests__/FormRegisterTest.spec.ts b/src/components/__tests__/FormRegisterTest.spec.ts
deleted file mode 100644
index 935801335b6ca43cd26082a3ea8a25d07a33a833..0000000000000000000000000000000000000000
--- a/src/components/__tests__/FormRegisterTest.spec.ts
+++ /dev/null
@@ -1,93 +0,0 @@
-import { afterEach, beforeEach, describe, expect, it } from 'vitest'
-import { mount } from '@vue/test-utils'
-import FormRegister from '../FormRegister.vue' // Change this to your registration component
-import { createPinia } from 'pinia'
-import MockAdapter from 'axios-mock-adapter'
-import axios from 'axios'
-
-describe('FormRegister', () => {
-    let wrapper: any
-    let mock: MockAdapter
-
-    beforeEach(() => {
-        wrapper = mount(FormRegister, {
-            global: {
-                plugins: [createPinia()]
-            }
-        })
-
-        mock = new MockAdapter(axios)
-    })
-
-    afterEach(() => {
-        mock.restore()
-    })
-
-    function successfulFormFill() {
-        wrapper.find('input[name="firstname"]').setValue('firstname')
-        wrapper.find('input[name="lastname"]').setValue('lastname')
-        wrapper.find('input[name="email"]').setValue('email@test.work')
-        wrapper.find('input[name="username"]').setValue('username')
-        wrapper.find('input[name="password"]').setValue('Password123!')
-        wrapper.find('input[name="confirm"]').setValue('Password123!')
-    }
-
-    it('renders properly', () => {
-        expect(wrapper.text()).toContain('Brukernavn')
-        expect(wrapper.text()).toContain('Passord')
-        expect(wrapper.text()).toContain('Registrer deg')
-
-        expect(wrapper.find('input[name="firstname"]').exists()).toBe(true)
-        expect(wrapper.find('input[name="lastname"]').exists()).toBe(true)
-        expect(wrapper.find('input[name="email"]').exists()).toBe(true)
-        expect(wrapper.find('input[name="username"]').exists()).toBe(true)
-        expect(wrapper.find('input[name="password"]').exists()).toBe(true)
-        expect(wrapper.find('input[name="confirm"]').exists()).toBe(true)
-
-        expect((wrapper.find('input[name="firstname"]').element as HTMLInputElement).value).toBe('')
-        expect((wrapper.find('input[name="lastname"]').element as HTMLInputElement).value).toBe('')
-        expect((wrapper.find('input[name="email"]').element as HTMLInputElement).value).toBe('')
-        expect((wrapper.find('input[name="username"]').element as HTMLInputElement).value).toBe('')
-        expect((wrapper.find('input[name="password"]').element as HTMLInputElement).value).toBe('')
-        expect((wrapper.find('input[name="confirm"]').element as HTMLInputElement).value).toBe('')
-
-        expect(wrapper.find('button[name="submit"]').exists()).toBe(true)
-    })
-
-    it('disables button when none inputs are filled', () => {
-        const button = wrapper.find('button[name="submit"]')
-        expect(button.attributes('disabled')).toBeDefined()
-    })
-
-    it('enables button when all inputs are filled', async () => {
-        const button = wrapper.find('button[name="submit"]')
-
-        successfulFormFill()
-
-        await wrapper.vm.$nextTick()
-
-        expect(button.attributes('disabled')).toBeUndefined()
-    })
-
-    it('disables button when password and confirm password do not match', async () => {
-        const button = wrapper.find('button[name="submit"]')
-
-        successfulFormFill()
-        wrapper.find('input[name="confirm"]').setValue('Password123')
-
-        await wrapper.vm.$nextTick()
-
-        expect(button.attributes('disabled')).toBeDefined()
-    })
-
-    it('disable button when email is invalid', async () => {
-        const button = wrapper.find('button[name="submit"]')
-
-        successfulFormFill()
-        wrapper.find('input[name="email"]').setValue('email')
-
-        await wrapper.vm.$nextTick()
-
-        expect(button.attributes('disabled')).toBeDefined()
-    })
-})
diff --git a/src/components/__tests__/InteractiveSpareTest.spec.ts b/src/components/__tests__/InteractiveSpareTest.spec.ts
deleted file mode 100644
index 834c86ded8cd3fc66732ba222bb0750563484b2f..0000000000000000000000000000000000000000
--- a/src/components/__tests__/InteractiveSpareTest.spec.ts
+++ /dev/null
@@ -1,64 +0,0 @@
-import { describe, expect, it } from 'vitest'
-import { mount } from '@vue/test-utils'
-import SpeechBubbleComponent from '@/components/InteractiveSpare.vue' // Adjust the import path as needed.
-
-describe('SpeechBubbleComponent', () => {
-    it('renders correctly with default props', () => {
-        const wrapper: any = mount(SpeechBubbleComponent, {
-            props: {
-                direction: 'left',
-                speech: ['Hello', 'World'],
-                pngSize: 100,
-                isModalOpen: true
-            }
-        })
-        expect(wrapper.exists()).toBeTruthy()
-    })
-
-    it('applies dynamic classes based on direction prop', () => {
-        const wrapper = mount(SpeechBubbleComponent, {
-            props: {
-                direction: 'right',
-                speech: ['Hello', 'World'],
-                pngSize: 100,
-                isModalOpen: true
-            }
-        })
-        expect(wrapper.find('.spareDiv').classes()).toContain('flex-row')
-        const wrapperReverse = mount(SpeechBubbleComponent, {
-            props: {
-                direction: 'left',
-                speech: ['Hello', 'World'],
-                pngSize: 100,
-                isModalOpen: true
-            }
-        })
-        expect(wrapperReverse.find('.spareDiv').classes()).toContain('flex-row-reverse')
-    })
-
-    it('image class is computed based on direction', () => {
-        const wrapper = mount(SpeechBubbleComponent, {
-            props: {
-                direction: 'right',
-                speech: ['Hello', 'World'],
-                pngSize: 100,
-                isModalOpen: true
-            }
-        })
-        expect(wrapper.find('img').classes()).toContain('scale-x-[-1]')
-    })
-
-    it('updates speech text on div click', async () => {
-        const wrapper = mount(SpeechBubbleComponent, {
-            props: {
-                direction: 'left',
-                speech: ['First speech', 'Second speech'],
-                pngSize: 100,
-                isModalOpen: true
-            }
-        })
-        expect(wrapper.find('.speech').text()).toBe('First speech')
-        await wrapper.find('.spareDiv').trigger('click')
-        expect(wrapper.find('.speech').text()).toBe('Second speech')
-    })
-})
diff --git a/src/components/__tests__/ModalTest.spec.ts b/src/components/__tests__/ModalTest.spec.ts
deleted file mode 100644
index f7fd91adddcbbba3bcd92c01df9193b64a8eb9c4..0000000000000000000000000000000000000000
--- a/src/components/__tests__/ModalTest.spec.ts
+++ /dev/null
@@ -1,37 +0,0 @@
-import { beforeEach, describe, expect, it } from 'vitest'
-import { shallowMount } from '@vue/test-utils'
-import ModalComponent from '@/components/ModalComponent.vue'
-
-describe('ModalComponent', () => {
-    let wrapper: any
-
-    beforeEach(() => {
-        wrapper = shallowMount(ModalComponent, {
-            props: {
-                title: 'Test Title',
-                message: 'Test Message',
-                isModalOpen: true
-            }
-        })
-    })
-
-    it('opens modal when button is clicked', async () => {
-        expect(wrapper.props().isModalOpen).toBe(true)
-    })
-
-    it('title should be: Test Title', () => {
-        expect(wrapper.find('.title').text()).toBe('Test Title')
-    })
-
-    it('title should not be: Wrong Title', () => {
-        expect(wrapper.find('.title').text()).not.toBe('Wrong Title')
-    })
-
-    it('message should be: Test Message', () => {
-        expect(wrapper.find('.message').text()).toBe('Test Message')
-    })
-
-    it('message should not be: Wrong Message', () => {
-        expect(wrapper.find('.message').text()).not.toBe('Wrong Message')
-    })
-})
diff --git a/src/components/__tests__/NavBarTest.spec.ts b/src/components/__tests__/NavBarTest.spec.ts
deleted file mode 100644
index ea7c2814a609abe8a0e43501fa558e7f45f70dc5..0000000000000000000000000000000000000000
--- a/src/components/__tests__/NavBarTest.spec.ts
+++ /dev/null
@@ -1,101 +0,0 @@
-import { mount, VueWrapper } from '@vue/test-utils'
-import NavBar from '@/components/NavBarComponent.vue'
-import router from '@/router'
-import { createPinia, setActivePinia } from 'pinia'
-import { beforeEach, describe, expect, it, vi } from 'vitest'
-
-vi.stubGlobal('scrollTo', vi.fn())
-
-describe('NavBar Routing', () => {
-    let wrapper: VueWrapper<any>
-
-    beforeEach(async () => {
-        const pinia = createPinia()
-        setActivePinia(pinia)
-
-        wrapper = mount(NavBar, {
-            global: {
-                plugins: [router, pinia]
-            }
-        })
-
-        await router.push('/')
-        await router.isReady()
-    })
-
-    it('renders without errors', () => {
-        expect(wrapper.exists()).toBe(true)
-    })
-
-    it('displays correct active route for home link on full screen', async () => {
-        global.innerWidth = 1200
-        await router.push('/hjem')
-        await router.isReady()
-
-        expect(wrapper.find('.router-link-exact-active').exists()).toBe(true)
-    })
-
-    it('displays correct active route for goals link on full screen', async () => {
-        global.innerWidth = 1200
-
-        await router.push('/sparemaal')
-        await router.isReady()
-        expect(wrapper.find('.router-link-exact-active').exists()).toBe(true)
-    })
-
-    it('displays correct active route for challenges link on full screen', async () => {
-        global.innerWidth = 1200
-
-        await router.push('/spareutfordringer')
-        await router.isReady()
-        expect(wrapper.find('.router-link-exact-active').exists()).toBe(true)
-    })
-
-    it('displays correct active route for profile link on full screen', async () => {
-        global.innerWidth = 1200
-
-        await router.push('/profil')
-        await router.isReady()
-        expect(wrapper.find('.router-link-exact-active').exists()).toBe(true)
-    })
-
-    it('displays correct active route for home link when the hamburger menu is open', async () => {
-        global.innerWidth = 1000
-        wrapper.vm.hamburgerOpen = true
-        await wrapper.vm.$nextTick()
-
-        await router.push('/hjem')
-        await router.isReady()
-        expect(wrapper.find('.router-link-exact-active').exists()).toBe(true)
-    })
-
-    it('displays correct active route for goals link when the hamburger menu is open', async () => {
-        global.innerWidth = 1000
-        wrapper.vm.hamburgerOpen = true
-        await wrapper.vm.$nextTick()
-
-        await router.push('/sparemaal')
-        await router.isReady()
-        expect(wrapper.find('.router-link-exact-active').exists()).toBe(true)
-    })
-
-    it('displays correct active route for challenges link when the hamburger menu is open', async () => {
-        global.innerWidth = 1000
-        wrapper.vm.hamburgerOpen = true
-        await wrapper.vm.$nextTick()
-
-        await router.push('/spareutfordringer')
-        await router.isReady()
-        expect(wrapper.find('.router-link-exact-active').exists()).toBe(true)
-    })
-
-    it('displays correct active route for profile link when the hamburger menu is open', async () => {
-        global.innerWidth = 1000
-        wrapper.vm.hamburgerOpen = true
-        await wrapper.vm.$nextTick()
-
-        await router.push('/profil')
-        await router.isReady()
-        expect(wrapper.find('.router-link-exact-active').exists()).toBe(true)
-    })
-})
diff --git a/src/components/__tests__/PageControlTest.spec.ts b/src/components/__tests__/PageControlTest.spec.ts
deleted file mode 100644
index 71739dfebc3e4cd9efc819de55d160d253e09e17..0000000000000000000000000000000000000000
--- a/src/components/__tests__/PageControlTest.spec.ts
+++ /dev/null
@@ -1,39 +0,0 @@
-import { beforeEach, describe, expect, it } from 'vitest'
-import { mount } from '@vue/test-utils'
-import PageControl from '../PageControl.vue'
-
-describe('PageControl', () => {
-    let wrapper: any
-
-    beforeEach(() => {
-        wrapper = mount(PageControl, {
-            props: {
-                currentPage: 0,
-                totalPages: 10
-            }
-        })
-    })
-
-    it('renders correctly', () => {
-        expect(wrapper.text()).toContain('1 / 10')
-        expect(wrapper.find('button', { text: 'Forrige' }).exists()).toBe(true)
-        expect(wrapper.find('button', { text: 'Neste' }).exists()).toBe(true)
-    })
-
-    it('disables the "Forrige" button and enables the "Neste" button when currentPage is 0', () => {
-        expect(wrapper.find('button', { text: 'Forrige' }).attributes('disabled')).toBe('')
-        expect(wrapper.find('button', { text: 'Neste' }).attributes('disabled')).toBe('')
-    })
-
-    it('enables both buttons when currentPage is more than 0 and less than totalPages', async () => {
-        await wrapper.setProps({ currentPage: 1 })
-        expect(wrapper.find('button', { text: 'Forrige' }).attributes('disabled')).toBeUndefined()
-        expect(wrapper.find('button', { text: 'Neste' }).attributes('disabled')).toBeUndefined()
-    })
-
-    it('enables the "Forrige" button and disables the "Neste" button when currentPage is equal to totalPages - 1', async () => {
-        await wrapper.setProps({ currentPage: 9 })
-        expect(wrapper.find('button', { text: 'Forrige' }).attributes('disabled')).toBeUndefined()
-        expect(wrapper.find('button', { text: 'Neste' }).attributes('disabled')).toBeUndefined()
-    })
-})
diff --git a/src/components/__tests__/savingsPathTest.spec.ts b/src/components/__tests__/savingsPathTest.spec.ts
deleted file mode 100644
index dea8650e2ad5d6ced6b43bfd45ce7bc012319875..0000000000000000000000000000000000000000
--- a/src/components/__tests__/savingsPathTest.spec.ts
+++ /dev/null
@@ -1,102 +0,0 @@
-import { beforeEach, describe, expect, it, vi } from 'vitest'
-import { mount } from '@vue/test-utils'
-import { createPinia, setActivePinia } from 'pinia'
-import SavingsPath from '@/components/SavingsPath.vue'
-
-vi.mock('canvas-confetti', () => ({
-    default: vi.fn(() => ({
-        reset: vi.fn(),
-        addFettis: vi.fn(),
-        render: vi.fn(),
-        clear: vi.fn()
-    }))
-}))
-
-describe('SavingsPath Component', () => {
-    let wrapper: any
-    const pinia = createPinia()
-
-    beforeEach(() => {
-        setActivePinia(pinia)
-        wrapper = mount(SavingsPath, {
-            global: {
-                plugins: [pinia]
-            },
-            props: {
-                challenges: [
-                    {
-                        id: 1,
-                        title: 'Test challenge',
-                        perPurchase: 20,
-                        saved: 100,
-                        target: 1000,
-                        description: 'Test description',
-                        due: '2022-01-01T00:00:00Z',
-                        createdOn: '2021-01-01T00:00:00Z',
-                        type: 'Challenge type',
-                        completion: 10
-                    }
-                ],
-                goal: {
-                    id: 1,
-                    title: 'Test goal',
-                    saved: 100,
-                    target: 1000,
-                    description: 'Test description',
-                    due: '2022-01-01T00:00:00Z',
-                    createdOn: '2021-01-01T00:00:00Z',
-                    completion: 10
-                }
-            }
-        })
-    })
-
-    describe('Initial Render', () => {
-        it('should render challenge and goal details correctly', async () => {
-            await wrapper.vm.$nextTick()
-            const challengeText = wrapper.text()
-            expect(challengeText).toContain('Test challenge')
-            expect(challengeText).toContain('100kr / 1000kr')
-            expect(challengeText).toContain('Test goal')
-            expect(challengeText).toContain('100kr / 1000kr')
-        })
-
-        it('should display the correct number of challenge elements', () => {
-            const challengeElements = wrapper.findAll('[data-cy="challenge-title"]')
-            expect(challengeElements.length).toBe(1)
-        })
-    })
-
-    describe('User Interactions', () => {
-        it('should update challenge progress when increment button is clicked', async () => {
-            await wrapper.vm.$nextTick()
-            const incrementButton = wrapper.find('[data-cy="increment-challenge1"]')
-            expect(incrementButton.exists()).toBe(true)
-            await incrementButton.trigger('click')
-            expect(wrapper.vm.challenges[0].saved).toBe(120)
-        })
-    })
-
-    describe('State Management', () => {
-        it('should react to changes in challenge completion status', async () => {
-            // Initially incomplete
-            let progressBar = wrapper.find('.bg-green-600')
-            expect(progressBar.element.style.width).toBe('10%')
-
-            // Update challenge to be almost complete
-            await wrapper.setProps({
-                challenges: [
-                    {
-                        ...wrapper.props().challenges[0],
-                        saved: 900,
-                        completion: 90
-                    }
-                ]
-            })
-            await wrapper.vm.$nextTick()
-
-            progressBar = wrapper.find('.bg-green-600')
-            expect(progressBar.element.style.width).toBe('90%')
-        })
-    })
-})
diff --git a/src/components/icons/IconCommunity.vue b/src/components/icons/IconCommunity.vue
deleted file mode 100644
index 36348e2ee2939606a832d4fd1b6353646af45f5f..0000000000000000000000000000000000000000
--- a/src/components/icons/IconCommunity.vue
+++ /dev/null
@@ -1,7 +0,0 @@
-<template>
-    <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" fill="currentColor">
-        <path
-            d="M15 4a1 1 0 1 0 0 2V4zm0 11v-1a1 1 0 0 0-1 1h1zm0 4l-.707.707A1 1 0 0 0 16 19h-1zm-4-4l.707-.707A1 1 0 0 0 11 14v1zm-4.707-1.293a1 1 0 0 0-1.414 1.414l1.414-1.414zm-.707.707l-.707-.707.707.707zM9 11v-1a1 1 0 0 0-.707.293L9 11zm-4 0h1a1 1 0 0 0-1-1v1zm0 4H4a1 1 0 0 0 1.707.707L5 15zm10-9h2V4h-2v2zm2 0a1 1 0 0 1 1 1h2a3 3 0 0 0-3-3v2zm1 1v6h2V7h-2zm0 6a1 1 0 0 1-1 1v2a3 3 0 0 0 3-3h-2zm-1 1h-2v2h2v-2zm-3 1v4h2v-4h-2zm1.707 3.293l-4-4-1.414 1.414 4 4 1.414-1.414zM11 14H7v2h4v-2zm-4 0c-.276 0-.525-.111-.707-.293l-1.414 1.414C5.42 15.663 6.172 16 7 16v-2zm-.707 1.121l3.414-3.414-1.414-1.414-3.414 3.414 1.414 1.414zM9 12h4v-2H9v2zm4 0a3 3 0 0 0 3-3h-2a1 1 0 0 1-1 1v2zm3-3V3h-2v6h2zm0-6a3 3 0 0 0-3-3v2a1 1 0 0 1 1 1h2zm-3-3H3v2h10V0zM3 0a3 3 0 0 0-3 3h2a1 1 0 0 1 1-1V0zM0 3v6h2V3H0zm0 6a3 3 0 0 0 3 3v-2a1 1 0 0 1-1-1H0zm3 3h2v-2H3v2zm1-1v4h2v-4H4zm1.707 4.707l.586-.586-1.414-1.414-.586.586 1.414 1.414z"
-        />
-    </svg>
-</template>
diff --git a/src/components/icons/IconDocumentation.vue b/src/components/icons/IconDocumentation.vue
deleted file mode 100644
index 0c0fa7610b34b2f5853f7d2c3143d2ff6c9ee1b4..0000000000000000000000000000000000000000
--- a/src/components/icons/IconDocumentation.vue
+++ /dev/null
@@ -1,7 +0,0 @@
-<template>
-    <svg xmlns="http://www.w3.org/2000/svg" width="20" height="17" fill="currentColor">
-        <path
-            d="M11 2.253a1 1 0 1 0-2 0h2zm-2 13a1 1 0 1 0 2 0H9zm.447-12.167a1 1 0 1 0 1.107-1.666L9.447 3.086zM1 2.253L.447 1.42A1 1 0 0 0 0 2.253h1zm0 13H0a1 1 0 0 0 1.553.833L1 15.253zm8.447.833a1 1 0 1 0 1.107-1.666l-1.107 1.666zm0-14.666a1 1 0 1 0 1.107 1.666L9.447 1.42zM19 2.253h1a1 1 0 0 0-.447-.833L19 2.253zm0 13l-.553.833A1 1 0 0 0 20 15.253h-1zm-9.553-.833a1 1 0 1 0 1.107 1.666L9.447 14.42zM9 2.253v13h2v-13H9zm1.553-.833C9.203.523 7.42 0 5.5 0v2c1.572 0 2.961.431 3.947 1.086l1.107-1.666zM5.5 0C3.58 0 1.797.523.447 1.42l1.107 1.666C2.539 2.431 3.928 2 5.5 2V0zM0 2.253v13h2v-13H0zm1.553 13.833C2.539 15.431 3.928 15 5.5 15v-2c-1.92 0-3.703.523-5.053 1.42l1.107 1.666zM5.5 15c1.572 0 2.961.431 3.947 1.086l1.107-1.666C9.203 13.523 7.42 13 5.5 13v2zm5.053-11.914C11.539 2.431 12.928 2 14.5 2V0c-1.92 0-3.703.523-5.053 1.42l1.107 1.666zM14.5 2c1.573 0 2.961.431 3.947 1.086l1.107-1.666C18.203.523 16.421 0 14.5 0v2zm3.5.253v13h2v-13h-2zm1.553 12.167C18.203 13.523 16.421 13 14.5 13v2c1.573 0 2.961.431 3.947 1.086l1.107-1.666zM14.5 13c-1.92 0-3.703.523-5.053 1.42l1.107 1.666C11.539 15.431 12.928 15 14.5 15v-2z"
-        />
-    </svg>
-</template>
diff --git a/src/components/icons/IconEcosystem.vue b/src/components/icons/IconEcosystem.vue
deleted file mode 100644
index 0702bbbe16bbbe88654ec119dc307cd678ea6d63..0000000000000000000000000000000000000000
--- a/src/components/icons/IconEcosystem.vue
+++ /dev/null
@@ -1,7 +0,0 @@
-<template>
-    <svg xmlns="http://www.w3.org/2000/svg" width="18" height="20" fill="currentColor">
-        <path
-            d="M11.447 8.894a1 1 0 1 0-.894-1.789l.894 1.789zm-2.894-.789a1 1 0 1 0 .894 1.789l-.894-1.789zm0 1.789a1 1 0 1 0 .894-1.789l-.894 1.789zM7.447 7.106a1 1 0 1 0-.894 1.789l.894-1.789zM10 9a1 1 0 1 0-2 0h2zm-2 2.5a1 1 0 1 0 2 0H8zm9.447-5.606a1 1 0 1 0-.894-1.789l.894 1.789zm-2.894-.789a1 1 0 1 0 .894 1.789l-.894-1.789zm2 .789a1 1 0 1 0 .894-1.789l-.894 1.789zm-1.106-2.789a1 1 0 1 0-.894 1.789l.894-1.789zM18 5a1 1 0 1 0-2 0h2zm-2 2.5a1 1 0 1 0 2 0h-2zm-5.447-4.606a1 1 0 1 0 .894-1.789l-.894 1.789zM9 1l.447-.894a1 1 0 0 0-.894 0L9 1zm-2.447.106a1 1 0 1 0 .894 1.789l-.894-1.789zm-6 3a1 1 0 1 0 .894 1.789L.553 4.106zm2.894.789a1 1 0 1 0-.894-1.789l.894 1.789zm-2-.789a1 1 0 1 0-.894 1.789l.894-1.789zm1.106 2.789a1 1 0 1 0 .894-1.789l-.894 1.789zM2 5a1 1 0 1 0-2 0h2zM0 7.5a1 1 0 1 0 2 0H0zm8.553 12.394a1 1 0 1 0 .894-1.789l-.894 1.789zm-1.106-2.789a1 1 0 1 0-.894 1.789l.894-1.789zm1.106 1a1 1 0 1 0 .894 1.789l-.894-1.789zm2.894.789a1 1 0 1 0-.894-1.789l.894 1.789zM8 19a1 1 0 1 0 2 0H8zm2-2.5a1 1 0 1 0-2 0h2zm-7.447.394a1 1 0 1 0 .894-1.789l-.894 1.789zM1 15H0a1 1 0 0 0 .553.894L1 15zm1-2.5a1 1 0 1 0-2 0h2zm12.553 2.606a1 1 0 1 0 .894 1.789l-.894-1.789zM17 15l.447.894A1 1 0 0 0 18 15h-1zm1-2.5a1 1 0 1 0-2 0h2zm-7.447-5.394l-2 1 .894 1.789 2-1-.894-1.789zm-1.106 1l-2-1-.894 1.789 2 1 .894-1.789zM8 9v2.5h2V9H8zm8.553-4.894l-2 1 .894 1.789 2-1-.894-1.789zm.894 0l-2-1-.894 1.789 2 1 .894-1.789zM16 5v2.5h2V5h-2zm-4.553-3.894l-2-1-.894 1.789 2 1 .894-1.789zm-2.894-1l-2 1 .894 1.789 2-1L8.553.106zM1.447 5.894l2-1-.894-1.789-2 1 .894 1.789zm-.894 0l2 1 .894-1.789-2-1-.894 1.789zM0 5v2.5h2V5H0zm9.447 13.106l-2-1-.894 1.789 2 1 .894-1.789zm0 1.789l2-1-.894-1.789-2 1 .894 1.789zM10 19v-2.5H8V19h2zm-6.553-3.894l-2-1-.894 1.789 2 1 .894-1.789zM2 15v-2.5H0V15h2zm13.447 1.894l2-1-.894-1.789-2 1 .894 1.789zM18 15v-2.5h-2V15h2z"
-        />
-    </svg>
-</template>
diff --git a/src/components/icons/IconSupport.vue b/src/components/icons/IconSupport.vue
deleted file mode 100644
index 908b94c4f8b389565dd8511113b74b7a34d276b8..0000000000000000000000000000000000000000
--- a/src/components/icons/IconSupport.vue
+++ /dev/null
@@ -1,7 +0,0 @@
-<template>
-    <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" fill="currentColor">
-        <path
-            d="M10 3.22l-.61-.6a5.5 5.5 0 0 0-7.666.105 5.5 5.5 0 0 0-.114 7.665L10 18.78l8.39-8.4a5.5 5.5 0 0 0-.114-7.665 5.5 5.5 0 0 0-7.666-.105l-.61.61z"
-        />
-    </svg>
-</template>
diff --git a/src/components/icons/IconTooling.vue b/src/components/icons/IconTooling.vue
deleted file mode 100644
index f2a971e08d007f25fe63be672f86b6ce16806f8b..0000000000000000000000000000000000000000
--- a/src/components/icons/IconTooling.vue
+++ /dev/null
@@ -1,18 +0,0 @@
-<!-- This icon is from <https://github.com/Templarian/MaterialDesign>, distributed under Apache 2.0 (https://www.apache.org/licenses/LICENSE-2.0) license-->
-<template>
-    <svg
-        xmlns="http://www.w3.org/2000/svg"
-        aria-hidden="true"
-        role="img"
-        class="iconify iconify--mdi"
-        width="24"
-        height="24"
-        preserveAspectRatio="xMidYMid meet"
-        viewBox="0 0 24 24"
-    >
-        <path
-            d="M20 18v-4h-3v1h-2v-1H9v1H7v-1H4v4h16M6.33 8l-1.74 4H7v-1h2v1h6v-1h2v1h2.41l-1.74-4H6.33M9 5v1h6V5H9m12.84 7.61c.1.22.16.48.16.8V18c0 .53-.21 1-.6 1.41c-.4.4-.85.59-1.4.59H4c-.55 0-1-.19-1.4-.59C2.21 19 2 18.53 2 18v-4.59c0-.32.06-.58.16-.8L4.5 7.22C4.84 6.41 5.45 6 6.33 6H7V5c0-.55.18-1 .57-1.41C7.96 3.2 8.44 3 9 3h6c.56 0 1.04.2 1.43.59c.39.41.57.86.57 1.41v1h.67c.88 0 1.49.41 1.83 1.22l2.34 5.39z"
-            fill="currentColor"
-        ></path>
-    </svg>
-</template>
diff --git a/src/main.ts b/src/main.ts
deleted file mode 100644
index 5dcad83c30800a564e96bad81c93d6be2ffaceaa..0000000000000000000000000000000000000000
--- a/src/main.ts
+++ /dev/null
@@ -1,14 +0,0 @@
-import './assets/main.css'
-
-import { createApp } from 'vue'
-import { createPinia } from 'pinia'
-
-import App from './App.vue'
-import router from './router'
-
-const app = createApp(App)
-
-app.use(createPinia())
-app.use(router)
-
-app.mount('#app')
diff --git a/src/router/index.ts b/src/router/index.ts
deleted file mode 100644
index 5f32e18fa4bcb61cf7ad48446e11dea346712c49..0000000000000000000000000000000000000000
--- a/src/router/index.ts
+++ /dev/null
@@ -1,137 +0,0 @@
-import { createRouter, createWebHistory } from 'vue-router'
-
-const router = createRouter({
-    history: createWebHistory(import.meta.env.BASE_URL),
-    routes: [
-        {
-            path: '/',
-            name: 'start',
-            component: () => import('@/views/StartView.vue')
-        },
-        {
-            path: '/hjem',
-            name: 'home',
-            component: () => import('@/views/HomeView.vue')
-        },
-        {
-            path: '/logginn',
-            name: 'login',
-            component: () => import('@/views/RegisterLoginView.vue')
-        },
-        {
-            path: '/registrer',
-            name: 'register',
-            component: () => import('@/views/RegisterLoginView.vue')
-        },
-        {
-            path: '/forgotPassword',
-            name: 'resetPassword',
-            component: () => import('@/views/ResetPasswordView.vue')
-        },
-        {
-            path: '/profil',
-            name: 'profile',
-            component: () => import('@/views/ProfileView.vue')
-        },
-        {
-            path: '/profil/rediger',
-            name: 'edit-profile',
-            component: () => import('@/views/EditProfileView.vue')
-        },
-        {
-            path: '/sparemaal',
-            name: 'goals',
-            component: () => import('@/views/UserGoalsView.vue')
-        },
-        {
-            path: '/sparemaal/rediger/ny',
-            name: 'new-goal',
-            component: () => import('@/views/ManageGoalView.vue')
-        },
-        {
-            path: '/sparemaal/rediger/:id',
-            name: 'edit-goal',
-            component: () => import('@/views/ManageGoalView.vue')
-        },
-        {
-            path: '/sparemaal/oversikt/:id',
-            name: 'view-goal',
-            component: () => import('@/views/ViewGoalView.vue')
-        },
-        {
-            path: '/spareutfordringer',
-            name: 'challenges',
-            component: () => import('@/views/UserChallengesView.vue')
-        },
-        {
-            path: '/spareutfordringer/ny',
-            name: 'new-challenge',
-            component: () => import('@/views/ManageChallengeView.vue')
-        },
-        {
-            path: '/spareutfordringer/rediger/:id',
-            name: 'edit-challenge',
-            component: () => import('@/views/ManageChallengeView.vue')
-        },
-        {
-            path: '/spareutfordringer/oversikt/:id',
-            name: 'view-challenge',
-            component: () => import('@/views/ViewChallengeView.vue')
-        },
-        {
-            path: '/konfigurasjonSteg1',
-            name: 'configurations1',
-            component: () => import('@/views/ConfigHabitChangeView.vue')
-        },
-        {
-            path: '/konfigurasjonSteg2',
-            name: 'configurations2',
-            component: () => import('@/views/ConfigFamiliarWithSavingsView.vue')
-        },
-        {
-            path: '/konfigurasjonSteg3',
-            name: 'configurations3',
-            component: () => import('@/views/ConfigSpendingItemsView.vue')
-        },
-        {
-            path: '/konfigurasjonSteg4',
-            name: 'configurations4',
-            component: () => import('@/views/ConfigSpendingItemsAmountView.vue')
-        },
-        {
-            path: '/konfigurasjonSteg5',
-            name: 'configurations5',
-            component: () => import('@/views/ConfigSpendingItemsTotalAmountView.vue')
-        },
-        {
-            path: '/konfigurasjonSteg6',
-            name: 'configurations6',
-            component: () => import('@/views/ConfigAccountNumberView.vue')
-        },
-        {
-            path: '/forsteSparemaal',
-            name: 'firstSavingGoal',
-            component: () => import('@/views/FirstSavingGoalView.vue')
-        },
-        {
-            path: '/forsteSpareutfordring',
-            name: 'firstSavingChallengde',
-            component: () => import('@/views/FirstSavingChallengeView.vue')
-        },
-        {
-            path: '/:pathMatch(.*)*',
-            name: 'not-found',
-            component: () => import('@/views/NotFoundView.vue')
-        },
-        {
-            path: '/addAlternativeLogin',
-            name: 'addAlternativeLogin',
-            component: () => import('@/views/AddAlternativeLogin.vue')
-        }
-    ],
-    scrollBehavior() {
-        return { top: 0 }
-    }
-})
-
-export default router
diff --git a/src/services/authInterceptor.ts b/src/services/authInterceptor.ts
deleted file mode 100644
index 0b175e5abab8c805f71bab83cc5746d0bf750da7..0000000000000000000000000000000000000000
--- a/src/services/authInterceptor.ts
+++ /dev/null
@@ -1,63 +0,0 @@
-import type { AxiosResponse } from 'axios'
-import axios, { AxiosError } from 'axios'
-import router from '@/router'
-
-const authInterceptor = axios.create({
-    baseURL: 'http://localhost:8080',
-    headers: {
-        'Content-Type': 'application/json'
-    }
-})
-
-authInterceptor.interceptors.request.use(
-    (config) => {
-        const accessToken = sessionStorage.getItem('accessToken')
-        if (accessToken) {
-            config.headers['Authorization'] = `Bearer ${accessToken}`
-        }
-        return config
-    },
-    (error: AxiosError) => {
-        return Promise.reject(error)
-    }
-)
-
-authInterceptor.interceptors.response.use(
-    (response: AxiosResponse) => {
-        return response
-    },
-    async (error) => {
-        const originalRequest = error.config
-        if (
-            (error.response.status === 401 || error.response.status === 403) &&
-            !originalRequest._retry
-        ) {
-            originalRequest._retry = true
-            const refreshToken = localStorage.getItem('refreshToken')
-            axios
-                .post('/auth/renewToken', null, {
-                    headers: {
-                        Authorization: `Bearer ${refreshToken}`
-                    }
-                })
-                .then((response) => {
-                    sessionStorage.setItem('accessToken', response.data.accessToken)
-                    authInterceptor.defaults.headers['Authorization'] =
-                        `Bearer ${response.data.accessToken}`
-                    return authInterceptor(originalRequest)
-                })
-                .catch((err) => {
-                    router.push({ name: 'login' })
-                    return Promise.reject(err)
-                })
-        }
-        // Specific handler for 404 errors
-        if (error.response?.status === 404) {
-            console.error('Requested resource not found:', error.config.url)
-            // Optionally redirect or inform the user, depending on the context
-        }
-        return Promise.reject(error)
-    }
-)
-
-export default authInterceptor
diff --git a/src/stores/accountStore.ts b/src/stores/accountStore.ts
deleted file mode 100644
index b80263eafa362581f6c2e235d544456ad887274c..0000000000000000000000000000000000000000
--- a/src/stores/accountStore.ts
+++ /dev/null
@@ -1,35 +0,0 @@
-import { defineStore } from 'pinia'
-import { ref } from 'vue'
-import authInterceptor from '@/services/authInterceptor'
-import { AxiosError } from 'axios'
-
-export const useAccountStore = defineStore('account', {
-    state: () => ({
-        errorMessage: ref<string>('')
-    }),
-    actions: {
-        async postAccount(accountType: 'SAVING' | 'SPENDING', accNumber: string, balance: number) {
-            const payload = {
-                accountType,
-                accNumber,
-                balance
-            }
-
-            try {
-                const response = await authInterceptor.post('/accounts', payload)
-                console.log('Success:', response.data)
-            } catch (error) {
-                console.error('Error posting account:', error)
-                this.handleAxiosError(error)
-            }
-        },
-        handleAxiosError(error: any) {
-            const axiosError = error as AxiosError
-            if (axiosError.response && axiosError.response.data) {
-                const errorData = axiosError.response.data as { message: string }
-            } else {
-                this.errorMessage = 'An unexpected error occurred'
-            }
-        }
-    }
-})
diff --git a/src/stores/challengeStore.ts b/src/stores/challengeStore.ts
deleted file mode 100644
index 8e4529c5cd004d75a741cd132bc35fa7d7e80310..0000000000000000000000000000000000000000
--- a/src/stores/challengeStore.ts
+++ /dev/null
@@ -1,50 +0,0 @@
-// store/challengeStore.js
-import { defineStore } from 'pinia'
-import { ref } from 'vue'
-import authInterceptor from '@/services/authInterceptor'
-import type { Challenge } from '@/types/challenge'
-
-export const useChallengeStore = defineStore('challenge', () => {
-    const challenges = ref<Challenge[]>([])
-
-    const getUserChallenges = async () => {
-        try {
-            const response = await authInterceptor('/challenges')
-            if (response.data && response.data.content) {
-                challenges.value = response.data.content
-                console.log('Fetched Challenges:', challenges.value)
-            } else {
-                challenges.value = []
-                console.error('No challenge content found:', response.data)
-            }
-        } catch (error) {
-            console.error('Error fetching challenges:', error)
-            challenges.value = [] // Ensure challenges is always an array
-        }
-    }
-
-    // Assuming 'challenges' is a reactive state in your store that holds the list of challenges
-    const editUserChallenge = async (challenge: Challenge) => {
-        try {
-            const response = await authInterceptor.put(`/challenges/${challenge.id}`, challenge)
-            if (response.data) {
-                // Update local challenge state to reflect changes
-                const index = challenges.value.findIndex((c) => c.id === challenge.id)
-                if (index !== -1) {
-                    challenges.value[index] = { ...challenges.value[index], ...response.data }
-                    console.log('Updated Challenge:', response.data)
-                }
-            } else {
-                console.error('No challenge content found in response data')
-            }
-        } catch (error) {
-            console.error('Error updating challenge:', error)
-        }
-    }
-
-    return {
-        challenges,
-        getUserChallenges,
-        editUserChallenge
-    }
-})
diff --git a/src/stores/goalStore.ts b/src/stores/goalStore.ts
deleted file mode 100644
index 30367ad29f6151e418d24d6a29ca53b6632963ed..0000000000000000000000000000000000000000
--- a/src/stores/goalStore.ts
+++ /dev/null
@@ -1,51 +0,0 @@
-import { defineStore } from 'pinia'
-import type { Goal } from '@/types/goal'
-import { ref } from 'vue'
-import authInterceptor from '@/services/authInterceptor'
-
-export const useGoalStore = defineStore('goal', () => {
-    const goals = ref<Goal[]>([])
-    const getUserGoals = async () => {
-        try {
-            const response = await authInterceptor('/goals')
-            if (response.data && response.data.content) {
-                goals.value = response.data.content
-                console.log(response.data.content)
-                console.log('Fetched Goals:', goals.value)
-            } else {
-                goals.value = []
-                console.error('No goal content found:', response.data)
-            }
-        } catch (error) {
-            console.error('Error fetching challenges:', error)
-            goals.value = [] // Ensure challenges is always an array
-        }
-    }
-    // Assuming 'challenges' is a reactive state in your store that holds the list of challenges
-    const editUserGoal = async (goal: Goal) => {
-        if (!goal || goal.id === null) {
-            console.error('Invalid goal or goal ID.')
-            return
-        }
-
-        try {
-            const response = await authInterceptor.put(`/goals/${goal.id}`, goal)
-            if (response.data) {
-                const index = goals.value.findIndex((g) => g.id === goal.id)
-                if (index !== -1) {
-                    goals.value[index] = { ...goals.value[index], ...response.data }
-                    console.log('Updated Goal:', response.data)
-                }
-            } else {
-                console.error('No goal content found in response data')
-            }
-        } catch (error) {
-            console.error('Error updating goal:', error)
-        }
-    }
-    return {
-        goals,
-        getUserGoals,
-        editUserGoal
-    }
-})
diff --git a/src/stores/userConfigStore.ts b/src/stores/userConfigStore.ts
deleted file mode 100644
index 6f1e0f1ccbe25f90f463aed9ef97ec9b63ac4319..0000000000000000000000000000000000000000
--- a/src/stores/userConfigStore.ts
+++ /dev/null
@@ -1,52 +0,0 @@
-import { defineStore } from 'pinia'
-import { ref } from 'vue'
-import authInterceptor from '@/services/authInterceptor'
-import { AxiosError } from 'axios'
-
-export const useUserConfigStore = defineStore('userConfig', {
-    state: () => ({
-        role: 'USER',
-        experience: 'VERY_HIGH',
-        motivation: 'VERY_HIGH',
-        challengeTypeConfigs: [] as {
-            type: string
-            specificAmount: number
-            generalAmount: number
-        }[],
-        errorMessage: ref<string>('')
-    }),
-    actions: {
-        setExperience(value: string) {
-            this.experience = value
-        },
-        setMotivation(value: string) {
-            this.motivation = value
-        },
-        addChallengeTypeConfig(type: string, specificAmount: number, generalAmount: number) {
-            this.challengeTypeConfigs.push({ type, specificAmount, generalAmount })
-        },
-        postUserConfig() {
-            const payload = {
-                experience: this.experience,
-                motivation: this.motivation,
-                challengeTypeConfigs: Array.from(this.challengeTypeConfigs)
-            }
-
-            authInterceptor
-                .post('/config/challenge', payload)
-                .then((response) => {
-                    console.log('Success:', response.data)
-                })
-                .catch((error) => {
-                    const axiosError = error as AxiosError
-                    if (axiosError.response && axiosError.response.data) {
-                        const errorData = axiosError.response.data as { message: string }
-                        this.errorMessage = errorData.message || 'An error occurred'
-                    } else {
-                        this.errorMessage = 'An unexpected error occurred'
-                    }
-                    console.error('Axios error:', this.errorMessage)
-                })
-        }
-    }
-})
diff --git a/src/stores/userStore.ts b/src/stores/userStore.ts
deleted file mode 100644
index ace14583f589aece97546bf3c653462a0fe3ee0e..0000000000000000000000000000000000000000
--- a/src/stores/userStore.ts
+++ /dev/null
@@ -1,224 +0,0 @@
-import { ref } from 'vue'
-import { defineStore } from 'pinia'
-import type { User } from '@/types/user'
-import router from '@/router'
-import type { AxiosError } from 'axios'
-import axios from 'axios'
-import type { CredentialRequestOptions } from '@/types/CredentialRequestOptions'
-import { base64urlToUint8array, initialCheckStatus, uint8arrayToBase64url } from '@/util'
-import authInterceptor from '@/services/authInterceptor'
-import type { CredentialCreationOptions } from '@/types/CredentialCreationOptions'
-
-export const useUserStore = defineStore('user', () => {
-    const defaultUser: User = {
-        firstname: 'Firstname',
-        lastname: 'Lastname',
-        username: 'Username'
-    }
-
-    const user = ref<User>(defaultUser)
-    const errorMessage = ref<string>('')
-
-    const register = async (
-        firstname: string,
-        lastname: string,
-        email: string,
-        username: string,
-        password: string
-    ) => {
-        await axios
-            .post(`http://localhost:8080/auth/register`, {
-                firstName: firstname, //TODO rename all instances of firstname to firstName
-                lastName: lastname,
-                email: email,
-                username: username,
-                password: password
-            })
-            .then((response) => {
-                sessionStorage.setItem('accessToken', response.data.accessToken)
-                localStorage.setItem('refreshToken', response.data.refreshToken)
-
-                user.value.firstname = firstname
-                user.value.lastname = lastname
-                user.value.username = username
-
-                router.push({ name: 'addAlternativeLogin' })
-            })
-            .catch((error) => {
-                const axiosError = error as AxiosError
-                errorMessage.value = (axiosError.response?.data as string) || 'An error occurred'
-            })
-    }
-
-    const login = async (username: string, password: string) => {
-        await axios
-            .post(`http://localhost:8080/auth/login`, {
-                username: username,
-                password: password
-            })
-            .then((response) => {
-                sessionStorage.setItem('accessToken', response.data.accessToken)
-                localStorage.setItem('refreshToken', response.data.refreshToken)
-
-                user.value.firstname = response.data.firstName
-                user.value.lastname = response.data.lastName
-                user.value.username = response.data.username
-
-                router.push({ name: 'home' })
-            })
-            .catch((error) => {
-                const axiosError = error as AxiosError
-                errorMessage.value = (axiosError.response?.data as string) || 'An error occurred'
-            })
-    }
-
-    const logout = () => {
-        console.log('Logging out')
-        sessionStorage.removeItem('accessToken')
-        localStorage.removeItem('refreshToken')
-        user.value = defaultUser
-        router.push({ name: 'login' })
-    }
-
-    const bioRegister = async () => {
-        try {
-            const response = await authInterceptor.post('/auth/bioRegistration')
-            initialCheckStatus(response)
-
-            const credentialCreateJson: CredentialCreationOptions = response.data
-
-            const credentialCreateOptions: CredentialCreationOptions = {
-                publicKey: {
-                    ...credentialCreateJson.publicKey,
-                    challenge: base64urlToUint8array(
-                        credentialCreateJson.publicKey.challenge as unknown as string
-                    ),
-                    user: {
-                        ...credentialCreateJson.publicKey.user,
-                        id: base64urlToUint8array(
-                            credentialCreateJson.publicKey.user.id as unknown as string
-                        )
-                    },
-                    excludeCredentials: credentialCreateJson.publicKey.excludeCredentials?.map(
-                        (credential) => ({
-                            ...credential,
-                            id: base64urlToUint8array(credential.id as unknown as string)
-                        })
-                    ),
-                    extensions: credentialCreateJson.publicKey.extensions
-                }
-            }
-
-            const publicKeyCredential = (await navigator.credentials.create(
-                credentialCreateOptions
-            )) as PublicKeyCredential
-
-            const publicKeyResponse =
-                publicKeyCredential.response as AuthenticatorAttestationResponse
-            const encodedResult = {
-                type: publicKeyCredential.type,
-                id: publicKeyCredential.id,
-                response: {
-                    attestationObject: uint8arrayToBase64url(publicKeyResponse.attestationObject),
-                    clientDataJSON: uint8arrayToBase64url(publicKeyResponse.clientDataJSON),
-                    transports: publicKeyResponse.getTransports?.() || []
-                },
-                clientExtensionResults: publicKeyCredential.getClientExtensionResults()
-            }
-
-            await authInterceptor
-                .post('/auth/finishBioRegistration', { credential: JSON.stringify(encodedResult) })
-                .then((response) => {
-                    router.push({ name: 'configurations1' })
-                })
-        } catch (error) {
-            router.push({ name: 'configurations1' })
-            console.error(error)
-        }
-    }
-
-    const bioLogin = async (username: string) => {
-        try {
-            const request = await axios.post(`http://localhost:8080/auth/bioLogin/${username}`)
-
-            initialCheckStatus(request)
-            console.log(request)
-
-            const credentialGetJson: CredentialRequestOptions = request.data
-            console.log(credentialGetJson)
-
-            const credentialGetOptions: CredentialRequestOptions = {
-                publicKey: {
-                    ...credentialGetJson.publicKey,
-                    allowCredentials:
-                        credentialGetJson.publicKey.allowCredentials &&
-                        credentialGetJson.publicKey.allowCredentials.map((credential) => ({
-                            ...credential,
-                            id: base64urlToUint8array(credential.id as unknown as string)
-                        })),
-                    challenge: base64urlToUint8array(
-                        credentialGetJson.publicKey.challenge as unknown as string
-                    ),
-                    extensions: credentialGetJson.publicKey.extensions
-                }
-            }
-
-            const publicKeyCredential = (await navigator.credentials.get(
-                credentialGetOptions
-            )) as PublicKeyCredential
-
-            // Extract response data based on the type of credential
-            const response = publicKeyCredential.response as AuthenticatorAssertionResponse
-
-            const encodedResult = {
-                type: publicKeyCredential.type,
-                id: publicKeyCredential.id,
-                response: {
-                    authenticatorData:
-                        response.authenticatorData &&
-                        uint8arrayToBase64url(response.authenticatorData),
-                    clientDataJSON:
-                        response.clientDataJSON && uint8arrayToBase64url(response.clientDataJSON),
-
-                    signature: response.signature && uint8arrayToBase64url(response.signature),
-                    userHandle: response.userHandle && uint8arrayToBase64url(response.userHandle)
-                },
-                clientExtensionResults: publicKeyCredential.getClientExtensionResults()
-            }
-            console.log(encodedResult)
-
-            await axios
-                .post(`http://localhost:8080/auth/finishBioLogin/${username}`, {
-                    credential: JSON.stringify(encodedResult)
-                })
-                .then((response) => {
-                    sessionStorage.setItem('accessToken', response.data.accessToken)
-                    localStorage.setItem('refreshToken', response.data.refreshToken)
-
-                    user.value.firstname = response.data.firstName
-                    user.value.lastname = response.data.lastName
-                    user.value.username = response.data.username
-
-                    router.push({ name: 'home' })
-                })
-                .catch((error) => {
-                    const axiosError = error as AxiosError
-                    errorMessage.value =
-                        (axiosError.response?.data as string) || 'An error occurred'
-                    console.log('hei :' + errorMessage.value)
-                })
-        } catch (error) {
-            // Handle errors
-            console.log(error)
-        }
-    }
-
-    return {
-        register,
-        login,
-        logout,
-        bioLogin,
-        bioRegister,
-        errorMessage
-    }
-})
diff --git a/src/types/CredentialCreationOptions.ts b/src/types/CredentialCreationOptions.ts
deleted file mode 100644
index b6fdd7a76510ca4033a1c763a2ca9545797ab1b5..0000000000000000000000000000000000000000
--- a/src/types/CredentialCreationOptions.ts
+++ /dev/null
@@ -1,3 +0,0 @@
-export interface CredentialCreationOptions {
-    publicKey: PublicKeyCredentialCreationOptions
-}
diff --git a/src/types/CredentialRequestOptions.ts b/src/types/CredentialRequestOptions.ts
deleted file mode 100644
index 4349a83cdfde9e60fe294adeef87dd4f1792087c..0000000000000000000000000000000000000000
--- a/src/types/CredentialRequestOptions.ts
+++ /dev/null
@@ -1,3 +0,0 @@
-export interface CredentialRequestOptions {
-    publicKey: PublicKeyCredentialRequestOptions
-}
diff --git a/src/types/challenge.ts b/src/types/challenge.ts
deleted file mode 100644
index ef9acee9b95f6d9ba0b28103b6981461bb1d8b83..0000000000000000000000000000000000000000
--- a/src/types/challenge.ts
+++ /dev/null
@@ -1,15 +0,0 @@
-// Assuming the use of classes from 'class-transformer' for date handling or plain TypeScript
-
-export interface Challenge {
-    id?: number
-    title: string
-    perPurchase: number
-    saved: number // BigDecimal in Java, but TypeScript uses number for floating points
-    target: number
-    description: string
-    due: string // Mapping ZonedDateTime to Date, optional since Temporal annotation not always implies required
-    createdOn?: string // Mapping ZonedDateTime to Date
-    type: string // Not specified as @NotNull, so it's optional
-    completion?: number // Assuming BigDecimal maps to number, optional due to @Transient
-    completedOn?: string // Adding the new variable as optional
-}
diff --git a/src/types/goal.ts b/src/types/goal.ts
deleted file mode 100644
index 6c0962f9f7b59e4e5f439e449478d1ed01ae1dbe..0000000000000000000000000000000000000000
--- a/src/types/goal.ts
+++ /dev/null
@@ -1,12 +0,0 @@
-export interface Goal {
-    id?: number
-    title: string
-    saved: number
-    target: number
-    completion?: number
-    description: string
-    priority?: number
-    createdOn?: string
-    due: string
-    completedOn?: string
-}
diff --git a/src/types/profile.ts b/src/types/profile.ts
deleted file mode 100644
index 392aee69615beff857dc324e85cc4f77ea1f7911..0000000000000000000000000000000000000000
--- a/src/types/profile.ts
+++ /dev/null
@@ -1,19 +0,0 @@
-export interface Profile {
-    id: number
-    firstName: string
-    lastName: string
-    email: string
-    username: string
-    password?: string
-    spendingAccount: {
-        accNumber?: number
-        accountType?: string
-        balance?: number
-    }
-    savingAccount: {
-        accNumber?: number
-        accountType?: string
-        balance?: number
-    }
-    badges?: object[]
-}
diff --git a/src/types/user.ts b/src/types/user.ts
deleted file mode 100644
index a420d33a4deb8de0e12fb303edf205b3be5e703f..0000000000000000000000000000000000000000
--- a/src/types/user.ts
+++ /dev/null
@@ -1,5 +0,0 @@
-export interface User {
-    firstname: string
-    lastname: string
-    username: string
-}
diff --git a/src/util.ts b/src/util.ts
deleted file mode 100644
index 7f6cbfc818ab356135d6acf232024019ea4fafe0..0000000000000000000000000000000000000000
--- a/src/util.ts
+++ /dev/null
@@ -1,33 +0,0 @@
-import base64js from 'base64-js'
-import { type AxiosResponse } from 'axios'
-
-export function base64urlToUint8array(base64Bytes: string): Uint8Array {
-    const padding = '===='.substring(0, (4 - (base64Bytes.length % 4)) % 4)
-    return base64js.toByteArray((base64Bytes + padding).replace(/\//g, '_').replace(/\+/g, '-'))
-}
-
-export function uint8arrayToBase64url(bytes: Uint8Array | ArrayBuffer | number[]): string {
-    if (bytes instanceof Uint8Array) {
-        return base64js
-            .fromByteArray(bytes)
-            .replace(/\+/g, '-')
-            .replace(/\//g, '_')
-            .replace(/=/g, '')
-    } else {
-        return uint8arrayToBase64url(new Uint8Array(bytes))
-    }
-}
-
-export function checkStatus(response: AxiosResponse<any>): AxiosResponse<any> | undefined {
-    if (response.status !== 200) {
-        console.log('an error occurred: ', response.statusText)
-        return undefined
-    } else {
-        return response
-    }
-}
-
-export function initialCheckStatus(response: AxiosResponse<any>): any {
-    checkStatus(response)
-    return response.data
-}
diff --git a/src/utilo.js b/src/utilo.js
deleted file mode 100644
index 4125c85af520a7d429032a90f80c9a4611f07740..0000000000000000000000000000000000000000
--- a/src/utilo.js
+++ /dev/null
@@ -1,28 +0,0 @@
-import base64js from 'base64-js'
-
-export function base64urlToUint8array(base64Bytes) {
-    const padding = '===='.substring(0, (4 - (base64Bytes.length % 4)) % 4)
-    return base64js.toByteArray((base64Bytes + padding).replace(/\//g, '_').replace(/\+/g, '-'))
-}
-export function uint8arrayToBase64url(bytes) {
-    if (bytes instanceof Uint8Array) {
-        return base64js
-            .fromByteArray(bytes)
-            .replace(/\+/g, '-')
-            .replace(/\//g, '_')
-            .replace(/=/g, '')
-    } else {
-        return uint8arrayToBase64url(new Uint8Array(bytes))
-    }
-}
-export function checkStatus(response) {
-    if (response.status !== 200) {
-        console.log('an error occurred: ', response.body)
-    } else {
-        return response
-    }
-}
-export function initialCheckStatus(response) {
-    checkStatus(response)
-    return response.data
-}
diff --git a/src/views/AddAlternativeLogin.vue b/src/views/AddAlternativeLogin.vue
deleted file mode 100644
index 554f09f25915282f5675244784a6bb212457d036..0000000000000000000000000000000000000000
--- a/src/views/AddAlternativeLogin.vue
+++ /dev/null
@@ -1,48 +0,0 @@
-<template>
-    <div class="alt-login-main">
-        <h1>Alternativ innlogging</h1>
-        <div class="img-div">
-            <img src="@/assets/bioAuthTouch.png" alt="bioAuthTouch" />
-            <img src="@/assets/bioAuthFace.png" alt="bioAuthFace" />
-        </div>
-        <h2>Vil du logge på med touch eller face id?</h2>
-        <div class="btn-div">
-            <button @click="router.push('konfigurasjonSteg1')">Senere</button>
-            <button @click="userStore.bioRegister()">OK</button>
-        </div>
-    </div>
-</template>
-<script setup lang="ts">
-import { useUserStore } from '@/stores/userStore'
-import router from '@/router'
-
-const userStore = useUserStore()
-</script>
-
-<style scoped>
-.alt-login-main {
-    max-width: 800px;
-    display: flex;
-    flex-direction: column;
-    align-items: center;
-}
-
-.img-div {
-    display: flex;
-    justify-content: center;
-}
-
-img {
-    width: 30%;
-}
-
-img:first-child {
-    margin-right: 20px;
-}
-
-button {
-    margin: 10px;
-    width: 100px;
-    height: 40px;
-}
-</style>
diff --git a/src/views/CardTemplate.vue b/src/views/CardTemplate.vue
deleted file mode 100644
index 6fa731e67776d9e923ea99427b9a23893f3de385..0000000000000000000000000000000000000000
--- a/src/views/CardTemplate.vue
+++ /dev/null
@@ -1,9 +0,0 @@
-<script lang="ts" setup></script>
-
-<template>
-    <div class="border rounded-xl shadow-lg overflow-hidden">
-        <slot></slot>
-    </div>
-</template>
-
-<style scoped></style>
diff --git a/src/views/ConfigAccountNumberView.vue b/src/views/ConfigAccountNumberView.vue
deleted file mode 100644
index 0537138ef5da7fcda18c58521fbde24009064bd9..0000000000000000000000000000000000000000
--- a/src/views/ConfigAccountNumberView.vue
+++ /dev/null
@@ -1,114 +0,0 @@
-<template>
-    <div
-        class="flex flex-col items-center justify-center min-h-screen md:pt-10 pt-4 pb-24 text-center"
-    >
-        <h1 class="mb-8 lg:mb-12 text-4xl font-bold">
-            Legg til kontonummer for sparekonto og brukskonto
-        </h1>
-        <div
-            class="flex flex-col items-center justify-center bg-white rounded-lg p-8 shadow-lg w-full md:w-[45%]"
-        >
-            <div class="w-full mb-4">
-                <label for="savingsAccount" class="block text-lg font-bold mb-2">Sparekonto</label>
-                <input
-                    id="savingsAccount"
-                    v-model="savingsAccount"
-                    @input="restrictToNumbers($event as InputEvent, 'savings')"
-                    @focus="removeFormatting('savings')"
-                    @blur="applyFormatting('savings')"
-                    class="w-full h-11 px-3 rounded-md text-xl focus:outline-none transition-colors border-2 border-gray-300"
-                    type="text"
-                    placeholder="Skriv inn ditt kontonummer..."
-                />
-            </div>
-            <div class="w-full mb-4">
-                <label for="spendingAccount" class="block text-lg font-bold mb-2">Brukskonto</label>
-                <input
-                    id="spendingAccount"
-                    v-model="spendingAccount"
-                    @input="restrictToNumbers($event as InputEvent, 'spending')"
-                    @focus="removeFormatting('spending')"
-                    @blur="applyFormatting('spending')"
-                    class="w-full h-11 px-3 rounded-md text-xl focus:outline-none transition-colors border-2 border-gray-300"
-                    type="text"
-                    placeholder="Skriv inn ditt kontonummer..."
-                />
-            </div>
-        </div>
-        <div class="absolute bottom-36 right-2">
-            <ContinueButtonComponent
-                @click="onButtonClick"
-                :disabled="!isFormValid"
-                class="px-10 py-3 text-2xl font-bold mb-4 mr-2"
-            ></ContinueButtonComponent>
-        </div>
-    </div>
-</template>
-
-<script setup lang="ts">
-import { computed, ref } from 'vue'
-import { useAccountStore } from '@/stores/accountStore'
-import ContinueButtonComponent from '@/components/ContinueButtonComponent.vue'
-import router from '@/router'
-
-const MAX_DIGITS = 11
-const accountStore = useAccountStore()
-
-const spendingAccount = ref('')
-const savingsAccount = ref('')
-
-const isFormValid = computed(() => {
-    return (
-        spendingAccount.value.replace(/\./g, '').length === MAX_DIGITS &&
-        savingsAccount.value.replace(/\./g, '').length === MAX_DIGITS
-    )
-})
-
-async function onButtonClick() {
-    const savingAccountNumber = savingsAccount.value.replace(/\./g, '')
-    const spendingAccountNumber = spendingAccount.value.replace(/\./g, '')
-
-    await accountStore.postAccount('SAVING', savingAccountNumber, 0)
-
-    await accountStore.postAccount('SPENDING', spendingAccountNumber, 0)
-
-    await router.push({ name: 'home', query: { firstLogin: 'true' } })
-}
-
-function restrictToNumbers(event: InputEvent, type: string) {
-    const inputValue = (event.target as HTMLInputElement)?.value
-    if (inputValue !== undefined) {
-        const sanitizedValue = inputValue.replace(/\D/g, '')
-        const truncatedValue = sanitizedValue.slice(0, MAX_DIGITS)
-        if (type === 'spending') {
-            spendingAccount.value = truncatedValue
-        } else {
-            savingsAccount.value = truncatedValue
-        }
-    }
-}
-
-function applyFormatting(type: string) {
-    if (type === 'spending') {
-        spendingAccount.value = formatAccount(spendingAccount.value)
-    } else {
-        savingsAccount.value = formatAccount(savingsAccount.value)
-    }
-}
-
-function removeFormatting(type: string) {
-    if (type === 'spending') {
-        spendingAccount.value = removeFormat(spendingAccount.value)
-    } else {
-        savingsAccount.value = removeFormat(savingsAccount.value)
-    }
-}
-
-function formatAccount(value: string): string {
-    return value.replace(/\D/g, '').replace(/^(.{4})(.{2})(.*)$/, '$1.$2.$3')
-}
-
-function removeFormat(value: string): string {
-    return value.replace(/\./g, '')
-}
-</script>
diff --git a/src/views/ConfigFamiliarWithSavingsView.vue b/src/views/ConfigFamiliarWithSavingsView.vue
deleted file mode 100644
index ecbd66aa41acbc1aa29f2fd9405ec17cb0c00213..0000000000000000000000000000000000000000
--- a/src/views/ConfigFamiliarWithSavingsView.vue
+++ /dev/null
@@ -1,84 +0,0 @@
-<template>
-    <div class="flex flex-col items-center justify-center min-h-screen px-4 text-center">
-        <h1 class="mb-8 text-2xl font-bold sm:mb-16 sm:text-4xl">
-            Hvor kjent er du med sparing fra før?
-        </h1>
-        <div class="grid grid-cols-1 gap-8 mb-16 sm:gap-14 sm:mb-20 md:grid-cols-3">
-            <div
-                :class="{
-                    'border-[var(--green)] border-4': selectedOption === 'litt',
-                    'border-gray-300 border-2': selectedOption !== 'litt'
-                }"
-                class="flex flex-col items-center justify-center w-40 h-40 p-2 sm:w-64 sm:h-64 transition-colors rounded-lg cursor-pointer hover:border-[var(--green)]"
-                @click="selectOption('litt')"
-            >
-                <img src="@/assets/nose.png" alt="Pig nose" class="h-12 sm:h-1/3" />
-                <p class="mt-2 text-lg font-bold">Litt kjent</p>
-            </div>
-            <div
-                :class="{
-                    'border-[var(--green)] border-4': selectedOption === 'noe',
-                    'border-gray-300 border-2': selectedOption !== 'noe'
-                }"
-                class="flex flex-col items-center justify-center w-40 h-40 p-2 sm:w-64 sm:h-64 transition-colors rounded-lg cursor-pointer hover:border-[var(--green)]"
-                @click="selectOption('noe')"
-            >
-                <img src="@/assets/head.png" alt="Pig face" class="h-12 sm:h-1/3" />
-                <p class="mt-2 text-lg font-bold">Noe kjent</p>
-            </div>
-            <div
-                :class="{
-                    'border-[var(--green)] border-4': selectedOption === 'godt',
-                    'border-gray-300 border-2': selectedOption !== 'godt'
-                }"
-                class="flex flex-col items-center justify-center w-40 h-40 p-2 sm:w-64 sm:h-64 transition-colors rounded-lg cursor-pointer hover:border-[var(--green)]"
-                @click="selectOption('godt')"
-            >
-                <img src="@/assets/pig.png" alt="Whole pig" class="h-12 sm:h-1/3" />
-                <p class="mt-2 text-lg font-bold">Godt kjent</p>
-            </div>
-        </div>
-        <ContinueButtonComponent
-            :disabled="selectedOption === null"
-            @click="onButtonClick"
-            class="px-10 py-3 text-2xl self-end"
-        ></ContinueButtonComponent>
-    </div>
-</template>
-
-<script setup lang="ts">
-import { ref } from 'vue'
-import ContinueButtonComponent from '@/components/ContinueButtonComponent.vue'
-import router from '@/router'
-import { useUserConfigStore } from '@/stores/userConfigStore'
-
-const selectedOption = ref<string | null>(null)
-const userConfigStore = useUserConfigStore()
-
-const selectOption = (option: string) => {
-    selectedOption.value = option
-    let experienceValue = ''
-
-    switch (option) {
-        case 'litt':
-            experienceValue = 'VERY_LOW'
-            break
-        case 'noe':
-            experienceValue = 'MEDIUM'
-            break
-        case 'godt':
-            experienceValue = 'VERY_HIGH'
-            break
-    }
-
-    userConfigStore.setExperience(experienceValue)
-}
-
-const onButtonClick = () => {
-    if (selectedOption.value) {
-        router.push({ name: 'configurations3' })
-    } else {
-        console.error('No option selected')
-    }
-}
-</script>
diff --git a/src/views/ConfigHabitChangeView.vue b/src/views/ConfigHabitChangeView.vue
deleted file mode 100644
index a1e8b37350d385d2c3f31db77f2b8c81b56b6e41..0000000000000000000000000000000000000000
--- a/src/views/ConfigHabitChangeView.vue
+++ /dev/null
@@ -1,84 +0,0 @@
-<template>
-    <div class="flex flex-col items-center justify-center min-h-screen px-4 text-center">
-        <h1 class="mb-8 text-2xl font-bold sm:mb-16 sm:text-4xl">
-            Hvor store vaneedringer er du villig til å gjøre?
-        </h1>
-        <div class="grid grid-cols-1 gap-8 mb-16 sm:gap-14 sm:mb-20 md:grid-cols-3">
-            <div
-                :class="{
-                    'border-[var(--green)] border-4': selectedOption === 'litt',
-                    'border-gray-300 border-2': selectedOption !== 'litt'
-                }"
-                class="flex flex-col items-center justify-center w-40 h-40 p-2 sm:w-64 sm:h-64 transition-colors rounded-lg cursor-pointer hover:border-[var(--green)]"
-                @click="selectOption('litt')"
-            >
-                <img src="@/assets/litt.png" alt="Thumbs down emoji" class="h-12 sm:h-1/3" />
-                <p class="mt-2 text-md sm:text-lg font-bold">Litt</p>
-            </div>
-            <div
-                :class="{
-                    'border-[var(--green)] border-4': selectedOption === 'passe',
-                    'border-gray-300 border-2': selectedOption !== 'passe'
-                }"
-                class="flex flex-col items-center justify-center w-40 h-40 p-2 sm:w-64 sm:h-64 transition-colors rounded-lg cursor-pointer hover:border-[var(--green)]"
-                @click="selectOption('passe')"
-            >
-                <img src="@/assets/passe.png" alt="A little bit emoji" class="h-12 sm:h-1/3" />
-                <p class="mt-2 text-md sm:text-lg font-bold">Passe</p>
-            </div>
-            <div
-                :class="{
-                    'border-[var(--green)] border-4': selectedOption === 'store',
-                    'border-gray-300 border-2': selectedOption !== 'store'
-                }"
-                class="flex flex-col items-center justify-center w-40 h-40 p-2 sm:w-64 sm:h-64 transition-colors rounded-lg cursor-pointer hover:border-[var(--green)]"
-                @click="selectOption('store')"
-            >
-                <img src="@/assets/store.png" alt="Thumbs up emoji" class="h-12 sm:h-1/3" />
-                <p class="mt-2 text-md sm:text-lg font-bold">Store</p>
-            </div>
-        </div>
-        <ContinueButtonComponent
-            :disabled="selectedOption === null"
-            @click="onButtonClick"
-            class="px-10 py-3 text-2xl self-end"
-        ></ContinueButtonComponent>
-    </div>
-</template>
-
-<script setup lang="ts">
-import { ref } from 'vue'
-import ContinueButtonComponent from '@/components/ContinueButtonComponent.vue'
-import router from '@/router'
-import { useUserConfigStore } from '@/stores/userConfigStore'
-
-const selectedOption = ref<string | null>(null)
-const userConfigStore = useUserConfigStore()
-
-const selectOption = (option: string) => {
-    selectedOption.value = option
-    let motivationValue = ''
-
-    switch (option) {
-        case 'litt':
-            motivationValue = 'VERY_LOW'
-            break
-        case 'passe':
-            motivationValue = 'MEDIUM'
-            break
-        case 'store':
-            motivationValue = 'VERY_HIGH'
-            break
-    }
-
-    userConfigStore.setMotivation(motivationValue)
-}
-
-const onButtonClick = () => {
-    if (selectedOption.value) {
-        router.push({ name: 'configurations2' })
-    } else {
-        console.error('No option selected')
-    }
-}
-</script>
diff --git a/src/views/ConfigSpendingItemsAmountView.vue b/src/views/ConfigSpendingItemsAmountView.vue
deleted file mode 100644
index aa77feb1371de00b5a70dfe7815dd86e77f939c5..0000000000000000000000000000000000000000
--- a/src/views/ConfigSpendingItemsAmountView.vue
+++ /dev/null
@@ -1,110 +0,0 @@
-<template>
-    <div class="flex flex-col items-center justify-center min-h-screen px-4 text-center relative">
-        <h1 class="mb-8 text-2xl font-bold sm:mb-16 sm:text-4xl">
-            Hvor mye bruker du per kjøp på ...
-        </h1>
-        <div class="w-full flex justify-center">
-            <div :class="[showSecondBox ? 'md:grid md:grid-cols-2 md:gap-4 sm:gap-8 mb-6' : '']">
-                <div
-                    v-if="showFirstBox"
-                    class="flex flex-col items-center bg-white rounded-lg p-4 sm:p-8 shadow-lg"
-                    :class="showSecondBox ? 'w-full' : 'w-full md:w-1/2 mx-auto'"
-                    :style="{ minWidth: '400px', maxWidth: '400px' }"
-                >
-                    <div
-                        v-for="(option, index) in firstBoxOptions"
-                        :key="`first-option-${index}`"
-                        class="w-full my-4"
-                    >
-                        <div class="flex justify-between items-center">
-                            <p class="text-xl font-bold mr-4">{{ option.type }}</p>
-                            <div class="flex items-center w-2/3">
-                                <input
-                                    v-model="amounts[index]"
-                                    @input="filterAmount(index, $event)"
-                                    class="h-11 px-3 rounded-md text-lg focus:outline-none border-2 w-full"
-                                    :class="{
-                                        'border-gray-300': !amounts[index],
-                                        'border-[var(--green)]': amounts[index]
-                                    }"
-                                />
-                                <p class="text-xl font-bold ml-2">kr</p>
-                            </div>
-                        </div>
-                    </div>
-                </div>
-                <div
-                    v-if="showSecondBox"
-                    class="flex flex-col items-center bg-white rounded-lg p-4 sm:p-8 shadow-lg"
-                    :class="showSecondBox ? 'w-full' : 'w-full md:w-1/2 mx-auto'"
-                    :style="{ minWidth: '400px', maxWidth: '400px' }"
-                >
-                    <div
-                        v-for="(option, index) in secondBoxOptions"
-                        :key="`second-option-${index}`"
-                        class="w-full my-4"
-                    >
-                        <div class="flex justify-between items-center">
-                            <p class="text-xl font-bold mr-4">{{ option.type }}</p>
-                            <div class="flex items-center w-2/3">
-                                <input
-                                    v-model="amounts[index + firstBoxOptions.length]"
-                                    @input="filterAmount(index + firstBoxOptions.length, $event)"
-                                    class="h-11 px-3 rounded-md text-lg focus:outline-none border-2 w-full"
-                                    :class="{
-                                        'border-gray-300': !amounts[index + firstBoxOptions.length],
-                                        'border-[var(--green)]':
-                                            amounts[index + firstBoxOptions.length]
-                                    }"
-                                />
-                                <p class="text-xl font-bold ml-2">kr</p>
-                            </div>
-                        </div>
-                    </div>
-                </div>
-            </div>
-        </div>
-        <div class="w-full text-right">
-            <ContinueButtonComponent
-                @click="onButtonClick"
-                :disabled="!isAllAmountsFilled"
-                class="px-10 py-3 text-2xl font-bold mb-20 mt-10 sm:mb-12 sm:mt-10"
-            ></ContinueButtonComponent>
-        </div>
-    </div>
-</template>
-
-<script setup lang="ts">
-import { computed, ref } from 'vue'
-import ContinueButtonComponent from '@/components/ContinueButtonComponent.vue'
-import router from '@/router'
-import { useUserConfigStore } from '@/stores/userConfigStore'
-
-const userConfigStore = useUserConfigStore()
-
-const options = ref(userConfigStore.challengeTypeConfigs)
-const amounts = ref(options.value.map(() => ''))
-
-const isAllAmountsFilled = computed(() => amounts.value.every((amount) => amount.trim() !== ''))
-
-const onButtonClick = () => {
-    options.value.forEach((option, index) => {
-        userConfigStore.challengeTypeConfigs[index].specificAmount =
-            parseFloat(amounts.value[index]) || 0
-    })
-    router.push({ name: 'configurations5' })
-}
-
-const filterAmount = (index: number, event: Event) => {
-    const input = event.target as HTMLInputElement
-    let filteredValue = input.value.replace(/[^\d,]/g, '')
-    filteredValue = filteredValue.replace(/(,.*?),/g, '$1').replace(/,+/g, ',')
-    amounts.value[index] = filteredValue
-}
-
-const firstBoxOptions = computed(() => options.value.slice(0, 6))
-const secondBoxOptions = computed(() => (options.value.length > 6 ? options.value.slice(6) : []))
-
-const showFirstBox = computed(() => options.value.length > 0)
-const showSecondBox = computed(() => options.value.length > 6)
-</script>
diff --git a/src/views/ConfigSpendingItemsTotalAmountView.vue b/src/views/ConfigSpendingItemsTotalAmountView.vue
deleted file mode 100644
index 098ba86faec729bcbc8450ad91268d7e65d82536..0000000000000000000000000000000000000000
--- a/src/views/ConfigSpendingItemsTotalAmountView.vue
+++ /dev/null
@@ -1,112 +0,0 @@
-<template>
-    <div class="flex flex-col items-center justify-center min-h-screen px-4 text-center relative">
-        <h1 class="mb-8 text-2xl font-bold sm:mb-16 sm:text-4xl">
-            Hvor mye bruker du per uke på ...
-        </h1>
-        <div class="w-full flex justify-center">
-            <div :class="[showSecondBox ? 'md:grid md:grid-cols-2 md:gap-4 sm:gap-8 mb-6' : '']">
-                <div
-                    v-if="showFirstBox"
-                    class="flex flex-col items-center bg-white rounded-lg p-4 sm:p-8 shadow-lg"
-                    :class="showSecondBox ? 'w-full' : 'w-full md:w-1/2 mx-auto'"
-                    :style="{ minWidth: '400px', maxWidth: '400px' }"
-                >
-                    <div
-                        v-for="(option, index) in firstBoxOptions"
-                        :key="`first-option-${index}`"
-                        class="w-full my-4"
-                    >
-                        <div class="flex justify-between items-center">
-                            <p class="text-xl font-bold mr-4">{{ option.type }}</p>
-                            <div class="flex items-center w-2/3">
-                                <input
-                                    v-model="amounts[index]"
-                                    @input="filterAmount(index, $event)"
-                                    class="h-11 px-3 rounded-md text-lg focus:outline-none border-2 w-full"
-                                    :class="{
-                                        'border-gray-300': !amounts[index],
-                                        'border-[var(--green)]': amounts[index]
-                                    }"
-                                />
-                                <p class="text-xl font-bold ml-2">kr</p>
-                            </div>
-                        </div>
-                    </div>
-                </div>
-                <div
-                    v-if="showSecondBox"
-                    class="flex flex-col items-center bg-white rounded-lg p-4 sm:p-8 shadow-lg"
-                    :class="showSecondBox ? 'w-full' : 'w-full md:w-1/2 mx-auto'"
-                    :style="{ minWidth: '400px', maxWidth: '400px' }"
-                >
-                    <div
-                        v-for="(option, index) in secondBoxOptions"
-                        :key="`second-option-${index}`"
-                        class="w-full my-4"
-                    >
-                        <div class="flex justify-between items-center">
-                            <p class="text-xl font-bold mr-4">{{ option.type }}</p>
-                            <div class="flex items-center w-2/3">
-                                <input
-                                    v-model="amounts[index + firstBoxOptions.length]"
-                                    @input="filterAmount(index + firstBoxOptions.length, $event)"
-                                    class="h-11 px-3 rounded-md text-lg focus:outline-none border-2 w-full"
-                                    :class="{
-                                        'border-gray-300': !amounts[index + firstBoxOptions.length],
-                                        'border-[var(--green)]':
-                                            amounts[index + firstBoxOptions.length]
-                                    }"
-                                />
-                                <p class="text-xl font-bold ml-2">kr</p>
-                            </div>
-                        </div>
-                    </div>
-                </div>
-            </div>
-        </div>
-        <div class="w-full text-right">
-            <ContinueButtonComponent
-                @click="onButtonClick"
-                :disabled="!isAllAmountsFilled"
-                class="px-10 py-3 text-2xl font-bold mb-20 mt-10 sm:mb-12 sm:mt-10"
-            ></ContinueButtonComponent>
-        </div>
-    </div>
-</template>
-
-<script setup lang="ts">
-import { computed, ref } from 'vue'
-import ContinueButtonComponent from '@/components/ContinueButtonComponent.vue'
-import router from '@/router'
-import { useUserConfigStore } from '@/stores/userConfigStore'
-
-const userConfigStore = useUserConfigStore()
-
-const options = ref(userConfigStore.challengeTypeConfigs)
-const amounts = ref(options.value.map(() => ''))
-
-const isAllAmountsFilled = computed(() => amounts.value.every((amount) => amount.trim() !== ''))
-
-const onButtonClick = async () => {
-    options.value.forEach((option, index) => {
-        userConfigStore.challengeTypeConfigs[index].generalAmount =
-            parseFloat(amounts.value[index]) || 0
-    })
-
-    userConfigStore.postUserConfig()
-    await router.push({ name: 'configurations6' })
-}
-
-const filterAmount = (index: number, event: Event) => {
-    const input = event.target as HTMLInputElement
-    let filteredValue = input.value.replace(/[^\d,]/g, '')
-    filteredValue = filteredValue.replace(/(,.*?),/g, '$1').replace(/,+/g, ',')
-    amounts.value[index] = filteredValue
-}
-
-const firstBoxOptions = computed(() => options.value.slice(0, 6))
-const secondBoxOptions = computed(() => (options.value.length > 6 ? options.value.slice(6) : []))
-
-const showFirstBox = computed(() => options.value.length > 0)
-const showSecondBox = computed(() => options.value.length > 6)
-</script>
diff --git a/src/views/ConfigSpendingItemsView.vue b/src/views/ConfigSpendingItemsView.vue
deleted file mode 100644
index fbeda5f09011b4a3f8639d752c02eab917c32e14..0000000000000000000000000000000000000000
--- a/src/views/ConfigSpendingItemsView.vue
+++ /dev/null
@@ -1,114 +0,0 @@
-<template>
-    <div class="flex flex-col items-center justify-center min-h-screen text-center">
-        <h1 class="mb-8 text-2xl font-bold sm:mb-16 sm:text-4xl">Hva bruker du mye penger på?</h1>
-        <div class="flex flex-wrap justify-center gap-8 mb-8">
-            <div
-                class="flex flex-col items-center justify-center bg-white rounded-lg sm:p-8 shadow-lg sm:w-full md:w-[45%]"
-            >
-                <div
-                    v-for="buttonText in [
-                        'Kaffe',
-                        'Snus',
-                        'Kantina',
-                        'Sigaretter',
-                        'Transport',
-                        'Klær'
-                    ]"
-                    :key="buttonText"
-                    class="w-full my-4"
-                >
-                    <button
-                        :class="[
-                            'w-full md:w-64 h-11 rounded-md text-xl font-bold',
-                            selectedOptions.includes(buttonText)
-                                ? 'border-2 border-[var(--green)]'
-                                : 'border-2 border-gray-300'
-                        ]"
-                        @click="toggleOption(buttonText)"
-                        style="background: transparent"
-                    >
-                        {{ buttonText }}
-                    </button>
-                </div>
-            </div>
-            <div
-                class="flex flex-col items-center justify-center bg-white rounded-lg sm:p-8 shadow-lg sm:w-full md:w-[45%]"
-            >
-                <div
-                    v-for="(option, index) in customOptions"
-                    :key="`custom-${index}`"
-                    class="w-full my-4"
-                >
-                    <input
-                        v-model="customOptions[index]"
-                        :class="[
-                            'w-full md:w-64 h-11 px-3 rounded-md text-xl focus:outline-none transition-colors border-2',
-                            customOptions[index].trim() !== ''
-                                ? 'border-[var(--green)]'
-                                : 'border-gray-300'
-                        ]"
-                        type="text"
-                        :placeholder="'Annet ' + ' ...'"
-                    />
-                </div>
-            </div>
-        </div>
-        <div class="w-full text-right">
-            <ContinueButtonComponent
-                @click="onButtonClick"
-                :disabled="!isFormValid"
-                class="px-10 py-3 text-2xl font-bold mt-36 mr-4 sm:mb-12 sm:mt-10"
-            ></ContinueButtonComponent>
-        </div>
-    </div>
-</template>
-
-<script setup lang="ts">
-import { computed, ref } from 'vue'
-import ContinueButtonComponent from '@/components/ContinueButtonComponent.vue'
-import router from '@/router'
-import { useUserConfigStore } from '@/stores/userConfigStore'
-
-const userConfigStore = useUserConfigStore()
-const selectedOptions = ref<string[]>([])
-const customOptions = ref(['', '', '', '', '', ''])
-
-const toggleOption = (option: string) => {
-    const index = selectedOptions.value.indexOf(option)
-    if (index === -1) {
-        selectedOptions.value.push(option)
-    } else {
-        selectedOptions.value.splice(index, 1)
-    }
-}
-
-const isFormValid = computed(() => {
-    const predefinedSelected = selectedOptions.value.length > 0
-    const customFilled = customOptions.value.some((option) => option.trim() !== '')
-    return predefinedSelected || customFilled
-})
-
-const onButtonClick = () => {
-    if (!isFormValid.value) {
-        console.error('Form is not valid')
-        return
-    }
-
-    const predefinedChallengeTypes = selectedOptions.value.map((option) => ({
-        type: option,
-        specificAmount: 0,
-        generalAmount: 0
-    }))
-
-    const customChallengeTypes = customOptions.value
-        .filter((option) => option.trim() !== '')
-        .map((option) => ({
-            type: option,
-            specificAmount: 0,
-            generalAmount: 0
-        }))
-
-    userConfigStore.challengeTypeConfigs = [...predefinedChallengeTypes, ...customChallengeTypes]
-    router.push({ name: 'configurations4' })
-}
-</script>
diff --git a/src/views/EditProfileView.vue b/src/views/EditProfileView.vue
deleted file mode 100644
index bb251d91ff657f3f5613f2e5caf2a168ad65e888..0000000000000000000000000000000000000000
--- a/src/views/EditProfileView.vue
+++ /dev/null
@@ -1,256 +0,0 @@
-<script lang="ts" setup>
-import authInterceptor from '@/services/authInterceptor'
-import { computed, onMounted, ref } from 'vue'
-import type { Profile } from '@/types/profile'
-import CardTemplate from '@/views/CardTemplate.vue'
-import router from '@/router'
-import ToolTip from '@/components/ToolTip.vue'
-import InteractiveSpare from '@/components/InteractiveSpare.vue'
-
-const profile = ref<Profile>({
-    id: 0,
-    firstName: '',
-    lastName: '',
-    email: '',
-    username: '',
-    password: '',
-    spendingAccount: {
-        accNumber: undefined,
-        balance: 0
-    },
-    savingAccount: {
-        accNumber: undefined,
-        balance: 0
-    }
-})
-
-const updatePassword = ref<boolean>(false)
-const confirmPassword = ref<string>('')
-const errorMessage = ref<string>('')
-const isModalOpen = ref(false)
-
-const nameRegex = /^[æÆøØåÅa-zA-Z,.'-][æÆøØåÅa-zA-Z ,.'-]{1,29}$/
-const emailRegex =
-    /^[æÆøØåÅa-zA-Z0-9_+&*-]+(?:\.[æÆøØåÅa-zA-Z0-9_+&*-]+)*@(?:[æÆøØåÅa-zA-Z0-9-]+\.)+[æÆøØåÅa-zA-Z]{2,7}$/
-const usernameRegex = /^[ÆØÅæøåA-Za-z][æÆøØåÅA-Za-z0-9_]{2,29}$/
-const passwordRegex = /^(?=.*[0-9])(?=.*[a-zæøå])(?=.*[ÆØÅA-Z])(?=.*[@#$%^&+=!])(?=\S+$).{8,30}$/
-const accountNumberRegex = /^\d{11}$/
-
-const isFirstNameValid = computed(
-    () => nameRegex.test(profile.value.firstName) && profile.value.firstName
-)
-const isLastNameValid = computed(
-    () => nameRegex.test(profile.value.lastName) && profile.value.lastName
-)
-const isEmailValid = computed(() => emailRegex.test(profile.value.email))
-const isUsernameValid = computed(() => usernameRegex.test(profile.value.username))
-const isPasswordValid = computed(() => passwordRegex.test(profile.value.password || ''))
-const isSpendingAccountValid = computed(() =>
-    accountNumberRegex.test(profile.value.spendingAccount.accNumber?.toString() || '')
-)
-const isSavingAccountValid = computed(() =>
-    accountNumberRegex.test(profile.value.savingAccount.accNumber?.toString() || '')
-)
-
-const isFormInvalid = computed(
-    () =>
-        [
-            isFirstNameValid,
-            isLastNameValid,
-            isEmailValid,
-            isUsernameValid,
-            isSpendingAccountValid,
-            isSavingAccountValid
-        ].some((v) => !v.value) ||
-        (updatePassword.value
-            ? profile.value.password !== confirmPassword.value || profile.value.password === ''
-            : false)
-)
-
-onMounted(async () => {
-    await authInterceptor('/profile')
-        .then((response) => {
-            profile.value = response.data
-            console.log(profile.value)
-        })
-        .catch((error) => {
-            return console.log(error)
-        })
-})
-
-const saveChanges = async () => {
-    if (isFormInvalid.value) {
-        errorMessage.value = 'Vennligst fyll ut alle feltene riktig'
-        return
-    }
-
-    if (!updatePassword.value) {
-        delete profile.value.password
-    }
-
-    await authInterceptor
-        .put('/profile', profile.value)
-        .then(() => {
-            router.back()
-        })
-        .catch((error) => {
-            errorMessage.value = error.response.data.message
-        })
-}
-</script>
-
-<template>
-    <div class="w-full flex px-10 justify-center">
-        <div class="flex flex-row flex-wrap justify-center w-full max-w-screen-xl gap-20">
-            <div class="flex flex-col max-w-96 w-full gap-5">
-                <h1>Rediger profil</h1>
-                <div class="w-full flex flex-row gap-5 justify-between justify-items-end">
-                    <div class="flex flex-col justify-center">
-                        <button class="h-min bg-transparent text-4xl" v-text="'⬅️'" />
-                    </div>
-                    <div class="w-32 h-32 border-black border-2 rounded-full shrink-0" />
-                    <div class="flex flex-col justify-center">
-                        <button class="h-min bg-transparent text-4xl" v-text="'➡️'" />
-                    </div>
-                </div>
-
-                <div class="flex flex-col">
-                    <div class="flex flex-row justify-between mx-4">
-                        <p>Fornavn*</p>
-                        <ToolTip
-                            :message="'Must include only letters, spaces, commas, apostrophes, periods, and hyphens. 1-30 characters long'"
-                        />
-                    </div>
-                    <input
-                        v-model="profile.firstName"
-                        :class="{ 'bg-green-200': isFirstNameValid }"
-                        name="firstname"
-                        placeholder="Skriv inn fornavn"
-                        type="text"
-                    />
-                </div>
-                <div class="flex flex-col">
-                    <div class="flex flex-row justify-between mx-4">
-                        <p>Etternavn*</p>
-                        <ToolTip
-                            :message="'Must include only letters, spaces, commas, apostrophes, periods, and hyphens. 1-30 characters long'"
-                        />
-                    </div>
-                    <input
-                        v-model="profile.lastName"
-                        :class="{ 'bg-green-200': isLastNameValid }"
-                        name="lastname"
-                        placeholder="Skriv inn etternavn"
-                        type="text"
-                    />
-                </div>
-                <div class="flex flex-col">
-                    <div class="flex flex-row justify-between mx-4">
-                        <p>E-post*</p>
-                        <ToolTip
-                            :message="'Valid email: Starts with Norwegian letters, numbers, or special characters. Includes \@\ followed by a domain. Ends with 2-7 letters.'"
-                        />
-                    </div>
-                    <input
-                        v-model="profile.email"
-                        :class="{ 'bg-green-200': isEmailValid }"
-                        name="email"
-                        placeholder="Skriv inn e-post"
-                        type="text"
-                    />
-                </div>
-                <div class="flex flex-col">
-                    <div class="flex flex-row justify-between mx-4">
-                        <p>Brukernavn*</p>
-                        <ToolTip
-                            :message="'Must start with a letter and can include numbers and underscores. 3-30 characters long.'"
-                        />
-                    </div>
-                    <input
-                        v-model="profile.username"
-                        :class="{ 'bg-green-200': isUsernameValid }"
-                        name="username"
-                        placeholder="Skriv inn brukernavn"
-                        type="text"
-                    />
-                </div>
-                <div class="flex flex-col">
-                    <div class="flex flex-row justify-between mx-4">
-                        <div class="flex flex-row gap-2">
-                            <p>Endre passord</p>
-                            <input v-model="updatePassword" type="checkbox" />
-                        </div>
-                        <ToolTip
-                            v-if="updatePassword"
-                            :message="'Must be at least 8 characters, including at least one number, one lowercase letter, one uppercase letter, one special character (@#$%^&+=!), and no spaces.'"
-                        />
-                    </div>
-                    <input
-                        v-if="updatePassword"
-                        v-model="profile.password"
-                        :class="{ 'bg-green-200': isPasswordValid }"
-                        class="w-full"
-                        name="password"
-                        placeholder="Skriv inn passord"
-                    />
-                    <input
-                        v-if="updatePassword"
-                        v-model="confirmPassword"
-                        :class="{ 'bg-red-200': profile.password !== confirmPassword }"
-                        class="mt-2"
-                        name="confirm"
-                        placeholder="Bekreft passord"
-                        type="password"
-                    />
-                </div>
-
-                <p v-if="errorMessage" class="text-red-500" v-text="errorMessage" />
-            </div>
-            <div class="flex flex-col justify-end max-w-96 w-full gap-5">
-                <InteractiveSpare
-                    :png-size="10"
-                    :speech="['Her kan du endre på profilen din!']"
-                    direction="left"
-                    :isModalOpen="isModalOpen"
-                />
-
-                <CardTemplate>
-                    <div class="bg-red-300">
-                        <p class="font-bold mx-3" v-text="'Brukskonto'" />
-                    </div>
-                    <input
-                        v-model="profile.spendingAccount.accNumber"
-                        :class="{ 'bg-green-200': isSpendingAccountValid }"
-                        class="border-2 rounded-none rounded-b-xl w-full"
-                        placeholder="Kontonummer"
-                        type="number"
-                    />
-                </CardTemplate>
-
-                <CardTemplate>
-                    <div class="bg-red-300">
-                        <p class="font-bold mx-3" v-text="'Sparekonto'" />
-                    </div>
-                    <input
-                        v-model="profile.savingAccount.accNumber"
-                        :class="{ 'bg-green-200': isSavingAccountValid }"
-                        class="border-2 rounded-none rounded-b-xl w-full"
-                        placeholder="Kontonummer"
-                        type="number"
-                    />
-                </CardTemplate>
-
-                <div class="flex flex-row justify-between">
-                    <button class="bg-button-other" @click="router.back()" v-text="'Avbryt'" />
-                    <button
-                        :disabled="isFormInvalid"
-                        @click="saveChanges"
-                        v-text="'Lagre endringer'"
-                    />
-                </div>
-            </div>
-        </div>
-    </div>
-</template>
-
-<style scoped></style>
diff --git a/src/views/FirstSavingChallengeView.vue b/src/views/FirstSavingChallengeView.vue
deleted file mode 100644
index 23cc78e8411420523f7b280e58da5ef88564005b..0000000000000000000000000000000000000000
--- a/src/views/FirstSavingChallengeView.vue
+++ /dev/null
@@ -1,112 +0,0 @@
-<template>
-    <div class="flex flex-col items-center justify-start min-h-screen px-4 text-center">
-        <div class="mb-20">
-            <div
-                class="flex flex-col items-center justify-start bg-white shadow-md rounded-lg p-16"
-                style="height: 530px; min-height: 500px; min-width: 400px; max-width: 400px"
-            >
-                <template v-if="!skipped && !accepted">
-                    <div class="mb-6 w-full text-left">
-                        <label for="savings-goal" class="block text-4xl font-bold mb-2"
-                            >Spareutfordring</label
-                        >
-                    </div>
-                    <div class="flex flex-col w-full mb-4">
-                        <button
-                            v-for="buttonText in buttonOptions"
-                            :key="buttonText"
-                            :class="[
-                                'mb-4 text-xl font-bold w-full rounded-lg py-3 px-4',
-                                selectedOptions.includes(buttonText)
-                                    ? 'bg-transparent border-2 border-[var(--green)]'
-                                    : 'bg-transparent border-2 border-gray-300'
-                            ]"
-                            @click="toggleOption(buttonText)"
-                        >
-                            {{ buttonText }}
-                        </button>
-                    </div>
-                    <div class="flex justify-between w-full mt-4 space-x-2">
-                        <button
-                            class="border-4 font-bold rounded-lg py-2 px-10 text-lg transition-all bg-[var(--green)] hover:brightness-90 active:brightness-75"
-                            @click="skip"
-                            style="margin-top: 29px"
-                        >
-                            Skip
-                        </button>
-                        <button
-                            :class="[
-                                'border-4 font-bold rounded-lg py-2 px-10 text-lg transition-all',
-                                {
-                                    'bg-[var(--green)] hover:brightness-90 active:brightness-75':
-                                        selectedOptions.length > 0
-                                },
-                                {
-                                    'opacity-60 bg-[rgba(149,227,93,0.6)] cursor-not-allowed':
-                                        selectedOptions.length === 0
-                                }
-                            ]"
-                            :disabled="selectedOptions.length === 0"
-                            @click="accept"
-                            style="margin-top: 29px"
-                        >
-                            Godta
-                        </button>
-                    </div>
-                </template>
-                <template v-else>
-                    <div class="flex justify-center items-center h-full">
-                        <div class="text-4xl font-bold">{{ acceptedMessage }}</div>
-                    </div>
-                </template>
-            </div>
-        </div>
-        <ContinueButtonComponent
-            :disabled="!skipped && !accepted"
-            @click="onButtonClick"
-            class="px-10 py-3 text-2xl font-bold self-end mb-32 mt-[-10px]"
-        ></ContinueButtonComponent>
-    </div>
-</template>
-
-<script setup lang="ts">
-import ContinueButtonComponent from '@/components/ContinueButtonComponent.vue'
-import router from '@/router'
-import { ref, watchEffect } from 'vue'
-
-const buttonOptions = ref(['Ikke kjøpe kaffe', 'Ikke kjøpe snus', 'Ikke kjøpe mat i kantina'])
-const selectedOptions = ref<string[]>([])
-const skipped = ref(false)
-const accepted = ref(false)
-
-const toggleOption = (option: string) => {
-    const index = selectedOptions.value.indexOf(option)
-    if (index === -1) {
-        selectedOptions.value.push(option)
-    } else {
-        selectedOptions.value.splice(index, 1)
-    }
-}
-
-const onButtonClick = () => {
-    router.push('/')
-}
-
-const skip = () => {
-    skipped.value = true
-}
-
-const accept = () => {
-    accepted.value = true
-}
-
-const acceptedMessage = ref('Du kan opprette spareutfordringer senere')
-
-watchEffect(() => {
-    if (accepted.value) {
-        acceptedMessage.value = 'Du har fått din første spareutfordring!'
-    } else if (skipped.value) {
-        acceptedMessage.value = 'Du kan opprette spareutfordringer senere'
-    }
-})
-</script>
diff --git a/src/views/FirstSavingGoalView.vue b/src/views/FirstSavingGoalView.vue
deleted file mode 100644
index bd28ba97b26defe4d241f903d973e542c9636717..0000000000000000000000000000000000000000
--- a/src/views/FirstSavingGoalView.vue
+++ /dev/null
@@ -1,142 +0,0 @@
-<template>
-    <div class="flex flex-col items-center justify-start min-h-screen px-4 text-center">
-        <div class="mb-20">
-            <div
-                class="flex flex-col items-center justify-center bg-white shadow-md rounded-lg p-16"
-                style="height: 530px; min-height: 500px; min-width: 400px; max-width: 400px"
-            >
-                <template v-if="!skipped && !accepted">
-                    <div class="mb-6 w-full text-left">
-                        <label for="savings-goal" class="block text-xl font-bold mb-2"
-                            >Jeg vil spare til:</label
-                        >
-                        <input
-                            type="text"
-                            id="savings-goal"
-                            v-model="savingsGoal"
-                            :class="{
-                                'border-[var(--green)]': savingsGoal.valueOf(),
-                                'border-gray-300': !savingsGoal.valueOf()
-                            }"
-                            class="border-2 block w-full rounded-md shadow-sm focus:border-indigo-300 focus:ring focus:ring-indigo-200 focus:ring-opacity-50 text-xl"
-                            placeholder=""
-                        />
-                    </div>
-                    <div class="mb-8 w-full flex items-center">
-                        <label for="amount" class="shrink-0 text-xl font-bold mr-2"
-                            >Jeg vil spare:</label
-                        >
-                        <input
-                            type="text"
-                            id="amount"
-                            v-model="rawAmount"
-                            :class="{
-                                'border-[var(--green)]': rawAmount.valueOf(),
-                                'border-gray-300': !rawAmount.valueOf()
-                            }"
-                            class="border-2 rounded-md shadow-sm focus:border-indigo-300 focus:ring focus:ring-indigo-200 focus:ring-opacity-50 text-xl mr-2 block w-full"
-                            placeholder=""
-                            min="0"
-                        />
-                        <span class="shrink-0 text-xl font-bold">kr</span>
-                    </div>
-                    <div class="w-full px-4 py-2">
-                        <img src="@/assets/penger.png" alt="Savings" class="mx-auto w-36 h-32" />
-                    </div>
-                    <div class="flex justify-between w-full mt-4 space-x-2">
-                        <button
-                            class="bg-[var(--green)] border-4 border-[var(--green)] hover:brightness-90 active:brightness-75 font-bold rounded-lg py-2 px-10 text-lg"
-                            @click="skip"
-                        >
-                            Skip
-                        </button>
-                        <button
-                            :class="[
-                                'border-4 font-bold rounded-lg py-2 px-10 text-lg transition-all',
-                                canAccept
-                                    ? 'bg-[var(--green)] hover:brightness-90 active:brightness-75'
-                                    : 'opacity-60 bg-gray-300 cursor-not-allowed'
-                            ]"
-                            :disabled="!canAccept"
-                            @click="accept"
-                        >
-                            Godta
-                        </button>
-                    </div>
-                </template>
-                <template v-else>
-                    <div
-                        class="flex justify-start items-center h-full min-h-[400px] min-w-[400px] max-w-[400px]"
-                    >
-                        <div class="text-4xl font-bold">{{ acceptedMessage }}</div>
-                    </div>
-                </template>
-            </div>
-        </div>
-        <ContinueButtonComponent
-            :disabled="!skipped && !accepted"
-            @click="onButtonClick"
-            class="px-10 py-3 text-lg font-bold self-end mb-80 mt-[-10px]"
-        ></ContinueButtonComponent>
-    </div>
-</template>
-
-<script setup lang="ts">
-import { computed, ref, watch, watchEffect } from 'vue'
-import ContinueButtonComponent from '@/components/ContinueButtonComponent.vue'
-import router from '@/router'
-
-const savingsGoal = ref('')
-const rawAmount = ref('')
-const skipped = ref(false)
-const accepted = ref(false)
-
-const validateAmount = () => {
-    const validPattern = /^(\d+)?(,\d*)?$/
-    if (!validPattern.test(rawAmount.value)) {
-        rawAmount.value = rawAmount.value.slice(0, -1)
-    } else if (rawAmount.value.includes(',')) {
-        rawAmount.value = rawAmount.value.replace(/,+/g, ',')
-    }
-}
-
-const checkNegative = () => {
-    const numericValue = parseFloat(rawAmount.value.replace(',', '.'))
-    if (numericValue < 0) {
-        rawAmount.value = ''
-    }
-}
-
-watch(rawAmount, validateAmount)
-watch(() => parseFloat(rawAmount.value.replace(',', '.')), checkNegative)
-
-const canAccept = computed(() => savingsGoal.value.trim() !== '' && rawAmount.value.trim() !== '')
-
-const skip = () => {
-    skipped.value = true
-    acceptedMessage.value = 'Du kan opprette sparemål senere'
-}
-
-const accept = () => {
-    if (canAccept.value) {
-        accepted.value = true
-        acceptedMessage.value = 'Du har fått ditt første sparemål!'
-    }
-}
-
-const onButtonClick = () => {
-    if (skipped.value || accepted.value) {
-        router.push('/forsteSpareutfordring')
-    }
-}
-
-const acceptedMessage = ref('')
-
-watchEffect(() => {
-    if (accepted.value) {
-        acceptedMessage.value = 'Du har fått ditt første sparemål!'
-    } else if (skipped.value) {
-        acceptedMessage.value = 'Du kan opprette sparemål senere'
-    }
-})
-</script>
diff --git a/src/views/HomeView.vue b/src/views/HomeView.vue
deleted file mode 100644
index fcdf62e7219bca4311b288fb439e6d10fd33d695..0000000000000000000000000000000000000000
--- a/src/views/HomeView.vue
+++ /dev/null
@@ -1,120 +0,0 @@
-<template>
-    <div class="flex flex-col items-center max-h-[60vh] md:flex-row md:max-h-[80vh] mx-auto">
-        <div class="flex flex-col basis-1/3 order-last md:order-first md:basis-1/4 md:pl-1 mt-10">
-            <img
-                v-if="newSpeechAvailable"
-                alt="Varsel"
-                class="jump scale-x-[-1] w-1/12 h-1/12 ml-52 cursor-pointer z-10"
-                src="@/assets/varsel.png"
-            />
-            <div class="flex items-center">
-                <a @click="openInteractiveSpare" class="hover:bg-transparent z-20">
-                    <img
-                        alt="Spare"
-                        class="scale-x-[-1] md:h-5/6 md:w-5/6 w-2/3 h-2/3 cursor-pointer ml-14 md:ml-10"
-                        src="@/assets/spare.png"
-                    />
-                </a>
-            </div>
-            <div class="flex flex-row gap-2 items-center mx-auto my-4 md:flex-col md:gap-4 md:m-8">
-                <ButtonAddGoalOrChallenge :buttonText="'Legg til sparemål'" :type="'goal'" />
-                <ButtonAddGoalOrChallenge
-                    :buttonText="'Legg til spareutfordring'"
-                    :type="'challenge'"
-                />
-            </div>
-        </div>
-        <savings-path :challenges="challenges" :goal="goal"></savings-path>
-    </div>
-    <InteractiveSpare
-        :speech="speech"
-        :direction="'right'"
-        :pngSize="15"
-        :isModalOpen="isModalOpen"
-        class="opacity-0 h-0 w-0 md:opacity-100 md:h-auto md:w-auto"
-    ></InteractiveSpare>
-    <div class="fixed bottom-5 left-5">
-        <div @click="openHelp" class="hover:cursor-pointer">
-            <img alt="Hjelp" class="w-1/12" src="@/assets/hjelp.png" />
-        </div>
-    </div>
-</template>
-
-<script setup lang="ts">
-import { onMounted, ref } from 'vue'
-import InteractiveSpare from '@/components/InteractiveSpare.vue'
-import ButtonAddGoalOrChallenge from '@/components/ButtonAddGoalOrChallenge.vue'
-import type { Challenge } from '@/types/challenge'
-import type { Goal } from '@/types/goal'
-import { useGoalStore } from '@/stores/goalStore'
-import { useChallengeStore } from '@/stores/challengeStore'
-import SavingsPath from '@/components/SavingsPath.vue'
-import router from '@/router'
-
-const goalStore = useGoalStore()
-const challengeStore = useChallengeStore()
-const isModalOpen = ref(false)
-const speech = ref<string[]>([])
-const newSpeechAvailable = ref(false)
-
-const challenges = ref<Challenge[]>([])
-const goals = ref<Goal[]>([])
-
-const goal = ref<Goal | null | undefined>(null)
-
-onMounted(async () => {
-    await goalStore.getUserGoals()
-    await challengeStore.getUserChallenges()
-    challenges.value = challengeStore.challenges
-    goals.value = goalStore.goals
-    goal.value = goals.value[0]
-    firstLoggedInSpeech()
-})
-
-// Check if the user is logging in for the first time, and display the first login speech
-const firstLoggedInSpeech = () => {
-    const isFirstLogin = router.currentRoute.value.query.firstLogin === 'true'
-    if (isFirstLogin) {
-        speech.value = [
-            'Hei, jeg er Spare!',
-            'Jeg skal hjelpe deg med å spare penger.',
-            'Du får varsel når jeg har noe å si!'
-        ]
-        isModalOpen.value = true
-        router.replace({ name: 'home', query: { firstLogin: 'false' } })
-    }
-}
-
-const openInteractiveSpare = () => {
-    // Check if there's new speech available before opening the modal.
-    if (newSpeechAvailable.value) {
-        isModalOpen.value = true // Open the modal
-        newSpeechAvailable.value = false // Reset the flag since the speech will now be displayed
-    }
-}
-const openHelp = () => {
-    speech.value = [
-        'Heisann, jeg er Spare!',
-        'Jeg skal hjelpe deg med å spare penger.',
-        'Du kan legge til sparemål og spareutfordringer!',
-        'Sammen kan vi spare penger og nå dine mål!'
-    ]
-    isModalOpen.value = true
-}
-</script>
-
-<style>
-@keyframes jump {
-    0%,
-    100% {
-        transform: translateY(0);
-    }
-    50% {
-        transform: translateY(-10px);
-    }
-}
-
-.jump {
-    animation: jump 0.6s infinite ease-in-out;
-}
-</style>
diff --git a/src/views/ManageChallengeView.vue b/src/views/ManageChallengeView.vue
deleted file mode 100644
index 7cf90c7a0afbce65fd3c47a48a693370bbc2af48..0000000000000000000000000000000000000000
--- a/src/views/ManageChallengeView.vue
+++ /dev/null
@@ -1,263 +0,0 @@
-<script lang="ts" setup>
-import { useRouter } from 'vue-router'
-import { computed, onMounted, ref, watch } from 'vue'
-import ProgressBar from '@/components/ProgressBar.vue'
-import authInterceptor from '@/services/authInterceptor'
-import type { Challenge } from '@/types/challenge'
-
-const router = useRouter()
-
-const oneWeekFromNow = new Date()
-oneWeekFromNow.setDate(oneWeekFromNow.getDate() + 7)
-const minDate = oneWeekFromNow.toISOString().slice(0, 16)
-
-const thirtyDaysFromNow = new Date()
-thirtyDaysFromNow.setDate(thirtyDaysFromNow.getDate() + 30)
-const maxDate = thirtyDaysFromNow.toISOString().slice(0, 16)
-
-const challengeInstance = ref<Challenge>({
-    title: '',
-    perPurchase: 20,
-    saved: 0,
-    target: 100,
-    description: '',
-    due: minDate + ':00.000Z',
-    type: ''
-})
-
-const isAmountSaved = ref(false)
-const timesSaved = ref(challengeInstance.value.saved / challengeInstance.value.perPurchase)
-
-watch(
-    () => timesSaved.value,
-    (newVal) => {
-        challengeInstance.value.saved = newVal * challengeInstance.value.perPurchase
-        challengeInstance.value.saved = parseFloat(challengeInstance.value.saved.toFixed(2))
-    }
-)
-
-watch(
-    () => challengeInstance.value.saved,
-    (newVal) => {
-        challengeInstance.value.saved = Math.max(
-            0,
-            Math.min(challengeInstance.value.target, newVal)
-        )
-        challengeInstance.value.saved = parseFloat(challengeInstance.value.saved.toFixed(2))
-        timesSaved.value = challengeInstance.value.saved / challengeInstance.value.perPurchase
-        timesSaved.value = parseFloat(timesSaved.value.toFixed(2))
-    }
-)
-
-watch(
-    () => challengeInstance.value.perPurchase,
-    (newVal) => {
-        challengeInstance.value.perPurchase = Math.max(
-            1,
-            Math.min(challengeInstance.value.target, newVal)
-        )
-        challengeInstance.value.perPurchase = parseFloat(
-            challengeInstance.value.perPurchase.toFixed(2)
-        )
-        timesSaved.value = challengeInstance.value.saved / challengeInstance.value.perPurchase
-        timesSaved.value = parseFloat(timesSaved.value.toFixed(2))
-    }
-)
-
-watch(
-    () => challengeInstance.value.target,
-    (newVal) => {
-        challengeInstance.value.target = Math.max(
-            Math.max(challengeInstance.value.saved, 1),
-            newVal
-        )
-    }
-)
-
-const selectedDate = ref(minDate)
-watch(
-    () => selectedDate.value,
-    (newVal) => {
-        if (newVal) {
-            selectedDate.value = newVal < minDate ? minDate : newVal
-            challengeInstance.value.due = selectedDate.value + ':00.000Z'
-        }
-    }
-)
-
-const isEdit = computed(() => router.currentRoute.value.name === 'edit-challenge')
-const pageTitle = computed(() => (isEdit.value ? 'Rediger utfordring' : 'Ny utfordring'))
-const submitButton = computed(() => (isEdit.value ? 'Oppdater' : 'Opprett'))
-const completion = computed(
-    () => (challengeInstance.value.saved / challengeInstance.value.target) * 100
-)
-
-const isInputValid = computed(() => {
-    return (
-        challengeInstance.value.title.length > 0 &&
-        challengeInstance.value.title.length <= 20 &&
-        challengeInstance.value.description.length <= 280 &&
-        challengeInstance.value.target > 0 &&
-        challengeInstance.value.due !== ''
-    )
-})
-
-const submitAction = () => {
-    if (!isInputValid.value) {
-        return () => alert('Fyll ut alle feltene')
-    }
-
-    if (isEdit.value) {
-        updateChallenge()
-    } else {
-        createChallenge()
-    }
-}
-
-onMounted(async () => {
-    if (isEdit.value) {
-        const challengeId = router.currentRoute.value.params.id
-        if (!challengeId) return router.push({ name: 'challenges' })
-
-        await authInterceptor(`/challenges/${challengeId}`)
-            .then((response) => {
-                if (response.data.completedOn) {
-                    router.push({ name: 'challenges' })
-                }
-
-                challengeInstance.value = response.data
-                selectedDate.value = response.data.due.slice(0, 16)
-            })
-            .catch((error) => {
-                console.error(error)
-                router.push({ name: 'challenges' })
-            })
-    }
-})
-
-const createChallenge = () => {
-    authInterceptor
-        .post('/challenges', challengeInstance.value, {})
-        .then(() => {
-            return router.push({ name: 'challenges' })
-        })
-        .catch((error) => {
-            console.error(error)
-        })
-}
-
-const updateChallenge = () => {
-    authInterceptor
-        .put(`/challenges/${challengeInstance.value.id}`, challengeInstance.value)
-        .then(() => {
-            router.push({ name: 'challenges' })
-        })
-        .catch((error) => {
-            console.error(error)
-        })
-}
-</script>
-
-<template>
-    <div class="flex flex-col justify-center items-center">
-        <h1 class="font-bold" v-text="pageTitle" />
-        <div class="flex flex-col gap-5 items-center justify-center">
-            <div class="flex flex-col">
-                <p class="mx-4">Tittel*</p>
-                <input
-                    v-model="challengeInstance.title"
-                    placeholder="Skriv en tittel"
-                    type="text"
-                />
-            </div>
-
-            <div class="flex flex-col">
-                <p class="mx-4">Type</p>
-                <input v-model="challengeInstance.type" placeholder="Skriv en type" type="text" />
-            </div>
-
-            <div class="flex flex-col">
-                <p class="mx-4">Beskrivelse</p>
-                <textarea
-                    v-model="challengeInstance.description"
-                    class="w-80 h-20 no-rezise"
-                    placeholder="Beskriv sparemålet"
-                />
-            </div>
-
-            <div class="flex flex-col sm:flex-row gap-3">
-                <div class="flex flex-col">
-                    <p class="mx-4">Pris per sparing</p>
-                    <input
-                        v-model="challengeInstance.perPurchase"
-                        class="w-40 text-right"
-                        placeholder="Kr spart per sparing"
-                        type="number"
-                    />
-                </div>
-
-                <div class="flex flex-col">
-                    <div class="flex flex-row justify-between mx-4">
-                        <p>{{ isAmountSaved ? 'Kroner spart' : 'Antall sparinger' }}</p>
-                        <button class="p-0 bg-transparent" @click="isAmountSaved = !isAmountSaved">
-                            🔄️
-                        </button>
-                    </div>
-                    <input
-                        v-if="isAmountSaved"
-                        v-model="challengeInstance.saved"
-                        class="w-40 text-right"
-                        min="0"
-                        placeholder="Sparebeløp"
-                        type="number"
-                    />
-                    <input
-                        v-else
-                        v-model="timesSaved"
-                        class="w-40 text-right"
-                        placeholder="Kr spart per sparing"
-                        type="number"
-                    />
-                </div>
-
-                <div class="flex flex-col">
-                    <p class="mx-4">Av målbeløp...*</p>
-                    <input
-                        v-model="challengeInstance.target"
-                        class="w-40 text-right"
-                        placeholder="Målbeløp"
-                        type="number"
-                    />
-                </div>
-            </div>
-            <ProgressBar :completion="completion" />
-
-            <div class="flex flex-col">
-                <p class="mx-4">Forfallsdato*</p>
-                <input
-                    v-model="selectedDate"
-                    :max="maxDate"
-                    :min="minDate"
-                    placeholder="Forfallsdato"
-                    type="datetime-local"
-                />
-            </div>
-
-            <div class="flex flex-row justify-between w-full">
-                <button :disabled="!isInputValid" @click="submitAction" v-text="submitButton" />
-
-                <button
-                    class="bg-button-other"
-                    @click="router.push({ name: 'challenges' })"
-                    v-text="'Avbryt'"
-                />
-            </div>
-        </div>
-    </div>
-</template>
-
-<style scoped>
-.no-rezise {
-    resize: none;
-}
-</style>
diff --git a/src/views/ManageGoalView.vue b/src/views/ManageGoalView.vue
deleted file mode 100644
index a3a246c4497701c183f38a3cf9b953a461b895c2..0000000000000000000000000000000000000000
--- a/src/views/ManageGoalView.vue
+++ /dev/null
@@ -1,196 +0,0 @@
-<script lang="ts" setup>
-import { useRouter } from 'vue-router'
-import { computed, onMounted, ref, watch } from 'vue'
-import type { Goal } from '@/types/goal'
-import ProgressBar from '@/components/ProgressBar.vue'
-import authInterceptor from '@/services/authInterceptor'
-
-const router = useRouter()
-
-const selectedDate = ref<string>('')
-const minDate = new Date(new Date().setDate(new Date().getDate() + 1)).toISOString().slice(0, 16)
-
-const goalInstance = ref<Goal>({
-    title: '',
-    saved: 0,
-    target: 100,
-    description: '',
-    due: ''
-})
-
-watch(
-    () => goalInstance.value.saved,
-    (newVal) => {
-        goalInstance.value.saved = Math.max(0, Math.min(goalInstance.value.target, newVal))
-    }
-)
-
-watch(
-    () => goalInstance.value.target,
-    (newVal) => {
-        goalInstance.value.target = Math.max(Math.max(goalInstance.value.saved, 1), newVal)
-    }
-)
-
-watch(
-    () => selectedDate.value,
-    (newVal) => {
-        if (newVal < minDate) selectedDate.value = minDate
-        goalInstance.value.due = newVal + ':00.000Z'
-    }
-)
-
-const isEdit = computed(() => router.currentRoute.value.name === 'edit-goal')
-const pageTitle = computed(() => (isEdit.value ? 'Rediger sparemål' : 'Nytt sparemål'))
-const submitButton = computed(() => (isEdit.value ? 'Oppdater' : 'Opprett'))
-const completion = computed(() => (goalInstance.value.saved / goalInstance.value.target) * 100)
-
-const isInputValid = computed(() => {
-    return (
-        goalInstance.value.title.length > 0 &&
-        goalInstance.value.title.length <= 20 &&
-        goalInstance.value.description.length <= 280 &&
-        goalInstance.value.target > 0 &&
-        goalInstance.value.due !== ''
-    )
-})
-
-const submitAction = () => {
-    if (!isInputValid.value) {
-        return () => alert('Fyll ut alle feltene')
-    }
-
-    if (isEdit.value) {
-        updateGoal()
-    } else {
-        createGoal()
-    }
-}
-
-onMounted(async () => {
-    if (isEdit.value) {
-        const goalId = router.currentRoute.value.params.id
-        if (!goalId) return router.push({ name: 'goals' })
-
-        await authInterceptor(`/goals/${goalId}`)
-            .then((response) => {
-                goalInstance.value = response.data
-                selectedDate.value = response.data.due.slice(0, 16)
-            })
-            .catch((error) => {
-                console.error(error)
-                router.push({ name: 'goals' })
-            })
-    }
-})
-
-const createGoal = () => {
-    authInterceptor
-        .post('/goals', goalInstance.value, {})
-        .then(() => {
-            return router.push({ name: 'goals' })
-        })
-        .catch((error) => {
-            console.error(error)
-        })
-}
-
-const updateGoal = () => {
-    authInterceptor
-        .put(`/goals/${goalInstance.value.id}`, goalInstance.value)
-        .then(() => {
-            router.back()
-        })
-        .catch((error) => {
-            console.error(error)
-        })
-}
-
-const deleteGoal = () => {
-    authInterceptor
-        .delete(`/goals/${goalInstance.value.id}`)
-        .then(() => {
-            router.push({ name: 'goals' })
-        })
-        .catch((error) => {
-            console.error(error)
-        })
-}
-</script>
-
-<template>
-    <div class="flex flex-col justify-center items-center">
-        <h1 class="font-bold" v-text="pageTitle" />
-        <div class="flex flex-col gap-5 items-center justify-center">
-            <div class="flex flex-col">
-                <p class="mx-4">Tittel*</p>
-                <input v-model="goalInstance.title" placeholder="Skriv en tittel" type="text" />
-            </div>
-
-            <div class="flex flex-col">
-                <p class="mx-4">Beskrivelse</p>
-                <textarea
-                    v-model="goalInstance.description"
-                    class="w-80 h-20 no-rezise"
-                    placeholder="Beskriv sparemålet"
-                />
-            </div>
-
-            <div class="flex flex-col sm:flex-row gap-3">
-                <div class="flex flex-col">
-                    <p class="mx-4">Kroner spart...</p>
-                    <input
-                        v-model="goalInstance.saved"
-                        class="w-40 text-right"
-                        min="0"
-                        placeholder="Sparebeløp"
-                        type="number"
-                    />
-                </div>
-
-                <div class="flex flex-col">
-                    <p class="mx-4">Av målbeløp...*</p>
-                    <input
-                        v-model="goalInstance.target"
-                        class="w-40 text-right"
-                        placeholder="Målbeløp"
-                        type="number"
-                    />
-                </div>
-            </div>
-            <ProgressBar :completion="completion" />
-
-            <div class="flex flex-col">
-                <p class="mx-4">Forfallsdato*</p>
-                <input
-                    :min="minDate"
-                    v-model="selectedDate"
-                    placeholder="Forfallsdato"
-                    type="datetime-local"
-                />
-            </div>
-
-            <div class="flex flex-row justify-between w-full">
-                <button :disabled="!isInputValid" @click="submitAction" v-text="submitButton" />
-                <button
-                    v-if="isEdit"
-                    class="ml-2 bg-button-danger"
-                    @click="deleteGoal"
-                    v-text="'Slett'"
-                />
-                <button
-                    v-else
-                    class="ml-2 bg-button-other"
-                    @click="router.push({ name: 'goals' })"
-                    v-text="'Avbryt'"
-                />
-            </div>
-        </div>
-    </div>
-</template>
-
-<style scoped>
-.no-rezise {
-    resize: none;
-}
-</style>
diff --git a/src/views/NotFoundView.vue b/src/views/NotFoundView.vue
deleted file mode 100644
index 12372705ccd7b4f6f5f71e15f61bbeef5765f3e9..0000000000000000000000000000000000000000
--- a/src/views/NotFoundView.vue
+++ /dev/null
@@ -1,8 +0,0 @@
-<script lang="ts" setup></script>
-
-<template>
-    <h1>404 - Siden finnes ikke</h1>
-    <p>Denne siden finnes ikke. GÃ¥ tilbake til <RouterLink to="/">hjem</RouterLink>.</p>
-</template>
-
-<style scoped></style>
diff --git a/src/views/ProfileView.vue b/src/views/ProfileView.vue
deleted file mode 100644
index 19fa96330c311c4113831e724fb271284250308a..0000000000000000000000000000000000000000
--- a/src/views/ProfileView.vue
+++ /dev/null
@@ -1,134 +0,0 @@
-<script lang="ts" setup>
-import authInterceptor from '@/services/authInterceptor'
-import { computed, onMounted, ref } from 'vue'
-import type { Profile } from '@/types/profile'
-import CardTemplate from '@/views/CardTemplate.vue'
-import InteractiveSpare from '@/components/InteractiveSpare.vue'
-import type { Challenge } from '@/types/challenge'
-import type { Goal } from '@/types/goal'
-import CardGoal from '@/components/CardGoal.vue'
-import router from '@/router'
-
-const profile = ref<Profile>()
-const completedGoals = ref<Goal[]>([])
-const completedChallenges = ref<Challenge[]>([])
-const isModalOpen = ref(false)
-
-onMounted(async () => {
-    await authInterceptor('/profile')
-        .then((response) => {
-            profile.value = response.data
-            console.log(profile.value)
-        })
-        .catch((error) => {
-            return console.log(error)
-        })
-
-    await authInterceptor(`/goals/completed?page=0&size=3`)
-        .then((response) => {
-            completedGoals.value = response.data.content
-        })
-        .catch((error) => {
-            return console.log(error)
-        })
-
-    await authInterceptor('/challenges/completed?page=0&size=3')
-        .then((response) => {
-            completedChallenges.value = response.data.content
-        })
-        .catch((error) => {
-            return console.log(error)
-        })
-})
-
-const welcome = computed(() => {
-    return [`Velkommen, ${profile.value?.firstName} ${profile.value?.lastName} !`]
-})
-
-const openInteractiveSpare = () => {
-    isModalOpen.value = true
-}
-</script>
-
-<template>
-    <div class="w-full flex px-10 justify-center">
-        <div class="flex flex-row flex-wrap justify-center w-full max-w-screen-xl gap-20">
-            <div class="flex flex-col max-w-96 w-full gap-5">
-                <h1>Profile</h1>
-                <div class="flex flex-row gap-5">
-                    <div class="w-32 h-32 border-black border-2 rounded-full shrink-0" />
-                    <div class="w-full flex flex-col justify-between">
-                        <h3 class="font-thin my-0">{{ profile?.username }}</h3>
-                        <h3 class="font-thin my-0">
-                            {{ profile?.firstName + ' ' + profile?.lastName }}
-                        </h3>
-                        <h3 class="font-thin my-0">{{ profile?.email }}</h3>
-                    </div>
-                </div>
-
-                <h3 class="font-bold" v-text="'Du har spart ' + '< totalSaved >' + 'kr'" />
-
-                <CardTemplate>
-                    <div class="bg-red-300">
-                        <p class="font-bold mx-3" v-text="'Brukskonto'" />
-                    </div>
-                    <p
-                        class="mx-3"
-                        v-text="profile?.spendingAccount.accNumber || 'Ingen brukskonto oppkoblet'"
-                    />
-                </CardTemplate>
-
-                <CardTemplate>
-                    <div class="bg-red-300">
-                        <p class="font-bold mx-3" v-text="'Sparekonto'" />
-                    </div>
-                    <p
-                        class="mx-3"
-                        v-text="profile?.savingAccount.accNumber || 'Ingen sparekonto oppkoblet'"
-                    />
-                </CardTemplate>
-
-                <button @click="router.push({ name: 'edit-profile' })" v-text="'Rediger bruker'" />
-            </div>
-
-            <div class="flex flex-col">
-                <InteractiveSpare
-                    :png-size="10"
-                    :speech="welcome"
-                    direction="left"
-                    :isModalOpen="isModalOpen"
-                />
-                <div class="flex items-center">
-                    <a @click="openInteractiveSpare" class="hover:bg-transparent z-20">
-                        <img
-                            alt="Spare"
-                            class="scale-x-[-1] md:h-5/6 md:w-5/6 w-2/3 h-2/3 cursor-pointer ml-14 md:ml-10"
-                            src="@/assets/spare.png"
-                        />
-                    </a>
-                </div>
-                <div class="flex flex-row justify-between mx-4">
-                    <p class="font-bold">Fullførte sparemål</p>
-                    <a class="hover:p-0 cursor-pointer" v-text="'Se alle'" />
-                </div>
-                <CardTemplate class="p-4 flex flex-row flex-wrap justify-center gap-2 mb-4 mt-2">
-                    <CardGoal v-for="goal in completedGoals" :key="goal.id" :goal-instance="goal" />
-                </CardTemplate>
-
-                <div class="flex flex-row justify-between mx-4">
-                    <p class="font-bold">Fullførte utfordringer</p>
-                    <a class="hover:p-0 cursor-pointer" v-text="'Se alle'" />
-                </div>
-                <CardTemplate class="p-4 flex flex-row flex-wrap justify-center gap-2 mb-4 mt-2">
-                    <CardGoal
-                        v-for="challenge in completedChallenges"
-                        :key="challenge.id"
-                        :goal-instance="challenge"
-                    />
-                </CardTemplate>
-            </div>
-        </div>
-    </div>
-</template>
-
-<style scoped></style>
diff --git a/src/views/RegisterLoginView.vue b/src/views/RegisterLoginView.vue
deleted file mode 100644
index 738002afa9461e9df0acbd0f592b327303ec33ba..0000000000000000000000000000000000000000
--- a/src/views/RegisterLoginView.vue
+++ /dev/null
@@ -1,56 +0,0 @@
-<script setup lang="ts">
-import FormLogin from '@/components/FormLogin.vue'
-import FormRegister from '@/components/FormRegister.vue'
-import { onMounted, ref } from 'vue'
-import { useRouter } from 'vue-router'
-
-const router = useRouter()
-
-const isLogin = ref<boolean>(true)
-
-onMounted(() => {
-    isLogin.value = router.currentRoute.value.path === '/logginn'
-})
-</script>
-
-<template>
-    <div class="flex flex-col items-center gap-5 justify-center md:flex-row h-screen">
-        <div class="flex items-center justify-center md:w-2/3">
-            <img
-                src="@/assets/spare_og_sti.png"
-                alt="Spare og sti logo"
-                class="w-5/6 ml-10 md:mb-64"
-            />
-        </div>
-        <div class="flex flex-col md:mr-10 md:mt-20 md:w-1/3 h-screen justify-start">
-            <div class="flex flex-row gap-5 justify-center">
-                <h3
-                    :class="{ selected: isLogin }"
-                    class="cursor-pointer"
-                    tabindex="0"
-                    @click="isLogin = true"
-                    @keydown.enter.prevent="isLogin = true"
-                >
-                    Logg inn
-                </h3>
-                <h3
-                    :class="{ selected: !isLogin }"
-                    class="cursor-pointer"
-                    tabindex="0"
-                    @click="isLogin = false"
-                    @keydown.enter.prevent="isLogin = false"
-                >
-                    Registrer deg
-                </h3>
-            </div>
-            <FormLogin v-if="isLogin" />
-            <FormRegister v-else />
-        </div>
-    </div>
-</template>
-
-<style scoped>
-.selected {
-    border-bottom: 2px solid black;
-}
-</style>
diff --git a/src/views/ResetPasswordView.vue b/src/views/ResetPasswordView.vue
deleted file mode 100644
index cce6427a6d0dbea6bd91a5dfb1905a439374ca56..0000000000000000000000000000000000000000
--- a/src/views/ResetPasswordView.vue
+++ /dev/null
@@ -1,114 +0,0 @@
-<template>
-    <div>
-        <h1 class="flex flex-col items-center mt-8">Oppdater passord</h1>
-        <p class="flex flex-col items-center mb-16">Skriv inn ditt nye passord 🔐</p>
-        <div class="flex justify-center items-center w-full">
-            <div class="flex flex-col md:w-1/4 w-2/3">
-                <div class="flex flex-row justify-between mx-4">
-                    <p>Nytt passord:</p>
-                    <ToolTip
-                        :message="'Must be at least 8 characters, including at least one number, one lowercase letter, one uppercase letter, one special character (@#$%^&+=!), and no spaces.'"
-                    />
-                </div>
-                <div class="relative">
-                    <input
-                        name="password"
-                        v-model="newPassword"
-                        :type="showPassword ? 'text' : 'password'"
-                        placeholder="Skriv inn passord"
-                        class="w-full"
-                        :class="{ 'bg-green-200': isPasswordValid }"
-                    />
-                    <button
-                        class="absolute right-0 top-1 bg-transparent hover:bg-transparent"
-                        @click="toggleShowPassword"
-                    >
-                        {{ showPassword ? '🔓' : '🔒' }}
-                    </button>
-                </div>
-                <input
-                    v-model="confirm"
-                    :class="{ 'bg-green-200': newPassword == confirm && '' !== confirm.valueOf() }"
-                    class="mt-2 w-full"
-                    name="confirm"
-                    placeholder="Bekreft passord"
-                    type="password"
-                />
-                <div class="flex justify-center mt-10">
-                    <button
-                        :disabled="!canResetPassword"
-                        @click="resetPassword"
-                        class="p-2 w-2/3 md:w-5/6 disabled:opacity-50"
-                    >
-                        Oppdater passord
-                    </button>
-                </div>
-            </div>
-        </div>
-        <ModalComponent
-            :title="'Passordet er oppdatert ✨'"
-            :message="'Passordet ditt er nå oppdatert. Du kan nå logge inn med ditt nye passord.'"
-            :is-modal-open="isModalOpen"
-            @close="isModalOpen = false"
-        >
-            <template v-slot:buttons>
-                <button
-                    @click="goToLogin"
-                    class="active-button font-bold py-2 px-4 w-1/2 hover:bg-[#f7da7c] border-2 border-[#f7da7c] disabled:border-transparent"
-                >
-                    Logg inn
-                </button>
-            </template>
-        </ModalComponent>
-    </div>
-</template>
-
-<script setup lang="ts">
-import { computed, ref } from 'vue'
-import { useRoute, useRouter } from 'vue-router'
-import axios from 'axios'
-import ToolTip from '@/components/ToolTip.vue'
-import ModalComponent from '@/components/ModalComponent.vue'
-
-const route = useRoute()
-const router = useRouter()
-
-const resetID = ref(route.query.resetID)
-const userID = ref(route.query.userID)
-const newPassword = ref<string>('')
-const confirm = ref<string>('')
-const showPassword = ref<boolean>(false)
-const isModalOpen = ref<boolean>(false)
-
-const passwordRegex = /^(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*[@#$%^&+=!])(?=\S+$).{8,}$/
-
-const isPasswordValid = computed(() => passwordRegex.test(newPassword.value))
-
-const canResetPassword = computed(() => {
-    return isPasswordValid.value && newPassword.value === confirm.value && confirm.value !== ''
-})
-
-const resetPassword = async () => {
-    isModalOpen.value = true
-
-    try {
-        await axios.post('http://localhost:8080/forgotPassword/resetPassword', {
-            resetID: resetID.value,
-            userID: userID.value,
-            newPassword: newPassword.value
-        })
-    } catch (error) {
-        const err = error as Error
-        console.error(err.message)
-    }
-}
-
-const toggleShowPassword = () => {
-    showPassword.value = !showPassword.value
-}
-
-const goToLogin = () => {
-    isModalOpen.value = false
-    router.push('/logginn')
-}
-</script>
diff --git a/src/views/StartView.vue b/src/views/StartView.vue
deleted file mode 100644
index 3f9842c83b91204842f1cf825d8352cdd2ad6f56..0000000000000000000000000000000000000000
--- a/src/views/StartView.vue
+++ /dev/null
@@ -1,83 +0,0 @@
-<template>
-    <div class="background-container">
-        <div class="overflow-hidden md:relative absolute max-md:-left-2/3 right-0 left-0">
-            <img
-                src="@/assets/start_page/sti.png"
-                alt="Background"
-                class="min-w-[1420px] h-auto overflow-hidden"
-            />
-        </div>
-        <div class="flex flex-col items-center pt-40 absolute top-0 left-0 right-0 z-10">
-            <img src="@/assets/spare.png" alt="Spare" class="md:w-1/6 w-1/3 h-auto" />
-            <img
-                src="@/assets/spareSti.png"
-                alt="Sparesti"
-                class="md:w-5/12 w-10/12 h-auto md:mt-4 mt-20"
-            />
-            <p class="mt-2 lg:text-2xl text-lg font-bold">GJØR SPARING TIL EN LEK!</p>
-        </div>
-
-        <div
-            class="flex flex-col items-end mr-3 justify-center space-y-4 z-20 absolute inset-0 -top-3/4 md:left-3/4 left-1/4 md:w-1/6 md:right-1/3 md:mt-44"
-        >
-            <button
-                class="md:py-3 md:px-0 md:w-3/4 py-2 px-12 w-1/2 border border-[#95E35D] shadow-lg rounded-lg transition-all duration-500 bg-[#95E35D] hover:bg-white text-sm md:text-base"
-                @click="goToRegister"
-            >
-                Start her
-            </button>
-            <button
-                class="md:py-3 md:px-0 md:w-3/4 py-2 px-12 w-1/2 border border-[#95E35D] shadow-lg rounded-lg transition-all duration-500 bg-white hover:bg-[#95E35D] text-sm md:text-base"
-                @click="goToLogin"
-            >
-                Logg inn
-            </button>
-        </div>
-
-        <div class="invisible md:visible absolute -bottom-80 right-0 mr-4 pr-10 w-1/4">
-            <h2>Kom igang med målene dine! 🚀</h2>
-            <p>Sett deg et sparemål og utfordre deg selv til å spare mer. 🎯</p>
-        </div>
-
-        <div class="invisible md:visible absolute -bottom-[1450px] right-0 mr-4 pr-10 w-1/4">
-            <h2>Gi slipp på dårlige vaner! 🍻</h2>
-            <p>Sett deg et spareutfordringer, bra for lommeboka og helsa! 🦾</p>
-        </div>
-
-        <div
-            class="absolute md:-bottom-[600px] -bottom-[500px] md:left-10 left-10 md:ml-2 md:pl-10 md:w-1/3 w-5/6"
-        >
-            <h2>Spar til din neste ferie! 🏖️☀️️</h2>
-            <p>Ferie er viktig for å lade batteriene 🔋. Spar til din neste ferie og nyt livet!</p>
-            <div
-                class="absolute top-50 left-10 right-10 h-24 overflow-hidden bg-[url('@/assets/start_page/skyer.png')] bg-repeat-x bg-center animate-clouds"
-            ></div>
-            <div
-                class="absolute top-80 left-10 right-10 h-24 overflow-hidden bg-[url('@/assets/start_page/strand.png')] bg-repeat-x bg-center animate-beach"
-            ></div>
-            <div
-                class="absolute -bottom-52 left-10 right-10 h-24 bg-[url('@/assets/start_page/fly.png')] bg-contain bg-no-repeat bg-center z-10"
-            ></div>
-            <div
-                class="flame1 absolute -bottom-36 md:left-60 left-44 h-2 w-8 rounded-lg bg-blue-100 animate-flame z-9"
-            ></div>
-            <div
-                class="flame2 absolute -bottom-48 md:left-[258px] left-48 h-2 w-10 rounded-lg bg-blue-100 animate-flame z-9"
-            ></div>
-        </div>
-    </div>
-</template>
-
-<script setup lang="ts">
-import { useRouter } from 'vue-router'
-
-const router = useRouter()
-
-const goToLogin = () => {
-    router.push('/logginn')
-}
-
-const goToRegister = () => {
-    router.push('/registrer')
-}
-</script>
diff --git a/src/views/UserChallengesView.vue b/src/views/UserChallengesView.vue
deleted file mode 100644
index fa5f8047a1a797065cc638881842ac1d6fecae23..0000000000000000000000000000000000000000
--- a/src/views/UserChallengesView.vue
+++ /dev/null
@@ -1,88 +0,0 @@
-<script lang="ts" setup>
-import { useRouter } from 'vue-router'
-import { onMounted, ref } from 'vue'
-import authInterceptor from '@/services/authInterceptor'
-import type { Challenge } from '@/types/challenge'
-import CardChallenge from '@/components/CardChallenge.vue'
-import PageControl from '@/components/PageControl.vue'
-
-const router = useRouter()
-
-const currentPageActive = ref(0)
-const totalPagesActive = ref(1)
-const currentPageCompleted = ref(0)
-const totalPagesCompleted = ref(1)
-
-const activeChallenges = ref<Challenge[]>([])
-const completedChallenges = ref<Challenge[]>([])
-
-const getActiveChallenges = async (newPage: number) => {
-    await authInterceptor(`/challenges/active?page=${newPage}&size=5`)
-        .then((response) => {
-            currentPageActive.value = response.data.number
-            totalPagesActive.value = response.data.totalPages
-            activeChallenges.value = response.data.content
-        })
-        .catch((error) => {
-            console.error(error)
-        })
-}
-
-const getCompletedChallenges = async (newPage: number) => {
-    await authInterceptor(`/challenges/completed?page=${newPage}&size=5`)
-        .then((response) => {
-            currentPageCompleted.value = response.data.number
-            totalPagesCompleted.value = response.data.totalPages
-            completedChallenges.value = response.data.content
-        })
-        .catch((error) => {
-            console.error(error)
-        })
-}
-
-onMounted(async () => {
-    await getActiveChallenges(currentPageActive.value)
-    await getCompletedChallenges(currentPageActive.value)
-})
-</script>
-
-<template>
-    <h1 class="font-bold text-center">Dine utfordringer</h1>
-    <div class="flex flex-col gap-5 items-center">
-        <div class="flex flex-row gap-5">
-            <button @click="router.push({ name: 'new-challenge' })">
-                Opprett en ny utfordring
-            </button>
-        </div>
-
-        <h2 class="font-bold">Aktive utfordringer</h2>
-        <div class="flex flex-row justify-center gap-10 flex-wrap">
-            <CardChallenge
-                v-for="challenge in activeChallenges"
-                :key="challenge.id"
-                :challenge-instance="challenge"
-            />
-        </div>
-        <PageControl
-            :currentPage="currentPageActive"
-            :on-page-change="getActiveChallenges"
-            :totalPages="totalPagesActive"
-        />
-
-        <h2 class="font-bold">Fullførte utfordringer</h2>
-        <div class="flex flex-row justify-center gap-10 flex-wrap">
-            <CardChallenge
-                v-for="challenge in completedChallenges"
-                :key="challenge.id"
-                :challenge-instance="challenge"
-            />
-        </div>
-        <PageControl
-            :currentPage="currentPageCompleted"
-            :on-page-change="getCompletedChallenges"
-            :totalPages="totalPagesCompleted"
-        />
-    </div>
-</template>
-
-<style scoped></style>
diff --git a/src/views/UserGoalsView.vue b/src/views/UserGoalsView.vue
deleted file mode 100644
index 80d893de8e834265f2e81645d5226223fecf60d1..0000000000000000000000000000000000000000
--- a/src/views/UserGoalsView.vue
+++ /dev/null
@@ -1,101 +0,0 @@
-<script lang="ts" setup>
-import CardGoal from '@/components/CardGoal.vue'
-
-import { useRouter } from 'vue-router'
-import { onMounted, ref } from 'vue'
-import authInterceptor from '@/services/authInterceptor'
-import type { Goal } from '@/types/goal'
-import draggable from 'vuedraggable'
-import PageControl from '@/components/PageControl.vue'
-
-const router = useRouter()
-
-const currentPage = ref(0)
-const totalPages = ref(1)
-
-const activeGoals = ref<Goal[]>([])
-const completedGoals = ref<Goal[]>([])
-
-const isDraggable = ref(false)
-
-onMounted(async () => {
-    await authInterceptor('/goals/active')
-        .then((response) => {
-            activeGoals.value = response.data
-            activeGoals.value.sort((a, b) => (a.priority || 0) - (b.priority || 0))
-        })
-        .catch((error) => {
-            console.error(error)
-        })
-
-    await updatePage(0)
-})
-
-const updatePage = async (page: number) => {
-    await authInterceptor(`/goals/completed?page=${page}&size=5`)
-        .then((response) => {
-            currentPage.value = response.data.number
-            totalPages.value = response.data.totalPages
-            completedGoals.value = response.data.content
-        })
-        .catch((error) => {
-            console.error(error)
-        })
-}
-
-const changeOrder = async () => {
-    if (isDraggable.value) {
-        const priorities = activeGoals.value.map((goal) => goal.id)
-        await authInterceptor.put('/goals', priorities).catch((error) => {
-            console.error(error)
-        })
-        isDraggable.value = false
-        await updatePage(currentPage.value)
-    } else {
-        isDraggable.value = true
-    }
-}
-</script>
-
-<template>
-    <div class="flex flex-col gap-5 items-center">
-        <h1 class="font-bold m-0">Dine sparemål</h1>
-        <button @click="router.push({ name: 'new-goal' })">Opprett et nytt sparemål</button>
-        <h2 class="font-thin m-0">Aktive sparemål</h2>
-        <p v-if="activeGoals.length === 0">Du har ingen aktive sparemål</p>
-        <draggable
-            v-else
-            v-model="activeGoals"
-            class="flex flex-row flex-wrap justify-center gap-10"
-            item-key="id"
-            :disabled="!isDraggable"
-        >
-            <template #item="{ element, index }">
-                <CardGoal
-                    :key="index"
-                    :class="[
-                        { 'cursor-move shadow-xl -translate-y-2 duration-300': isDraggable },
-                        { 'border-4 border-green-500': index === 0 }
-                    ]"
-                    :goal-instance="element"
-                    :is-clickable="!isDraggable"
-                />
-            </template>
-        </draggable>
-        <button :disabled="activeGoals.length === 0" @click="changeOrder()">
-            {{ isDraggable ? 'Lagre rekkefølge' : 'Endre rekkefølge' }}
-        </button>
-        <h2 class="font-thin m-0">Fullførte sparemål</h2>
-        <p v-if="completedGoals.length === 0">Du har ingen fullførte sparemål</p>
-        <div v-else class="flex flex-row flex-wrap justify-center gap-10">
-            <CardGoal v-for="goal in completedGoals" :key="goal.id" :goal-instance="goal" />
-        </div>
-        <PageControl
-            :current-page="currentPage"
-            :on-page-change="updatePage"
-            :total-pages="totalPages"
-        />
-    </div>
-</template>
-
-<style scoped></style>
diff --git a/src/views/ViewChallengeView.vue b/src/views/ViewChallengeView.vue
deleted file mode 100644
index 71b2a67e67c73f158626efb25d67a80bb0e78edc..0000000000000000000000000000000000000000
--- a/src/views/ViewChallengeView.vue
+++ /dev/null
@@ -1,158 +0,0 @@
-<script lang="ts" setup>
-import { useRouter } from 'vue-router'
-import { computed, onMounted, ref } from 'vue'
-import ProgressBar from '@/components/ProgressBar.vue'
-import authInterceptor from '@/services/authInterceptor'
-import type { Challenge } from '@/types/challenge'
-import InteractiveSpare from '@/components/InteractiveSpare.vue'
-
-const router = useRouter()
-
-const challengeInstance = ref<Challenge>({
-    title: 'Test titel',
-    perPurchase: 20,
-    saved: 0,
-    target: 100,
-    description: 'Dette er en lang textbeskrivelse',
-    due: '2024-01-01T00:00:00.000Z',
-    type: '☕️',
-    completedOn: ''
-})
-
-const timesSaved = computed(
-    () => challengeInstance.value.saved / challengeInstance.value.perPurchase
-)
-const completion = computed(
-    () => (challengeInstance.value.saved / challengeInstance.value.target) * 100
-)
-const isCompleted = computed(() => challengeInstance.value.completedOn != null)
-
-const motivation = ref<string[]>([])
-
-const isModalOpen = ref(false)
-
-const calculateSpeech = () => {
-    if (completion.value === 0) {
-        return motivation.value.push(
-            `Du har ikke spart noe enda. Du har ${challengeInstance.value.target}kr igjen til målet.`
-        )
-    } else if (completion.value < 25) {
-        return motivation.value.push(
-            `Du har spart ${challengeInstance.value.saved}kr av ${challengeInstance.value.target}kr, som er ${timesSaved.value} ganger.`
-        )
-    } else if (completion.value < 75) {
-        return motivation.value.push(
-            `Du er på god vei! Du har spart ${challengeInstance.value.saved}kr av ${challengeInstance.value.target}kr, som er ${timesSaved.value} ganger.`
-        )
-    } else if (completion.value < 100) {
-        return motivation.value.push(
-            `Nesten der! Du har spart ${challengeInstance.value.saved}kr av ${challengeInstance.value.target}kr, som er ${timesSaved.value} ganger.`
-        )
-    } else if (completion.value >= 100) {
-        return motivation.value.push(
-            `Fantastisk! Du har nådd målet ditt! Du har spart ${challengeInstance.value.saved}kr av ${challengeInstance.value.target}kr, som er ${timesSaved.value} ganger.`
-        )
-    }
-}
-
-onMounted(() => {
-    const challengeId = router.currentRoute.value.params.id
-    if (!challengeId) return router.push({ name: 'challenges' })
-
-    authInterceptor(`/challenges/${challengeId}`)
-        .then((response) => {
-            challengeInstance.value = response.data
-            calculateSpeech()
-        })
-        .catch(() => router.push({ name: 'challenges' }))
-})
-
-const completeChallenge = () => {
-    authInterceptor
-        .put(`/challenges/${challengeInstance.value.id}/complete`)
-        .then(() => {
-            router.push({ name: 'challenges' })
-        })
-        .catch((error) => {
-            console.error(error)
-        })
-}
-</script>
-
-<template>
-    <div class="flex flex-row flex-wrap items-center justify-center gap-10">
-        <div class="flex flex-col gap-5 max-w-96">
-            <button
-                class="w-min"
-                @click="router.push({ name: 'challenges', params: { id: challengeInstance.id } })"
-            >
-                Oversikt
-            </button>
-
-            <div
-                class="flex flex-col justify-center border-4 border-black rounded-3xl align-middle p-5 card-shadow overflow-hidden w-full"
-            >
-                <h2 class="my-0">Spareutfordring:</h2>
-                <h2 class="font-light">
-                    {{ challengeInstance.title + ' ' + challengeInstance.type }}
-                </h2>
-                <p class="text-center">
-                    Du har spart {{ timesSaved }} ganger som er {{ challengeInstance.saved }}kr av
-                    {{ challengeInstance.target }}kr
-                </p>
-                <ProgressBar :completion="completion" />
-                <br />
-                <p class="text-wrap break-words">{{ challengeInstance.description }}</p>
-                <br />
-                <p>
-                    Du sparer {{ challengeInstance.perPurchase }}kr hver gang du dropper å bruke
-                    penger på {{ challengeInstance.type }}
-                </p>
-            </div>
-
-            <div class="flex flex-row justify-between w-full">
-                <button
-                    v-if="!isCompleted"
-                    @click="
-                        router.push({
-                            name: 'edit-challenge',
-                            params: { id: challengeInstance.id }
-                        })
-                    "
-                >
-                    Rediger
-                </button>
-
-                <button
-                    v-if="!isCompleted"
-                    @click="completeChallenge"
-                    v-text="'Sett utfordring til ferdig'"
-                />
-
-                <button
-                    class="bg-button-danger hover:bg-button-danger"
-                    @click="
-                        authInterceptor
-                            .delete(`/challenges/${challengeInstance.id}`)
-                            .then(() => router.push({ name: 'challenges' }))
-                            .catch((error) => console.error(error))
-                    "
-                >
-                    Slett
-                </button>
-            </div>
-        </div>
-        <InteractiveSpare
-            :png-size="10"
-            :speech="motivation"
-            direction="left"
-            :isModalOpen="isModalOpen"
-        />
-    </div>
-</template>
-
-<style scoped>
-.card-shadow {
-    box-shadow: 0 10px 20px rgba(0, 0, 0, 0.2);
-}
-</style>
diff --git a/src/views/ViewGoalView.vue b/src/views/ViewGoalView.vue
deleted file mode 100644
index 50ec73bb87ee4c101808f113f552a58e90ca94db..0000000000000000000000000000000000000000
--- a/src/views/ViewGoalView.vue
+++ /dev/null
@@ -1,156 +0,0 @@
-<script lang="ts" setup>
-import { useRouter } from 'vue-router'
-import { computed, onMounted, ref } from 'vue'
-import ProgressBar from '@/components/ProgressBar.vue'
-import authInterceptor from '@/services/authInterceptor'
-import type { Goal } from '@/types/goal'
-import InteractiveSpare from '@/components/InteractiveSpare.vue'
-
-const router = useRouter()
-
-const goalInstance = ref<Goal>({
-    title: 'Test tittel',
-    saved: 0,
-    target: 100,
-    description: 'Dette er en lang textbeskrivelse',
-    due: ''
-})
-
-const completion = computed(() => (goalInstance.value.saved / goalInstance.value.target) * 100)
-const isCompleted = computed(() => goalInstance.value.completedOn != null)
-
-const motivation = ref<string[]>([])
-const isModalOpen = ref(false)
-
-const openInteractiveSpare = () => {
-    isModalOpen.value = true
-}
-
-const calculateSpeech = () => {
-    if (completion.value === 0) {
-        return motivation.value.push(
-            `Du har ikke spart noe enda. Du har ${goalInstance.value.target}kr igjen til målet.`
-        )
-    } else if (completion.value < 25) {
-        return motivation.value.push(
-            `Du har spart ${goalInstance.value.saved}kr av ${goalInstance.value.target}kr.`
-        )
-    } else if (completion.value < 75) {
-        return motivation.value.push(
-            `Du er på god vei! Du har spart ${goalInstance.value.saved}kr av ${goalInstance.value.target}kr.`
-        )
-    } else if (completion.value < 100) {
-        return motivation.value.push(
-            `Nesten der! Du har spart ${goalInstance.value.saved}kr av ${goalInstance.value.target}kr.`
-        )
-    } else if (completion.value >= 100) {
-        return motivation.value.push(
-            `Fantastisk! Du har nådd målet ditt! Du har spart ${goalInstance.value.saved}kr av ${goalInstance.value.target}kr.`
-        )
-    }
-}
-
-onMounted(() => {
-    const goalId = router.currentRoute.value.params.id
-    if (!goalId) return router.push({ name: 'goals' })
-
-    authInterceptor(`/goals/${goalId}`)
-        .then((response) => {
-            goalInstance.value = response.data
-            calculateSpeech()
-        })
-        .catch(() => router.push({ name: 'goals' }))
-})
-
-const completeGoal = () => {
-    authInterceptor
-        .put(`/goals/${goalInstance.value.id}/complete`)
-        .then(() => {
-            router.push({ name: 'goals' })
-        })
-        .catch((error) => {
-            console.error(error)
-        })
-}
-</script>
-
-<template>
-    <div class="flex flex-row flex-wrap items-center justify-center gap-10">
-        <div class="flex flex-col gap-5 max-w-96">
-            <button
-                class="w-min"
-                @click="router.push({ name: 'goals', params: { id: goalInstance.id } })"
-            >
-                Oversikt
-            </button>
-
-            <div
-                class="flex flex-col justify-center border-4 border-black rounded-3xl align-middle p-5 card-shadow overflow-hidden w-full"
-            >
-                <h2 class="my-0">Sparemål:</h2>
-                <h2 class="font-light">
-                    {{ goalInstance.title }}
-                </h2>
-                <p class="text-wrap break-words">{{ goalInstance.description }}</p>
-                <br />
-                <p class="text-center">
-                    Du har spart {{ goalInstance.saved }}kr av {{ goalInstance.target }}kr
-                </p>
-                <ProgressBar :completion="completion" />
-            </div>
-
-            <div class="flex flex-row justify-between gap-2 w-full">
-                <button
-                    v-if="!isCompleted"
-                    @click="
-                        router.push({
-                            name: 'edit-goal',
-                            params: { id: goalInstance.id }
-                        })
-                    "
-                >
-                    Rediger
-                </button>
-
-                <button
-                    v-if="!isCompleted"
-                    @click="completeGoal"
-                    v-text="'Marker målet som ferdig'"
-                />
-
-                <button
-                    class="bg-button-danger hover:bg-button-danger"
-                    @click="
-                        authInterceptor
-                            .delete(`/goals/${goalInstance.id}`)
-                            .then(() => router.push({ name: 'goals' }))
-                            .catch((error) => console.error(error))
-                    "
-                >
-                    Slett
-                </button>
-            </div>
-        </div>
-        <div class="flex items-center">
-            <a @click="openInteractiveSpare" class="hover:bg-transparent z-20">
-                <img
-                    alt="Spare"
-                    class="scale-x-[-1] md:h-5/6 md:w-5/6 w-2/3 h-2/3 cursor-pointer ml-14 md:ml-10"
-                    src="@/assets/spare.png"
-                />
-            </a>
-        </div>
-        <InteractiveSpare
-            :png-size="10"
-            :speech="motivation"
-            direction="left"
-            :isModalOpen="isModalOpen"
-        />
-    </div>
-</template>
-
-<style scoped>
-.card-shadow {
-    box-shadow: 0 10px 20px rgba(0, 0, 0, 0.2);
-}
-</style>
diff --git a/tailwind.config.js b/tailwind.config.js
deleted file mode 100644
index 85dfc48accae773f41c89b06e72c48669c4df697..0000000000000000000000000000000000000000
--- a/tailwind.config.js
+++ /dev/null
@@ -1,34 +0,0 @@
-/** @type {import('tailwindcss').Config} */
-export default {
-    content: ['./index.html', './src/**/*.{vue,js,ts,jsx,tsx}'],
-    theme: {
-        extend: {
-            animation: {
-                clouds: 'clouds 20s linear infinite',
-                beach: 'beach 5s linear infinite',
-                flame: 'flame 0.3s linear infinite'
-            },
-            keyframes: {
-                clouds: {
-                    '0%': { backgroundPosition: '0%' },
-                    '100%': { backgroundPosition: '-100%' }
-                },
-                beach: {
-                    '0%': { backgroundPosition: '0%' },
-                    '100%': { backgroundPosition: '-100%' }
-                },
-
-                flame: {
-                    '0%, 100%': { transform: 'translateX(0%)' },
-                    '50%': { transform: 'translateX(50%)' }
-                }
-            },
-            colors: {
-                'button-disabled': 'var(--grey)',
-                'button-danger': 'var(--red)',
-                'button-other': 'var(--accent1)'
-            }
-        }
-    },
-    plugins: []
-}
\ No newline at end of file
diff --git a/tsconfig.app.json b/tsconfig.app.json
deleted file mode 100644
index e14c754d3ae5775d2ab13001e251c1371be912de..0000000000000000000000000000000000000000
--- a/tsconfig.app.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
-  "extends": "@vue/tsconfig/tsconfig.dom.json",
-  "include": ["env.d.ts", "src/**/*", "src/**/*.vue"],
-  "exclude": ["src/**/__tests__/*"],
-  "compilerOptions": {
-    "composite": true,
-    "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
-
-    "baseUrl": ".",
-    "paths": {
-      "@/*": ["./src/*"]
-    }
-  }
-}
diff --git a/tsconfig.json b/tsconfig.json
deleted file mode 100644
index 5304731b8d26326f23e647245010b28216f91dac..0000000000000000000000000000000000000000
--- a/tsconfig.json
+++ /dev/null
@@ -1,17 +0,0 @@
-{
-  "files": [],
-  "references": [
-    {
-      "path": "./tsconfig.node.json"
-    },
-    {
-      "path": "./tsconfig.app.json"
-    },
-    {
-      "path": "./tsconfig.vitest.json"
-    }
-  ],
-  "compilerOptions": {
-    "module": "NodeNext"
-  }
-}
diff --git a/tsconfig.node.json b/tsconfig.node.json
deleted file mode 100644
index f0940630302f8c4b03a6f601a908d6fa0240ad54..0000000000000000000000000000000000000000
--- a/tsconfig.node.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
-  "extends": "@tsconfig/node20/tsconfig.json",
-  "include": [
-    "vite.config.*",
-    "vitest.config.*",
-    "cypress.config.*",
-    "nightwatch.conf.*",
-    "playwright.config.*"
-  ],
-  "compilerOptions": {
-    "composite": true,
-    "noEmit": true,
-    "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
-
-    "module": "ESNext",
-    "moduleResolution": "Bundler",
-    "types": ["node"]
-  }
-}
diff --git a/tsconfig.vitest.json b/tsconfig.vitest.json
deleted file mode 100644
index 571995d11e6acb21020f2570fb6a034609ee654e..0000000000000000000000000000000000000000
--- a/tsconfig.vitest.json
+++ /dev/null
@@ -1,11 +0,0 @@
-{
-  "extends": "./tsconfig.app.json",
-  "exclude": [],
-  "compilerOptions": {
-    "composite": true,
-    "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.vitest.tsbuildinfo",
-
-    "lib": [],
-    "types": ["node", "jsdom"]
-  }
-}
diff --git a/vite.config.ts b/vite.config.ts
deleted file mode 100644
index d48b67e5cc93e47429649f84e1e6671fa2680b93..0000000000000000000000000000000000000000
--- a/vite.config.ts
+++ /dev/null
@@ -1,19 +0,0 @@
-import { fileURLToPath, URL } from 'node:url'
-
-import { defineConfig } from 'vite'
-import vue from '@vitejs/plugin-vue'
-
-// https://vitejs.dev/config/
-export default defineConfig({
-  plugins: [
-    vue(),
-  ],
-  resolve: {
-    alias: {
-      '@': fileURLToPath(new URL('./src', import.meta.url))
-    }
-  },
-  server: {
-    host: '0.0.0.0'
-  }
-})
diff --git a/vitest.config.ts b/vitest.config.ts
deleted file mode 100644
index 4b1c897997739635a6e14248a6448b67b2703c44..0000000000000000000000000000000000000000
--- a/vitest.config.ts
+++ /dev/null
@@ -1,14 +0,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))
-    }
-  })
-)