diff --git a/.env.sample b/.env.sample
new file mode 100644
index 0000000..209ce0b
--- /dev/null
+++ b/.env.sample
@@ -0,0 +1,3 @@
+MSSQL='Server=.database.windows.net;Initial Catalog=;Persist Security Info=False;User ID=session_recommender_app;Password=unEno!h5!&*KP420xds&@P901afb$^M;MultipleActiveResultSets=False;Encrypt=True;Connection Timeout=30;'
+OPENAI.URL='https://.openai.azure.com'
+OPENAI.KEY=''
diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 0000000..8efbe82
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1,13 @@
+# Thanks to: https://rehansaeed.com/gitattributes-best-practices/
+
+# Set default behavior to automatically normalize line endings.
+* text=auto
+
+# Force batch scripts to always use CRLF line endings so that if a repo is accessed
+# in Windows via a file share from Linux, the scripts will work.
+*.{cmd,[cC][mM][dD]} text eol=crlf
+*.{bat,[bB][aA][tT]} text eol=crlf
+
+# Force bash scripts to always use LF line endings so that if a repo is accessed
+# in Unix via a file share from Windows, the scripts will work.
+*.sh text eol=lf
\ No newline at end of file
diff --git a/.gitignore b/.gitignore
index 8a30d25..e21ec49 100644
--- a/.gitignore
+++ b/.gitignore
@@ -396,3 +396,9 @@ FodyWeavers.xsd
 
 # JetBrains Rider
 *.sln.iml
+
+# Custom
+.env
+azuredeploy.parameters.json
+*.zip
+.azure/
diff --git a/.nvmrc b/.nvmrc
new file mode 100644
index 0000000..2edeafb
--- /dev/null
+++ b/.nvmrc
@@ -0,0 +1 @@
+20
\ No newline at end of file
diff --git a/.vscode/extensions.json b/.vscode/extensions.json
new file mode 100644
index 0000000..bb76300
--- /dev/null
+++ b/.vscode/extensions.json
@@ -0,0 +1,6 @@
+{
+  "recommendations": [
+    "ms-azuretools.vscode-azurefunctions",
+    "ms-dotnettools.csharp"
+  ]
+}
\ No newline at end of file
diff --git a/.vscode/launch.json b/.vscode/launch.json
new file mode 100644
index 0000000..a778a15
--- /dev/null
+++ b/.vscode/launch.json
@@ -0,0 +1,25 @@
+{
+  "version": "0.2.0",
+  "configurations": [
+    {
+      "name": "Attach to .NET Functions",
+      "type": "coreclr",
+      "request": "attach",
+      "processId": "${command:azureFunctions.pickProcess}"
+    },
+    {
+      "name": "Run web app",
+      "type": "node",
+      "request": "launch",
+      "cwd": "${workspaceFolder}",
+      "runtimeExecutable": "swa",
+      "runtimeArgs": ["start"],
+      "presentation": {
+        "hidden": false,
+        "group": "Frontend",
+        "order": 1
+      },
+      "preLaunchTask": "npm: install"
+    }
+  ]
+}
diff --git a/.vscode/settings.json b/.vscode/settings.json
new file mode 100644
index 0000000..4ff618a
--- /dev/null
+++ b/.vscode/settings.json
@@ -0,0 +1,7 @@
+{
+    "azureFunctions.deploySubpath": "api/bin/Release/net8.0/publish",
+    "azureFunctions.projectLanguage": "C#",
+    "azureFunctions.projectRuntime": "~4",
+    "debug.internalConsoleOptions": "neverOpen",
+    "azureFunctions.preDeployTask": "publish (functions)"
+}
\ No newline at end of file
diff --git a/.vscode/tasks.json b/.vscode/tasks.json
new file mode 100644
index 0000000..370f7e1
--- /dev/null
+++ b/.vscode/tasks.json
@@ -0,0 +1,89 @@
+{
+  "version": "2.0.0",
+  "tasks": [
+    {
+      "label": "clean (functions)",
+      "command": "dotnet",
+      "args": [
+        "clean",
+        "/property:GenerateFullPaths=true",
+        "/consoleloggerparameters:NoSummary"
+      ],
+      "type": "process",
+      "problemMatcher": "$msCompile",
+      "options": {
+        "cwd": "${workspaceFolder}/api"
+      }
+    },
+    {
+      "label": "build (functions)",
+      "command": "dotnet",
+      "args": [
+        "build",
+        "/property:GenerateFullPaths=true",
+        "/consoleloggerparameters:NoSummary"
+      ],
+      "type": "process",
+      "dependsOn": "clean (functions)",
+      "group": {
+        "kind": "build",
+        "isDefault": true
+      },
+      "problemMatcher": "$msCompile",
+      "options": {
+        "cwd": "${workspaceFolder}/api"
+      }
+    },
+    {
+      "label": "clean release (functions)",
+      "command": "dotnet",
+      "args": [
+        "clean",
+        "--configuration",
+        "Release",
+        "/property:GenerateFullPaths=true",
+        "/consoleloggerparameters:NoSummary"
+      ],
+      "type": "process",
+      "problemMatcher": "$msCompile",
+      "options": {
+        "cwd": "${workspaceFolder}/api"
+      }
+    },
+    {
+      "label": "publish (functions)",
+      "command": "dotnet",
+      "args": [
+        "publish",
+        "--configuration",
+        "Release",
+        "/property:GenerateFullPaths=true",
+        "/consoleloggerparameters:NoSummary"
+      ],
+      "type": "process",
+      "dependsOn": "clean release (functions)",
+      "problemMatcher": "$msCompile",
+      "options": {
+        "cwd": "${workspaceFolder}/api"
+      }
+    },
+    {
+      "type": "func",
+      "dependsOn": "build (functions)",
+      "options": {
+        "cwd": "${workspaceFolder}/api/bin/Debug/net8.0"
+      },
+      "command": "host start",
+      "isBackground": true,
+      "problemMatcher": "$func-dotnet-watch"
+    },
+    {
+      "type": "npm",
+      "options": {
+        "cwd": "${workspaceFolder}/client"
+      },
+      "script": "install",
+      "label": "npm: install"
+    }
+  ]
+}
diff --git a/README.md b/README.md
index 4fcc945..46433b3 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,168 @@
-Coming Soon!
+---
+page_type: sample
+languages:
+- azdeveloper
+- csharp
+- sql
+- tsql
+- javascript
+- html
+- bicep
+products:
+- azure-functions
+- azure-sql-database
+- static-web-apps
+- sql-server
+- azure-sql-managed-instance
+- azure-sqlserver-vm
+- dotnet
+- azure-openai
+urlFragment: azure-sql-db-session-recommender
+name: Session Recommender using Azure SQL DB, Open AI and Vector Search
+description: Build a session recommender using Jamstack and Event-Driven architecture, using Azure SQL DB to store and search vectors embeddings generated using OpenAI
+---
+<!-- YAML front-matter schema: https://review.learn.microsoft.com/en-us/help/contribute/samples/process/onboarding?branch=main#supported-metadata-fields-for-readmemd -->
 
-In the meantime take a look at v1 of this project:
+# Session Assistant Sample - Retrieveal Augmented Generation with Azure SQL DB and OpenAI
 
-- https://sessionfinder.dotnetconf.net/
-- https://github.com/Azure-Samples/azure-sql-db-session-recommender
+This repository is a evoution of the [Session Recommender](https://github.com/azure-samples/azure-sql-db-session-recommender) sample. In addition to vector search, also Retrival Augmented Generation (RAG) is used to generate the response to the user query. If you are completely new to this topic, you may want to start there, and then come back here.
+
+![Architecture Diagram](./_docs/session-recommender-architecture.png)
+
+A session recommender built using
+
+- [Azure Static Web Apps](https://learn.microsoft.com/en-us/azure/static-web-apps/overview)
+- [Azure OpenAI](https://learn.microsoft.com/en-us/azure/ai-services/openai/)
+- [Azure Functions](https://learn.microsoft.com/en-us/azure/azure-functions/functions-overview?pivots=programming-language-csharp)
+- [Azure SQL Database](https://www.sqlservercentral.com/articles/the-sql-developer-experience-beyond-rdbms)
+- [Data API builder](https://aka.ms/dab)
+
+For more details on the solution check also the following articles:
+
+- [How I built a session recommender in 1 hour using Open AI](https://dev.to/azure/how-i-built-a-session-recommender-in-1-hour-using-open-ai-5419)
+- [Vector Similarity Search with Azure SQL database and OpenAI](https://devblogs.microsoft.com/azure-sql/vector-similarity-search-with-azure-sql-database-and-openai/)
+
+# Deploy the sample using the Azure Developer CLI (azd) template
+
+The Azure Developer CLI (`azd`) is a developer-centric command-line interface (CLI) tool for creating Azure applications.
+
+## Prerequisites
+
+- Install [AZD CLI](https://learn.microsoft.com/azure/developer/azure-developer-cli/install-azd).
+- Install [.NET SDK](https://dotnet.microsoft.com/download).
+- Install [Node.js](https://nodejs.org/download/).
+- Install [SWA CLI](https://azure.github.io/static-web-apps-cli/docs/use/install#installing-the-cli).
+
+## Install AZD CLI
+
+You need to install it before running and deploying with the Azure Developer CLI.
+
+### Windows
+
+```powershell
+powershell -ex AllSigned -c "Invoke-RestMethod 'https://aka.ms/install-azd.ps1' | Invoke-Expression"
+```
+
+### Linux/MacOS
+
+```bash
+curl -fsSL https://aka.ms/install-azd.sh | bash
+```
+
+After logging in with the following command, you will be able to use azd cli to quickly provision and deploy the application.
+
+## Authenticate with Azure
+
+Make sure AZD CLI can access Azure resources. You can use the following command to log in to Azure:
+
+```bash
+azd auth login
+```
+
+## Initialize the template
+
+Then, execute the `azd init` command to initialize the environment (You do not need to run this command if you already have the code or have opened this in a Codespace or DevContainer).
+
+```bash
+azd init -t Azure-Samples/azure-sql-db-session-recommender-v2
+```
+
+Enter an environment name.
+
+## Deploy the sample
+
+Run `azd up` to provision all the resources to Azure and deploy the code to those resources.
+
+```bash
+azd up 
+```
+
+Select your desired `subscription` and `location`. Then choose a resource group or create a new resource group. Wait a moment for the resource deployment to complete, click the Website endpoint and you will see the web app page.
+
+**Note**: Make sure to pick a region where all services are available like, for example, *West Europe* or *East US 2*
+
+## GitHub Actions
+
+Using the Azure Developer CLI, you can setup your pipelines, monitor your application, test and debug locally.
+
+```bash
+azd pipeline config
+```
+
+## Test the solution
+
+Add a new row to the `Sessions` table using the following SQL statement (you can use tools like [Azure Data Studio](https://learn.microsoft.com/en-us/azure-data-studio/quickstart-sql-database) or [SQL Server Management Studio](https://learn.microsoft.com/en-us/azure/azure-sql/database/connect-query-ssms?view=azuresql) to connect to the database. No need to install them if you don't want. In that case you can use the [SQL Editor in the Azure Portal](https://learn.microsoft.com/en-us/azure/azure-sql/database/connect-query-portal?view=azuresql)):
+
+```sql
+insert into web.sessions 
+    (title, abstract, external_id, start_time_PST, end_time_PST, require_embeddings_update)
+values
+    (
+        'Building a session recommender using OpenAI and Azure SQL', 
+        'In this fun and demo-driven session you’ll learn how to integrate Azure SQL with OpenAI to generate text embeddings, store them in the database, index them and calculate cosine distance to build a session recommender. And once that is done, you’ll publish it as a REST and GraphQL API to be consumed by a modern JavaScript frontend. Sounds pretty cool, uh? Well, it is!',
+        'S1',
+		'2024-03-10 10:00:00',
+        '2024-03-10 11:00:00',
+        1
+    )
+```
+
+immediately the deployed Azure Function will get executed in response to the `INSERT` statement. The Azure Function will call the OpenAI service to generate the text embedding for the session title and abstract, and then store the embedding in the database, specifically in the `web.sessions_embeddings` table.
+
+```sql
+select * from web.sessions_embeddings
+```
+
+You can now open the URL associated with the created Static Web App to see the session recommender in action. You can get the URL from the Static Web App overview page in the Azure portal.
+
+![Website running](./_docs/session-recommender.png)
+
+## Run the solution locally
+
+The whole solution can be executed locally, using [Static Web App CLI](https://github.com/Azure/static-web-apps-cli) and [Azure Function CLI](https://learn.microsoft.com/en-us/azure/azure-functions/functions-run-local?tabs=windows%2Cisolated-process%2Cnode-v4%2Cpython-v2%2Chttp-trigger%2Ccontainer-apps&pivots=programming-language-csharp).
+
+Install the required node packages needed by the fronted:
+
+```bash
+cd client
+npm install
+```
+
+once finished, create a `./func/local.settings.json` and `.env` starting from provided samples files, and fill out the settings using the correct values for your environment.
+
+From the sample root folder run:
+
+```bash
+swa start ./client --api-location ./func --data-api-location ./swa-db-connections
+```
+
+## Fluent UI
+
+The solution uses Fluent UI for the UI components. The Fluent UI is a collection of UX frameworks from Microsoft that provides a consistent design language for web, mobile, and desktop applications. More details about Fluent UI can be found at the following links: 
+
+- https://github.com/microsoft/fluentui
+- https://react.fluentui.dev/ 
+
+## Credits
+
+Thanks a lot to [Aaron Powell](https://www.aaron-powell.com/) for having helped in building the RAG sample, doing a complete UI revamp using the Fluent UI and for the implementaiton of the `ask` endpoint.
\ No newline at end of file
diff --git a/azure.yaml b/azure.yaml
new file mode 100644
index 0000000..b03c92c
--- /dev/null
+++ b/azure.yaml
@@ -0,0 +1,15 @@
+# yaml-language-server: $schema=https://raw.githubusercontent.com/Azure/azure-dev/main/schemas/v1.0/azure.yaml.json
+
+name: azure-sql-db-session-recommender-v2
+metadata:
+  template: azure-sql-db-session-recommender-v2
+services:
+  web:
+    project: ./client
+    language: js
+    host: staticwebapp
+    dist: dist
+  functionapp:
+    project: ./func
+    language: dotnet
+    host: function
\ No newline at end of file
diff --git a/client/.eslintrc.cjs b/client/.eslintrc.cjs
new file mode 100644
index 0000000..4dcb439
--- /dev/null
+++ b/client/.eslintrc.cjs
@@ -0,0 +1,20 @@
+module.exports = {
+  root: true,
+  env: { browser: true, es2020: true },
+  extends: [
+    'eslint:recommended',
+    'plugin:react/recommended',
+    'plugin:react/jsx-runtime',
+    'plugin:react-hooks/recommended',
+  ],
+  ignorePatterns: ['dist', '.eslintrc.cjs'],
+  parserOptions: { ecmaVersion: 'latest', sourceType: 'module' },
+  settings: { react: { version: '18.2' } },
+  plugins: ['react-refresh'],
+  rules: {
+    'react-refresh/only-export-components': [
+      'warn',
+      { allowConstantExport: true },
+    ],
+  },
+}
diff --git a/client/.gitignore b/client/.gitignore
new file mode 100644
index 0000000..a547bf3
--- /dev/null
+++ b/client/.gitignore
@@ -0,0 +1,24 @@
+# Logs
+logs
+*.log
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+pnpm-debug.log*
+lerna-debug.log*
+
+node_modules
+dist
+dist-ssr
+*.local
+
+# Editor directories and files
+.vscode/*
+!.vscode/extensions.json
+.idea
+.DS_Store
+*.suo
+*.ntvs*
+*.njsproj
+*.sln
+*.sw?
diff --git a/client/index.html b/client/index.html
new file mode 100644
index 0000000..f0fa470
--- /dev/null
+++ b/client/index.html
@@ -0,0 +1,17 @@
+<!doctype html>
+<html lang="en">
+  <head>
+    <meta charset="UTF-8" />    
+    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+    <title>Conference AI Assistant</title>
+    <link rel="preconnect" href="https://fonts.googleapis.com">
+    <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin="">
+    <link href="https://fonts.googleapis.com/css2?family=Open+Sans:wght@400;600&amp;family=Space+Grotesk:wght@700&amp;display=swap" rel="stylesheet">
+    <style>.github-corner:hover .octo-arm{animation:octocat-wave 560ms ease-in-out}@keyframes octocat-wave{0%,100%{transform:rotate(0)}20%,60%{transform:rotate(-25deg)}40%,80%{transform:rotate(10deg)}}@media (max-width:500px){.github-corner:hover .octo-arm{animation:none}.github-corner .octo-arm{animation:octocat-wave 560ms ease-in-out}}</style>
+  </head>
+  <body>
+    <a href="https://github.com/Azure-Samples/azure-sql-db-session-recommender-v2" class="github-corner" aria-label="View source on GitHub"><svg width="80" height="80" viewBox="0 0 250 250" style="fill:#151513; color:#fff; position: absolute; top: 0; border: 0; right: 0;" aria-hidden="true"><path d="M0,0 L115,115 L130,115 L142,142 L250,250 L250,0 Z"></path><path d="M128.3,109.0 C113.8,99.7 119.0,89.6 119.0,89.6 C122.0,82.7 120.5,78.6 120.5,78.6 C119.2,72.0 123.4,76.3 123.4,76.3 C127.3,80.9 125.5,87.3 125.5,87.3 C122.9,97.6 130.6,101.9 134.4,103.2" fill="currentColor" style="transform-origin: 130px 106px;" class="octo-arm"></path><path d="M115.0,115.0 C114.9,115.1 118.7,116.5 119.8,115.4 L133.7,101.6 C136.9,99.2 139.9,98.4 142.2,98.6 C133.8,88.0 127.5,74.4 143.8,58.0 C148.5,53.4 154.0,51.2 159.7,51.0 C160.3,49.4 163.2,43.6 171.4,40.1 C171.4,40.1 176.1,42.5 178.8,56.2 C183.1,58.6 187.2,61.8 190.9,65.4 C194.5,69.0 197.7,73.2 200.1,77.6 C213.8,80.2 216.3,84.9 216.3,84.9 C212.7,93.1 206.9,96.0 205.4,96.6 C205.1,102.4 203.0,107.8 198.3,112.5 C181.9,128.9 168.3,122.5 157.7,114.1 C157.9,116.9 156.7,120.9 152.7,124.9 L141.0,136.5 C139.8,137.7 141.6,141.9 141.8,141.8 Z" fill="currentColor" class="octo-body"></path></svg></a>
+    <div id="root"></div>
+    <script type="module" src="/src/main.tsx"></script>
+  </body>
+</html>
diff --git a/client/package-lock.json b/client/package-lock.json
new file mode 100644
index 0000000..66c4fde
--- /dev/null
+++ b/client/package-lock.json
@@ -0,0 +1,7054 @@
+{
+  "name": "client",
+  "version": "0.0.0",
+  "lockfileVersion": 3,
+  "requires": true,
+  "packages": {
+    "": {
+      "name": "client",
+      "version": "0.0.0",
+      "dependencies": {
+        "@fluentui/react": "^8.115.5",
+        "@fluentui/react-components": "^9.38.0",
+        "dayjs": "^1.11.10",
+        "localforage": "^1.10.0",
+        "localstorage-slim": "^2.7.0",
+        "match-sorter": "^6.3.1",
+        "react": "^18.2.0",
+        "react-dom": "^18.2.0",
+        "react-markdown": "^9.0.1",
+        "react-router-dom": "^6.16.0",
+        "sort-by": "^1.2.0"
+      },
+      "devDependencies": {
+        "@types/react": "^18.2.15",
+        "@types/react-dom": "^18.2.7",
+        "@typescript-eslint/eslint-plugin": "^6.10.0",
+        "@typescript-eslint/parser": "^6.10.0",
+        "@vitejs/plugin-react": "^4.0.3",
+        "eslint": "^8.45.0",
+        "eslint-plugin-react": "^7.32.2",
+        "eslint-plugin-react-hooks": "^4.6.0",
+        "eslint-plugin-react-refresh": "^0.4.3",
+        "typescript": "^5.2.2",
+        "vite": "^4.5.2"
+      }
+    },
+    "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/@ampproject/remapping": {
+      "version": "2.2.1",
+      "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.1.tgz",
+      "integrity": "sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==",
+      "dev": true,
+      "dependencies": {
+        "@jridgewell/gen-mapping": "^0.3.0",
+        "@jridgewell/trace-mapping": "^0.3.9"
+      },
+      "engines": {
+        "node": ">=6.0.0"
+      }
+    },
+    "node_modules/@babel/code-frame": {
+      "version": "7.22.13",
+      "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.13.tgz",
+      "integrity": "sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w==",
+      "dev": true,
+      "dependencies": {
+        "@babel/highlight": "^7.22.13",
+        "chalk": "^2.4.2"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/compat-data": {
+      "version": "7.22.20",
+      "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.22.20.tgz",
+      "integrity": "sha512-BQYjKbpXjoXwFW5jGqiizJQQT/aC7pFm9Ok1OWssonuguICi264lbgMzRp2ZMmRSlfkX6DsWDDcsrctK8Rwfiw==",
+      "dev": true,
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/core": {
+      "version": "7.23.0",
+      "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.23.0.tgz",
+      "integrity": "sha512-97z/ju/Jy1rZmDxybphrBuI+jtJjFVoz7Mr9yUQVVVi+DNZE333uFQeMOqcCIy1x3WYBIbWftUSLmbNXNT7qFQ==",
+      "dev": true,
+      "dependencies": {
+        "@ampproject/remapping": "^2.2.0",
+        "@babel/code-frame": "^7.22.13",
+        "@babel/generator": "^7.23.0",
+        "@babel/helper-compilation-targets": "^7.22.15",
+        "@babel/helper-module-transforms": "^7.23.0",
+        "@babel/helpers": "^7.23.0",
+        "@babel/parser": "^7.23.0",
+        "@babel/template": "^7.22.15",
+        "@babel/traverse": "^7.23.0",
+        "@babel/types": "^7.23.0",
+        "convert-source-map": "^2.0.0",
+        "debug": "^4.1.0",
+        "gensync": "^1.0.0-beta.2",
+        "json5": "^2.2.3",
+        "semver": "^6.3.1"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/babel"
+      }
+    },
+    "node_modules/@babel/generator": {
+      "version": "7.23.0",
+      "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.0.tgz",
+      "integrity": "sha512-lN85QRR+5IbYrMWM6Y4pE/noaQtg4pNiqeNGX60eqOfo6gtEj6uw/JagelB8vVztSd7R6M5n1+PQkDbHbBRU4g==",
+      "dev": true,
+      "dependencies": {
+        "@babel/types": "^7.23.0",
+        "@jridgewell/gen-mapping": "^0.3.2",
+        "@jridgewell/trace-mapping": "^0.3.17",
+        "jsesc": "^2.5.1"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/helper-compilation-targets": {
+      "version": "7.22.15",
+      "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.15.tgz",
+      "integrity": "sha512-y6EEzULok0Qvz8yyLkCvVX+02ic+By2UdOhylwUOvOn9dvYc9mKICJuuU1n1XBI02YWsNsnrY1kc6DVbjcXbtw==",
+      "dev": true,
+      "dependencies": {
+        "@babel/compat-data": "^7.22.9",
+        "@babel/helper-validator-option": "^7.22.15",
+        "browserslist": "^4.21.9",
+        "lru-cache": "^5.1.1",
+        "semver": "^6.3.1"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/helper-environment-visitor": {
+      "version": "7.22.20",
+      "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz",
+      "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==",
+      "dev": true,
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/helper-function-name": {
+      "version": "7.23.0",
+      "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz",
+      "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==",
+      "dev": true,
+      "dependencies": {
+        "@babel/template": "^7.22.15",
+        "@babel/types": "^7.23.0"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/helper-hoist-variables": {
+      "version": "7.22.5",
+      "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz",
+      "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==",
+      "dev": true,
+      "dependencies": {
+        "@babel/types": "^7.22.5"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/helper-module-imports": {
+      "version": "7.22.15",
+      "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.22.15.tgz",
+      "integrity": "sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w==",
+      "dev": true,
+      "dependencies": {
+        "@babel/types": "^7.22.15"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/helper-module-transforms": {
+      "version": "7.23.0",
+      "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.23.0.tgz",
+      "integrity": "sha512-WhDWw1tdrlT0gMgUJSlX0IQvoO1eN279zrAUbVB+KpV2c3Tylz8+GnKOLllCS6Z/iZQEyVYxhZVUdPTqs2YYPw==",
+      "dev": true,
+      "dependencies": {
+        "@babel/helper-environment-visitor": "^7.22.20",
+        "@babel/helper-module-imports": "^7.22.15",
+        "@babel/helper-simple-access": "^7.22.5",
+        "@babel/helper-split-export-declaration": "^7.22.6",
+        "@babel/helper-validator-identifier": "^7.22.20"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0"
+      }
+    },
+    "node_modules/@babel/helper-plugin-utils": {
+      "version": "7.22.5",
+      "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz",
+      "integrity": "sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg==",
+      "dev": true,
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/helper-simple-access": {
+      "version": "7.22.5",
+      "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz",
+      "integrity": "sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==",
+      "dev": true,
+      "dependencies": {
+        "@babel/types": "^7.22.5"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/helper-split-export-declaration": {
+      "version": "7.22.6",
+      "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz",
+      "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==",
+      "dev": true,
+      "dependencies": {
+        "@babel/types": "^7.22.5"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/helper-string-parser": {
+      "version": "7.22.5",
+      "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz",
+      "integrity": "sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==",
+      "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/helper-validator-option": {
+      "version": "7.22.15",
+      "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.22.15.tgz",
+      "integrity": "sha512-bMn7RmyFjY/mdECUbgn9eoSY4vqvacUnS9i9vGAGttgFWesO6B4CYWA7XlpbWgBt71iv/hfbPlynohStqnu5hA==",
+      "dev": true,
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/helpers": {
+      "version": "7.23.1",
+      "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.23.1.tgz",
+      "integrity": "sha512-chNpneuK18yW5Oxsr+t553UZzzAs3aZnFm4bxhebsNTeshrC95yA7l5yl7GBAG+JG1rF0F7zzD2EixK9mWSDoA==",
+      "dev": true,
+      "dependencies": {
+        "@babel/template": "^7.22.15",
+        "@babel/traverse": "^7.23.0",
+        "@babel/types": "^7.23.0"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/highlight": {
+      "version": "7.22.20",
+      "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.20.tgz",
+      "integrity": "sha512-dkdMCN3py0+ksCgYmGG8jKeGA/8Tk+gJwSYYlFGxG5lmhfKNoAy004YpLxpS1W2J8m/EK2Ew+yOs9pVRwO89mg==",
+      "dev": true,
+      "dependencies": {
+        "@babel/helper-validator-identifier": "^7.22.20",
+        "chalk": "^2.4.2",
+        "js-tokens": "^4.0.0"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/parser": {
+      "version": "7.23.0",
+      "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.0.tgz",
+      "integrity": "sha512-vvPKKdMemU85V9WE/l5wZEmImpCtLqbnTvqDS2U1fJ96KrxoW7KrXhNsNCblQlg8Ck4b85yxdTyelsMUgFUXiw==",
+      "dev": true,
+      "bin": {
+        "parser": "bin/babel-parser.js"
+      },
+      "engines": {
+        "node": ">=6.0.0"
+      }
+    },
+    "node_modules/@babel/plugin-transform-react-jsx-self": {
+      "version": "7.22.5",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.22.5.tgz",
+      "integrity": "sha512-nTh2ogNUtxbiSbxaT4Ds6aXnXEipHweN9YRgOX/oNXdf0cCrGn/+2LozFa3lnPV5D90MkjhgckCPBrsoSc1a7g==",
+      "dev": true,
+      "dependencies": {
+        "@babel/helper-plugin-utils": "^7.22.5"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@babel/plugin-transform-react-jsx-source": {
+      "version": "7.22.5",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.22.5.tgz",
+      "integrity": "sha512-yIiRO6yobeEIaI0RTbIr8iAK9FcBHLtZq0S89ZPjDLQXBA4xvghaKqI0etp/tF3htTM0sazJKKLz9oEiGRtu7w==",
+      "dev": true,
+      "dependencies": {
+        "@babel/helper-plugin-utils": "^7.22.5"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@babel/runtime": {
+      "version": "7.23.1",
+      "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.23.1.tgz",
+      "integrity": "sha512-hC2v6p8ZSI/W0HUzh3V8C5g+NwSKzKPtJwSpTjwl0o297GP9+ZLQSkdvHz46CM3LqyoXxq+5G9komY+eSqSO0g==",
+      "dependencies": {
+        "regenerator-runtime": "^0.14.0"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/template": {
+      "version": "7.22.15",
+      "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz",
+      "integrity": "sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==",
+      "dev": true,
+      "dependencies": {
+        "@babel/code-frame": "^7.22.13",
+        "@babel/parser": "^7.22.15",
+        "@babel/types": "^7.22.15"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/traverse": {
+      "version": "7.23.0",
+      "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.0.tgz",
+      "integrity": "sha512-t/QaEvyIoIkwzpiZ7aoSKK8kObQYeF7T2v+dazAYCb8SXtp58zEVkWW7zAnju8FNKNdr4ScAOEDmMItbyOmEYw==",
+      "dev": true,
+      "dependencies": {
+        "@babel/code-frame": "^7.22.13",
+        "@babel/generator": "^7.23.0",
+        "@babel/helper-environment-visitor": "^7.22.20",
+        "@babel/helper-function-name": "^7.23.0",
+        "@babel/helper-hoist-variables": "^7.22.5",
+        "@babel/helper-split-export-declaration": "^7.22.6",
+        "@babel/parser": "^7.23.0",
+        "@babel/types": "^7.23.0",
+        "debug": "^4.1.0",
+        "globals": "^11.1.0"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/types": {
+      "version": "7.23.0",
+      "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.0.tgz",
+      "integrity": "sha512-0oIyUfKoI3mSqMvsxBdclDwxXKXAUA8v/apZbc+iSyARYou1o8ZGDxbUYyLFoW2arqS2jDGqJuZvv1d/io1axg==",
+      "dev": true,
+      "dependencies": {
+        "@babel/helper-string-parser": "^7.22.5",
+        "@babel/helper-validator-identifier": "^7.22.20",
+        "to-fast-properties": "^2.0.0"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@emotion/hash": {
+      "version": "0.9.1",
+      "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.9.1.tgz",
+      "integrity": "sha512-gJB6HLm5rYwSLI6PQa+X1t5CFGrv1J1TWG+sOyMCeKz2ojaj6Fnl/rZEspogG+cvqbt4AE/2eIyD2QfLKTBNlQ=="
+    },
+    "node_modules/@esbuild/android-arm": {
+      "version": "0.18.20",
+      "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.20.tgz",
+      "integrity": "sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==",
+      "cpu": [
+        "arm"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "android"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@esbuild/android-arm64": {
+      "version": "0.18.20",
+      "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.18.20.tgz",
+      "integrity": "sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==",
+      "cpu": [
+        "arm64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "android"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@esbuild/android-x64": {
+      "version": "0.18.20",
+      "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.18.20.tgz",
+      "integrity": "sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "android"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@esbuild/darwin-arm64": {
+      "version": "0.18.20",
+      "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.18.20.tgz",
+      "integrity": "sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==",
+      "cpu": [
+        "arm64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "darwin"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@esbuild/darwin-x64": {
+      "version": "0.18.20",
+      "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.18.20.tgz",
+      "integrity": "sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "darwin"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@esbuild/freebsd-arm64": {
+      "version": "0.18.20",
+      "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.20.tgz",
+      "integrity": "sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==",
+      "cpu": [
+        "arm64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "freebsd"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@esbuild/freebsd-x64": {
+      "version": "0.18.20",
+      "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.18.20.tgz",
+      "integrity": "sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "freebsd"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@esbuild/linux-arm": {
+      "version": "0.18.20",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.18.20.tgz",
+      "integrity": "sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==",
+      "cpu": [
+        "arm"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@esbuild/linux-arm64": {
+      "version": "0.18.20",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.18.20.tgz",
+      "integrity": "sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==",
+      "cpu": [
+        "arm64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@esbuild/linux-ia32": {
+      "version": "0.18.20",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.18.20.tgz",
+      "integrity": "sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==",
+      "cpu": [
+        "ia32"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@esbuild/linux-loong64": {
+      "version": "0.18.20",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.18.20.tgz",
+      "integrity": "sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==",
+      "cpu": [
+        "loong64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@esbuild/linux-mips64el": {
+      "version": "0.18.20",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.18.20.tgz",
+      "integrity": "sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==",
+      "cpu": [
+        "mips64el"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@esbuild/linux-ppc64": {
+      "version": "0.18.20",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.18.20.tgz",
+      "integrity": "sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==",
+      "cpu": [
+        "ppc64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@esbuild/linux-riscv64": {
+      "version": "0.18.20",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.18.20.tgz",
+      "integrity": "sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==",
+      "cpu": [
+        "riscv64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@esbuild/linux-s390x": {
+      "version": "0.18.20",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.18.20.tgz",
+      "integrity": "sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==",
+      "cpu": [
+        "s390x"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@esbuild/linux-x64": {
+      "version": "0.18.20",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.18.20.tgz",
+      "integrity": "sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@esbuild/netbsd-x64": {
+      "version": "0.18.20",
+      "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.18.20.tgz",
+      "integrity": "sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "netbsd"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@esbuild/openbsd-x64": {
+      "version": "0.18.20",
+      "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.18.20.tgz",
+      "integrity": "sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "openbsd"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@esbuild/sunos-x64": {
+      "version": "0.18.20",
+      "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.18.20.tgz",
+      "integrity": "sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "sunos"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@esbuild/win32-arm64": {
+      "version": "0.18.20",
+      "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.18.20.tgz",
+      "integrity": "sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==",
+      "cpu": [
+        "arm64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "win32"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@esbuild/win32-ia32": {
+      "version": "0.18.20",
+      "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.18.20.tgz",
+      "integrity": "sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==",
+      "cpu": [
+        "ia32"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "win32"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@esbuild/win32-x64": {
+      "version": "0.18.20",
+      "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.18.20.tgz",
+      "integrity": "sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==",
+      "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.9.1",
+      "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.9.1.tgz",
+      "integrity": "sha512-Y27x+MBLjXa+0JWDhykM3+JE+il3kHKAEqabfEWq3SDhZjLYb6/BHL/JKFnH3fe207JaXkyDo685Oc2Glt6ifA==",
+      "dev": true,
+      "engines": {
+        "node": "^12.0.0 || ^14.0.0 || >=16.0.0"
+      }
+    },
+    "node_modules/@eslint/eslintrc": {
+      "version": "2.1.2",
+      "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.2.tgz",
+      "integrity": "sha512-+wvgpDsrB1YqAMdEUCcnTlpfVBH7Vqn6A/NT3D8WVXFIaKMlErPIZT3oCIAVCOtarRpMtelZLqJeU3t7WY6X6g==",
+      "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/globals": {
+      "version": "13.23.0",
+      "resolved": "https://registry.npmjs.org/globals/-/globals-13.23.0.tgz",
+      "integrity": "sha512-XAmF0RjlrjY23MA51q3HltdlGxUpXPvg0GioKiD9X6HD28iMjo2dKC8Vqwm7lne4GNr78+RHTfliktR6ZH09wA==",
+      "dev": true,
+      "dependencies": {
+        "type-fest": "^0.20.2"
+      },
+      "engines": {
+        "node": ">=8"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/@eslint/js": {
+      "version": "8.51.0",
+      "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.51.0.tgz",
+      "integrity": "sha512-HxjQ8Qn+4SI3/AFv6sOrDB+g6PpUTDwSJiQqOrnneEk8L71161srI9gjzzZvYVbzHiVg/BvcH95+cK/zfIt4pg==",
+      "dev": true,
+      "engines": {
+        "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+      }
+    },
+    "node_modules/@floating-ui/core": {
+      "version": "1.5.0",
+      "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.5.0.tgz",
+      "integrity": "sha512-kK1h4m36DQ0UHGj5Ah4db7R0rHemTqqO0QLvUqi1/mUUp3LuAWbWxdxSIf/XsnH9VS6rRVPLJCncjRzUvyCLXg==",
+      "dependencies": {
+        "@floating-ui/utils": "^0.1.3"
+      }
+    },
+    "node_modules/@floating-ui/dom": {
+      "version": "1.5.3",
+      "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.5.3.tgz",
+      "integrity": "sha512-ClAbQnEqJAKCJOEbbLo5IUlZHkNszqhuxS4fHAVxRPXPya6Ysf2G8KypnYcOTpx6I8xcgF9bbHb6g/2KpbV8qA==",
+      "dependencies": {
+        "@floating-ui/core": "^1.4.2",
+        "@floating-ui/utils": "^0.1.3"
+      }
+    },
+    "node_modules/@floating-ui/utils": {
+      "version": "0.1.6",
+      "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.1.6.tgz",
+      "integrity": "sha512-OfX7E2oUDYxtBvsuS4e/jSn4Q9Qb6DzgeYtsAdkPZ47znpoNsMgZw0+tVijiv3uGNR6dgNlty6r9rzIzHjtd/A=="
+    },
+    "node_modules/@fluentui/date-time-utilities": {
+      "version": "8.5.16",
+      "resolved": "https://registry.npmjs.org/@fluentui/date-time-utilities/-/date-time-utilities-8.5.16.tgz",
+      "integrity": "sha512-l+mLfJ2VhdHjBpELLLPDaWgT7GMLynm2aqR7SttbEb6Jh7hc/7ck1MWm93RTb3gYVHYai8SENqimNcvIxHt/zg==",
+      "dependencies": {
+        "@fluentui/set-version": "^8.2.14",
+        "tslib": "^2.1.0"
+      }
+    },
+    "node_modules/@fluentui/dom-utilities": {
+      "version": "2.2.14",
+      "resolved": "https://registry.npmjs.org/@fluentui/dom-utilities/-/dom-utilities-2.2.14.tgz",
+      "integrity": "sha512-+4DVm5sNfJh+l8fM+7ylpOkGNZkNr4X1z1uKQPzRJ1PRhlnvc6vLpWNNicGwpjTbgufSrVtGKXwP5sf++r81lg==",
+      "dependencies": {
+        "@fluentui/set-version": "^8.2.14",
+        "tslib": "^2.1.0"
+      }
+    },
+    "node_modules/@fluentui/font-icons-mdl2": {
+      "version": "8.5.32",
+      "resolved": "https://registry.npmjs.org/@fluentui/font-icons-mdl2/-/font-icons-mdl2-8.5.32.tgz",
+      "integrity": "sha512-PCZMijJlDQ5Zy8oNb80vUD6I4ORiR03qFgDT8o08mAGu+KzQO96q4jm0rzPRQuI9CO7pDD/6naOo8UVrmhZ2Aw==",
+      "dependencies": {
+        "@fluentui/set-version": "^8.2.14",
+        "@fluentui/style-utilities": "^8.10.3",
+        "@fluentui/utilities": "^8.13.24",
+        "tslib": "^2.1.0"
+      }
+    },
+    "node_modules/@fluentui/foundation-legacy": {
+      "version": "8.2.52",
+      "resolved": "https://registry.npmjs.org/@fluentui/foundation-legacy/-/foundation-legacy-8.2.52.tgz",
+      "integrity": "sha512-tHCD0m58Zja7wN1FTsvj4Gaj0B22xOhRTpyDzyvxRfjFGYPpR2Jgx/y/KRB3JTOX5EfJHAVzInyWZBeN5IfsVA==",
+      "dependencies": {
+        "@fluentui/merge-styles": "^8.5.15",
+        "@fluentui/set-version": "^8.2.14",
+        "@fluentui/style-utilities": "^8.10.3",
+        "@fluentui/utilities": "^8.13.24",
+        "tslib": "^2.1.0"
+      },
+      "peerDependencies": {
+        "@types/react": ">=16.8.0 <19.0.0",
+        "react": ">=16.8.0 <19.0.0"
+      }
+    },
+    "node_modules/@fluentui/keyboard-key": {
+      "version": "0.4.14",
+      "resolved": "https://registry.npmjs.org/@fluentui/keyboard-key/-/keyboard-key-0.4.14.tgz",
+      "integrity": "sha512-XzZHcyFEM20H23h3i15UpkHi2AhRBriXPGAHq0Jm98TKFppXehedjjEFuUsh+CyU5JKBhDalWp8TAQ1ArpNzow==",
+      "dependencies": {
+        "tslib": "^2.1.0"
+      }
+    },
+    "node_modules/@fluentui/keyboard-keys": {
+      "version": "9.0.7",
+      "resolved": "https://registry.npmjs.org/@fluentui/keyboard-keys/-/keyboard-keys-9.0.7.tgz",
+      "integrity": "sha512-vaQ+lOveQTdoXJYqDQXWb30udSfTVcIuKk1rV0X0eGAgcHeSDeP1HxMy+OgHOQZH3OiBH4ZYeWxb+tmfiDiygQ==",
+      "dependencies": {
+        "@swc/helpers": "^0.5.1"
+      }
+    },
+    "node_modules/@fluentui/merge-styles": {
+      "version": "8.5.15",
+      "resolved": "https://registry.npmjs.org/@fluentui/merge-styles/-/merge-styles-8.5.15.tgz",
+      "integrity": "sha512-4CdKwo4k1Un2QLulpSVIz/KMgLNBMgin4NPyapmKDMVuO1OOxJUqfocubRGNO5x9mKgAMMYwBKGO9i0uxMMpJw==",
+      "dependencies": {
+        "@fluentui/set-version": "^8.2.14",
+        "tslib": "^2.1.0"
+      }
+    },
+    "node_modules/@fluentui/priority-overflow": {
+      "version": "9.1.9",
+      "resolved": "https://registry.npmjs.org/@fluentui/priority-overflow/-/priority-overflow-9.1.9.tgz",
+      "integrity": "sha512-+YlmuQ2E2le/FsJHKQPgs/vx2q4nDFXTN1yDLht2RUQl8/wsl7AHorHyMU/9ETPoxVWP+fFMnj3rTV+e5vWirg==",
+      "dependencies": {
+        "@swc/helpers": "^0.5.1"
+      }
+    },
+    "node_modules/@fluentui/react": {
+      "version": "8.115.5",
+      "resolved": "https://registry.npmjs.org/@fluentui/react/-/react-8.115.5.tgz",
+      "integrity": "sha512-/Dmtf52r1pd2tbJ6NqbC65Zs+V/lOharui2uTtc0GxaMr3QREUWUkojtxKFwLVHqCrO1NzcIZm6siqR4z6ucRw==",
+      "dependencies": {
+        "@fluentui/date-time-utilities": "^8.5.16",
+        "@fluentui/font-icons-mdl2": "^8.5.32",
+        "@fluentui/foundation-legacy": "^8.2.52",
+        "@fluentui/merge-styles": "^8.5.15",
+        "@fluentui/react-focus": "^8.8.40",
+        "@fluentui/react-hooks": "^8.6.36",
+        "@fluentui/react-portal-compat-context": "^9.0.11",
+        "@fluentui/react-window-provider": "^2.2.18",
+        "@fluentui/set-version": "^8.2.14",
+        "@fluentui/style-utilities": "^8.10.3",
+        "@fluentui/theme": "^2.6.41",
+        "@fluentui/utilities": "^8.13.24",
+        "@microsoft/load-themed-styles": "^1.10.26",
+        "tslib": "^2.1.0"
+      },
+      "peerDependencies": {
+        "@types/react": ">=16.8.0 <19.0.0",
+        "@types/react-dom": ">=16.8.0 <19.0.0",
+        "react": ">=16.8.0 <19.0.0",
+        "react-dom": ">=16.8.0 <19.0.0"
+      }
+    },
+    "node_modules/@fluentui/react-accordion": {
+      "version": "9.3.27",
+      "resolved": "https://registry.npmjs.org/@fluentui/react-accordion/-/react-accordion-9.3.27.tgz",
+      "integrity": "sha512-JBG5werMVMqpZJrQeGqrVyF7AOALkFrzQH4MZ0Pcf9zo3qnZ62QUz7YEj+Zl/In7jdfQhRTJ8grf47c4b6Nsiw==",
+      "dependencies": {
+        "@fluentui/react-aria": "^9.3.44",
+        "@fluentui/react-context-selector": "^9.1.42",
+        "@fluentui/react-icons": "^2.0.217",
+        "@fluentui/react-jsx-runtime": "^9.0.19",
+        "@fluentui/react-shared-contexts": "^9.12.0",
+        "@fluentui/react-tabster": "^9.14.4",
+        "@fluentui/react-theme": "^9.1.16",
+        "@fluentui/react-utilities": "^9.15.2",
+        "@griffel/react": "^1.5.14",
+        "@swc/helpers": "^0.5.1"
+      },
+      "peerDependencies": {
+        "@types/react": ">=16.14.0 <19.0.0",
+        "@types/react-dom": ">=16.14.0 <19.0.0",
+        "react": ">=16.14.0 <19.0.0",
+        "react-dom": ">=16.14.0 <19.0.0",
+        "scheduler": "^0.19.0 || ^0.20.0"
+      }
+    },
+    "node_modules/@fluentui/react-alert": {
+      "version": "9.0.0-beta.91",
+      "resolved": "https://registry.npmjs.org/@fluentui/react-alert/-/react-alert-9.0.0-beta.91.tgz",
+      "integrity": "sha512-cH7I64f2uq7x7Ly4oaapZZY9EU+xbqmvgJAgi7Px8LwvC3zohI1RZtlpaTKitjR3Aq51YYd9tP3VU8+1W58PwA==",
+      "dependencies": {
+        "@fluentui/react-avatar": "^9.5.45",
+        "@fluentui/react-button": "^9.3.54",
+        "@fluentui/react-icons": "^2.0.217",
+        "@fluentui/react-jsx-runtime": "^9.0.19",
+        "@fluentui/react-tabster": "^9.14.4",
+        "@fluentui/react-theme": "^9.1.16",
+        "@fluentui/react-utilities": "^9.15.2",
+        "@griffel/react": "^1.5.14",
+        "@swc/helpers": "^0.5.1"
+      },
+      "peerDependencies": {
+        "@types/react": ">=16.14.0 <19.0.0",
+        "@types/react-dom": ">=16.14.0 <19.0.0",
+        "react": ">=16.14.0 <19.0.0",
+        "react-dom": ">=16.14.0 <19.0.0"
+      }
+    },
+    "node_modules/@fluentui/react-aria": {
+      "version": "9.3.44",
+      "resolved": "https://registry.npmjs.org/@fluentui/react-aria/-/react-aria-9.3.44.tgz",
+      "integrity": "sha512-D3pvGgYObBzO00lhwhuuMWbPOZccy5EaYLXXI3OvzYdTs6ias6xXsOCgdnvrQ8BsIKixNUbtfjjxWCCIcLr4cg==",
+      "dependencies": {
+        "@fluentui/keyboard-keys": "^9.0.7",
+        "@fluentui/react-utilities": "^9.15.2",
+        "@swc/helpers": "^0.5.1"
+      },
+      "peerDependencies": {
+        "@types/react": ">=16.14.0 <19.0.0",
+        "@types/react-dom": ">=16.14.0 <19.0.0",
+        "react": ">=16.14.0 <19.0.0",
+        "react-dom": ">=16.14.0 <19.0.0"
+      }
+    },
+    "node_modules/@fluentui/react-avatar": {
+      "version": "9.5.45",
+      "resolved": "https://registry.npmjs.org/@fluentui/react-avatar/-/react-avatar-9.5.45.tgz",
+      "integrity": "sha512-JEpjDO9O06IERUJQa0i19QLvA36vK81a3xuMln6rjDEbk53Lw5IohhzIAr2ozBGk61x4woJPiyP9hX0uol0ACA==",
+      "dependencies": {
+        "@fluentui/react-badge": "^9.2.13",
+        "@fluentui/react-context-selector": "^9.1.42",
+        "@fluentui/react-icons": "^2.0.217",
+        "@fluentui/react-jsx-runtime": "^9.0.19",
+        "@fluentui/react-popover": "^9.8.20",
+        "@fluentui/react-shared-contexts": "^9.12.0",
+        "@fluentui/react-tabster": "^9.14.4",
+        "@fluentui/react-theme": "^9.1.16",
+        "@fluentui/react-tooltip": "^9.3.21",
+        "@fluentui/react-utilities": "^9.15.2",
+        "@griffel/react": "^1.5.14",
+        "@swc/helpers": "^0.5.1"
+      },
+      "peerDependencies": {
+        "@types/react": ">=16.14.0 <19.0.0",
+        "@types/react-dom": ">=16.14.0 <19.0.0",
+        "react": ">=16.14.0 <19.0.0",
+        "react-dom": ">=16.14.0 <19.0.0",
+        "scheduler": "^0.19.0 || ^0.20.0"
+      }
+    },
+    "node_modules/@fluentui/react-badge": {
+      "version": "9.2.13",
+      "resolved": "https://registry.npmjs.org/@fluentui/react-badge/-/react-badge-9.2.13.tgz",
+      "integrity": "sha512-oK8U+VnaFHL0EM9t3f/G+IoVqRNEFILvTibLPufH8voDJbSQDZarXjNEUonovAUqGp4Y3TsCL6y27rRMi9TK/Q==",
+      "dependencies": {
+        "@fluentui/react-icons": "^2.0.217",
+        "@fluentui/react-jsx-runtime": "^9.0.19",
+        "@fluentui/react-shared-contexts": "^9.12.0",
+        "@fluentui/react-theme": "^9.1.16",
+        "@fluentui/react-utilities": "^9.15.2",
+        "@griffel/react": "^1.5.14",
+        "@swc/helpers": "^0.5.1"
+      },
+      "peerDependencies": {
+        "@types/react": ">=16.14.0 <19.0.0",
+        "@types/react-dom": ">=16.14.0 <19.0.0",
+        "react": ">=16.14.0 <19.0.0",
+        "react-dom": ">=16.14.0 <19.0.0"
+      }
+    },
+    "node_modules/@fluentui/react-button": {
+      "version": "9.3.54",
+      "resolved": "https://registry.npmjs.org/@fluentui/react-button/-/react-button-9.3.54.tgz",
+      "integrity": "sha512-hjwpwdSJgYcBVZhonM/h+q++69hNa4OoCkL+SXWyHjKc6UZn9QyUVbdUvyHkhA/K5MhKfzrv5Hw2i4PLJb2S6w==",
+      "dependencies": {
+        "@fluentui/keyboard-keys": "^9.0.7",
+        "@fluentui/react-aria": "^9.3.44",
+        "@fluentui/react-icons": "^2.0.217",
+        "@fluentui/react-jsx-runtime": "^9.0.19",
+        "@fluentui/react-shared-contexts": "^9.12.0",
+        "@fluentui/react-tabster": "^9.14.4",
+        "@fluentui/react-theme": "^9.1.16",
+        "@fluentui/react-utilities": "^9.15.2",
+        "@griffel/react": "^1.5.14",
+        "@swc/helpers": "^0.5.1"
+      },
+      "peerDependencies": {
+        "@types/react": ">=16.14.0 <19.0.0",
+        "@types/react-dom": ">=16.14.0 <19.0.0",
+        "react": ">=16.14.0 <19.0.0",
+        "react-dom": ">=16.14.0 <19.0.0"
+      }
+    },
+    "node_modules/@fluentui/react-card": {
+      "version": "9.0.53",
+      "resolved": "https://registry.npmjs.org/@fluentui/react-card/-/react-card-9.0.53.tgz",
+      "integrity": "sha512-fNKBzLnuU6zVU/YFdsuR63Y0LjjzMg6ptRztGqY92bWilmv8xQVLHhJmUqtw9WTnGu0KM7FmdZZLrCm5gEJM1w==",
+      "dependencies": {
+        "@fluentui/keyboard-keys": "^9.0.7",
+        "@fluentui/react-jsx-runtime": "^9.0.19",
+        "@fluentui/react-tabster": "^9.14.4",
+        "@fluentui/react-theme": "^9.1.16",
+        "@fluentui/react-utilities": "^9.15.2",
+        "@griffel/react": "^1.5.14",
+        "@swc/helpers": "^0.5.1"
+      },
+      "peerDependencies": {
+        "@types/react": ">=16.14.0 <19.0.0",
+        "@types/react-dom": ">=16.14.0 <19.0.0",
+        "react": ">=16.14.0 <19.0.0",
+        "react-dom": ">=16.14.0 <19.0.0"
+      }
+    },
+    "node_modules/@fluentui/react-checkbox": {
+      "version": "9.1.55",
+      "resolved": "https://registry.npmjs.org/@fluentui/react-checkbox/-/react-checkbox-9.1.55.tgz",
+      "integrity": "sha512-1XcTP/6SnHJrk41Qr1A/ntpF9sIVPZkG9YLUxXo1Cz3QeO1yik22GkEugupBlmeyOx4zs+Cwiasw0vZKBRUqew==",
+      "dependencies": {
+        "@fluentui/react-field": "^9.1.41",
+        "@fluentui/react-icons": "^2.0.217",
+        "@fluentui/react-jsx-runtime": "^9.0.19",
+        "@fluentui/react-label": "^9.1.49",
+        "@fluentui/react-shared-contexts": "^9.12.0",
+        "@fluentui/react-tabster": "^9.14.4",
+        "@fluentui/react-theme": "^9.1.16",
+        "@fluentui/react-utilities": "^9.15.2",
+        "@griffel/react": "^1.5.14",
+        "@swc/helpers": "^0.5.1"
+      },
+      "peerDependencies": {
+        "@types/react": ">=16.14.0 <19.0.0",
+        "@types/react-dom": ">=16.14.0 <19.0.0",
+        "react": ">=16.14.0 <19.0.0",
+        "react-dom": ">=16.14.0 <19.0.0"
+      }
+    },
+    "node_modules/@fluentui/react-combobox": {
+      "version": "9.5.29",
+      "resolved": "https://registry.npmjs.org/@fluentui/react-combobox/-/react-combobox-9.5.29.tgz",
+      "integrity": "sha512-IrZGFNL3J+AnN92nN3bD27HPWx++6hcfH/jgpxZGUBdG8F6fhixlItCkx2k4DxONWNNMlZQ/SGB5TXNO5lCP4g==",
+      "dependencies": {
+        "@fluentui/keyboard-keys": "^9.0.7",
+        "@fluentui/react-context-selector": "^9.1.42",
+        "@fluentui/react-field": "^9.1.41",
+        "@fluentui/react-icons": "^2.0.217",
+        "@fluentui/react-jsx-runtime": "^9.0.19",
+        "@fluentui/react-portal": "^9.4.0",
+        "@fluentui/react-positioning": "^9.10.0",
+        "@fluentui/react-shared-contexts": "^9.12.0",
+        "@fluentui/react-theme": "^9.1.16",
+        "@fluentui/react-utilities": "^9.15.2",
+        "@griffel/react": "^1.5.14",
+        "@swc/helpers": "^0.5.1"
+      },
+      "peerDependencies": {
+        "@types/react": ">=16.14.0 <19.0.0",
+        "@types/react-dom": ">=16.14.0 <19.0.0",
+        "react": ">=16.14.0 <19.0.0",
+        "react-dom": ">=16.14.0 <19.0.0",
+        "scheduler": "^0.19.0 || ^0.20.0"
+      }
+    },
+    "node_modules/@fluentui/react-components": {
+      "version": "9.38.0",
+      "resolved": "https://registry.npmjs.org/@fluentui/react-components/-/react-components-9.38.0.tgz",
+      "integrity": "sha512-lDmoYefKSeXjORmO8cvKlDQOkWDfKEuOrMSDci6orxgWnGrIONh6mDmHg7C+2H8DeIWBiK7Bigd75BAWt6TNQA==",
+      "dependencies": {
+        "@fluentui/react-accordion": "^9.3.27",
+        "@fluentui/react-alert": "9.0.0-beta.91",
+        "@fluentui/react-avatar": "^9.5.45",
+        "@fluentui/react-badge": "^9.2.13",
+        "@fluentui/react-button": "^9.3.54",
+        "@fluentui/react-card": "^9.0.53",
+        "@fluentui/react-checkbox": "^9.1.55",
+        "@fluentui/react-combobox": "^9.5.29",
+        "@fluentui/react-dialog": "^9.8.4",
+        "@fluentui/react-divider": "^9.2.49",
+        "@fluentui/react-drawer": "9.0.0",
+        "@fluentui/react-field": "^9.1.41",
+        "@fluentui/react-image": "^9.1.46",
+        "@fluentui/react-infobutton": "9.0.0-beta.75",
+        "@fluentui/react-infolabel": "^9.0.3",
+        "@fluentui/react-input": "^9.4.51",
+        "@fluentui/react-label": "^9.1.49",
+        "@fluentui/react-link": "^9.1.33",
+        "@fluentui/react-menu": "^9.12.31",
+        "@fluentui/react-message-bar": "^9.0.5",
+        "@fluentui/react-overflow": "^9.0.43",
+        "@fluentui/react-persona": "^9.2.55",
+        "@fluentui/react-popover": "^9.8.20",
+        "@fluentui/react-portal": "^9.4.0",
+        "@fluentui/react-positioning": "^9.10.0",
+        "@fluentui/react-progress": "^9.1.51",
+        "@fluentui/react-provider": "^9.12.0",
+        "@fluentui/react-radio": "^9.1.55",
+        "@fluentui/react-select": "^9.1.51",
+        "@fluentui/react-shared-contexts": "^9.12.0",
+        "@fluentui/react-skeleton": "^9.0.39",
+        "@fluentui/react-slider": "^9.1.55",
+        "@fluentui/react-spinbutton": "^9.2.51",
+        "@fluentui/react-spinner": "^9.3.29",
+        "@fluentui/react-switch": "^9.1.55",
+        "@fluentui/react-table": "^9.10.10",
+        "@fluentui/react-tabs": "^9.3.56",
+        "@fluentui/react-tabster": "^9.14.4",
+        "@fluentui/react-tags": "^9.0.9",
+        "@fluentui/react-text": "^9.3.46",
+        "@fluentui/react-textarea": "^9.3.51",
+        "@fluentui/react-theme": "^9.1.16",
+        "@fluentui/react-toast": "^9.3.16",
+        "@fluentui/react-toolbar": "^9.1.55",
+        "@fluentui/react-tooltip": "^9.3.21",
+        "@fluentui/react-tree": "^9.4.12",
+        "@fluentui/react-utilities": "^9.15.2",
+        "@fluentui/react-virtualizer": "9.0.0-alpha.56",
+        "@griffel/react": "^1.5.14",
+        "@swc/helpers": "^0.5.1"
+      },
+      "peerDependencies": {
+        "@types/react": ">=16.14.0 <19.0.0",
+        "@types/react-dom": ">=16.14.0 <19.0.0",
+        "react": ">=16.14.0 <19.0.0",
+        "react-dom": ">=16.14.0 <19.0.0",
+        "scheduler": "^0.19.0 || ^0.20.0"
+      }
+    },
+    "node_modules/@fluentui/react-context-selector": {
+      "version": "9.1.42",
+      "resolved": "https://registry.npmjs.org/@fluentui/react-context-selector/-/react-context-selector-9.1.42.tgz",
+      "integrity": "sha512-Xq9JcPBCRLkCnrUd83qSFgEYZc1BYyxFXLamtev5Ok1SSF53XI4yqN7Y34A13fSu/Q2wGeZibHcCTHJIXad2sQ==",
+      "dependencies": {
+        "@fluentui/react-utilities": "^9.15.2",
+        "@swc/helpers": "^0.5.1"
+      },
+      "peerDependencies": {
+        "@types/react": ">=16.14.0 <19.0.0",
+        "@types/react-dom": ">=16.14.0 <19.0.0",
+        "react": ">=16.14.0 <19.0.0",
+        "react-dom": ">=16.14.0 <19.0.0",
+        "scheduler": "^0.19.0 || ^0.20.0"
+      }
+    },
+    "node_modules/@fluentui/react-dialog": {
+      "version": "9.8.4",
+      "resolved": "https://registry.npmjs.org/@fluentui/react-dialog/-/react-dialog-9.8.4.tgz",
+      "integrity": "sha512-H8PNiYnsycpK5+I7rO/IhRn5hZImeAmdc7A9t9lNMGTIDELSTRS/aOOV7D8dENY0fegD6oNi4gLBM+k6WOAc6g==",
+      "dependencies": {
+        "@fluentui/keyboard-keys": "^9.0.7",
+        "@fluentui/react-aria": "^9.3.44",
+        "@fluentui/react-context-selector": "^9.1.42",
+        "@fluentui/react-icons": "^2.0.217",
+        "@fluentui/react-jsx-runtime": "^9.0.19",
+        "@fluentui/react-portal": "^9.4.0",
+        "@fluentui/react-shared-contexts": "^9.12.0",
+        "@fluentui/react-tabster": "^9.14.4",
+        "@fluentui/react-theme": "^9.1.16",
+        "@fluentui/react-utilities": "^9.15.2",
+        "@griffel/react": "^1.5.14",
+        "@swc/helpers": "^0.5.1",
+        "react-transition-group": "^4.4.1"
+      },
+      "peerDependencies": {
+        "@types/react": ">=16.14.0 <19.0.0",
+        "@types/react-dom": ">=16.14.0 <19.0.0",
+        "react": ">=16.14.0 <19.0.0",
+        "react-dom": ">=16.14.0 <19.0.0"
+      }
+    },
+    "node_modules/@fluentui/react-divider": {
+      "version": "9.2.49",
+      "resolved": "https://registry.npmjs.org/@fluentui/react-divider/-/react-divider-9.2.49.tgz",
+      "integrity": "sha512-XS0QWsbU0YHhZCtssYT3hT6825im8COcnSJ96KAj7rpffhlkOmpCdewNIQr/TyFrcLgfYg8jdKWO9QSmZpl1qg==",
+      "dependencies": {
+        "@fluentui/react-jsx-runtime": "^9.0.19",
+        "@fluentui/react-shared-contexts": "^9.12.0",
+        "@fluentui/react-theme": "^9.1.16",
+        "@fluentui/react-utilities": "^9.15.2",
+        "@griffel/react": "^1.5.14",
+        "@swc/helpers": "^0.5.1"
+      },
+      "peerDependencies": {
+        "@types/react": ">=16.14.0 <19.0.0",
+        "@types/react-dom": ">=16.14.0 <19.0.0",
+        "react": ">=16.14.0 <19.0.0",
+        "react-dom": ">=16.14.0 <19.0.0"
+      }
+    },
+    "node_modules/@fluentui/react-drawer": {
+      "version": "9.0.0",
+      "resolved": "https://registry.npmjs.org/@fluentui/react-drawer/-/react-drawer-9.0.0.tgz",
+      "integrity": "sha512-HWXtBwFQsDklhDiS3O5h2OokJ3B/kKMOXPHE8/vjELK4TsUDaV9gkr2IEHIlhx1OR7oo+N5wKmsbp+B7FNFspA==",
+      "dependencies": {
+        "@fluentui/react-dialog": "^9.8.4",
+        "@fluentui/react-jsx-runtime": "^9.0.19",
+        "@fluentui/react-motion-preview": "^0.5.1",
+        "@fluentui/react-shared-contexts": "^9.12.0",
+        "@fluentui/react-tabster": "^9.14.4",
+        "@fluentui/react-theme": "^9.1.16",
+        "@fluentui/react-utilities": "^9.15.2",
+        "@griffel/react": "^1.5.14",
+        "@swc/helpers": "^0.5.1"
+      },
+      "peerDependencies": {
+        "@types/react": ">=16.14.0 <19.0.0",
+        "@types/react-dom": ">=16.14.0 <19.0.0",
+        "react": ">=16.14.0 <19.0.0",
+        "react-dom": ">=16.14.0 <19.0.0"
+      }
+    },
+    "node_modules/@fluentui/react-field": {
+      "version": "9.1.41",
+      "resolved": "https://registry.npmjs.org/@fluentui/react-field/-/react-field-9.1.41.tgz",
+      "integrity": "sha512-0HmXM7HMAkabLuPDhlXKJjVg9hY5fGtgtrT1sVW3GgqiqYU+P5RYD67X4R28MSzrPvUVAc1tv9a3+UIQFF59QQ==",
+      "dependencies": {
+        "@fluentui/react-context-selector": "^9.1.42",
+        "@fluentui/react-icons": "^2.0.217",
+        "@fluentui/react-jsx-runtime": "^9.0.19",
+        "@fluentui/react-label": "^9.1.49",
+        "@fluentui/react-theme": "^9.1.16",
+        "@fluentui/react-utilities": "^9.15.2",
+        "@griffel/react": "^1.5.14",
+        "@swc/helpers": "^0.5.1"
+      },
+      "peerDependencies": {
+        "@types/react": ">=16.14.0 <19.0.0",
+        "@types/react-dom": ">=16.14.0 <19.0.0",
+        "react": ">=16.14.0 <19.0.0",
+        "react-dom": ">=16.14.0 <19.0.0"
+      }
+    },
+    "node_modules/@fluentui/react-focus": {
+      "version": "8.8.40",
+      "resolved": "https://registry.npmjs.org/@fluentui/react-focus/-/react-focus-8.8.40.tgz",
+      "integrity": "sha512-ha0CbLv5EIbjYCtQky6LVZObxOeMfhixrgrzfXm3Ta2eGs1NyZRDm1VeM6acOolWB/8QiN/CbdGckjALli8L2g==",
+      "dependencies": {
+        "@fluentui/keyboard-key": "^0.4.14",
+        "@fluentui/merge-styles": "^8.5.15",
+        "@fluentui/set-version": "^8.2.14",
+        "@fluentui/style-utilities": "^8.10.3",
+        "@fluentui/utilities": "^8.13.24",
+        "tslib": "^2.1.0"
+      },
+      "peerDependencies": {
+        "@types/react": ">=16.8.0 <19.0.0",
+        "react": ">=16.8.0 <19.0.0"
+      }
+    },
+    "node_modules/@fluentui/react-hooks": {
+      "version": "8.6.36",
+      "resolved": "https://registry.npmjs.org/@fluentui/react-hooks/-/react-hooks-8.6.36.tgz",
+      "integrity": "sha512-kI0Z4Q4xHUs4SOmmI5n5OH5fPckqMSCovTRpiuxzCO2TNzLmfC861+nqf4Ygw/ChqNm2gWNZZfUADfnNAEsq+Q==",
+      "dependencies": {
+        "@fluentui/react-window-provider": "^2.2.18",
+        "@fluentui/set-version": "^8.2.14",
+        "@fluentui/utilities": "^8.13.24",
+        "tslib": "^2.1.0"
+      },
+      "peerDependencies": {
+        "@types/react": ">=16.8.0 <19.0.0",
+        "react": ">=16.8.0 <19.0.0"
+      }
+    },
+    "node_modules/@fluentui/react-icons": {
+      "version": "2.0.222",
+      "resolved": "https://registry.npmjs.org/@fluentui/react-icons/-/react-icons-2.0.222.tgz",
+      "integrity": "sha512-3Qy9GPww9rj51mJ6iEGCqSBEDZ8qBK+FK0BdtcVF4LFxpnPbB45hEf2dZ6LBQbfuKgH8NB3QHRSky75DjrjfdA==",
+      "dependencies": {
+        "@griffel/react": "^1.0.0",
+        "tslib": "^2.1.0"
+      },
+      "peerDependencies": {
+        "react": ">=16.8.0 <19.0.0"
+      }
+    },
+    "node_modules/@fluentui/react-image": {
+      "version": "9.1.46",
+      "resolved": "https://registry.npmjs.org/@fluentui/react-image/-/react-image-9.1.46.tgz",
+      "integrity": "sha512-J7fOUyF+xNvdfBBCthmW2VV3LMCdD4kDa4TzjAbMT9a/gafeXWaY2+gcEPtuBQ5gLAKv5HDVlEtxTmK3Bj+OAA==",
+      "dependencies": {
+        "@fluentui/react-jsx-runtime": "^9.0.19",
+        "@fluentui/react-shared-contexts": "^9.12.0",
+        "@fluentui/react-theme": "^9.1.16",
+        "@fluentui/react-utilities": "^9.15.2",
+        "@griffel/react": "^1.5.14",
+        "@swc/helpers": "^0.5.1"
+      },
+      "peerDependencies": {
+        "@types/react": ">=16.14.0 <19.0.0",
+        "@types/react-dom": ">=16.14.0 <19.0.0",
+        "react": ">=16.14.0 <19.0.0",
+        "react-dom": ">=16.14.0 <19.0.0"
+      }
+    },
+    "node_modules/@fluentui/react-infobutton": {
+      "version": "9.0.0-beta.75",
+      "resolved": "https://registry.npmjs.org/@fluentui/react-infobutton/-/react-infobutton-9.0.0-beta.75.tgz",
+      "integrity": "sha512-axkJNnQGHpiOrrXOdJ9qrR9RNM626fYc4G/uUv9lgBp9NSD0ov15lFnzzjFWx34zTTfbmXZUVDzUEyzXd9g0xA==",
+      "dependencies": {
+        "@fluentui/react-icons": "^2.0.217",
+        "@fluentui/react-jsx-runtime": "^9.0.19",
+        "@fluentui/react-label": "^9.1.49",
+        "@fluentui/react-popover": "^9.8.20",
+        "@fluentui/react-tabster": "^9.14.4",
+        "@fluentui/react-theme": "^9.1.16",
+        "@fluentui/react-utilities": "^9.15.2",
+        "@griffel/react": "^1.5.14",
+        "@swc/helpers": "^0.5.1"
+      },
+      "peerDependencies": {
+        "@types/react": ">=16.14.0 <19.0.0",
+        "@types/react-dom": ">=16.14.0 <19.0.0",
+        "react": ">=16.14.0 <19.0.0",
+        "react-dom": ">=16.14.0 <19.0.0"
+      }
+    },
+    "node_modules/@fluentui/react-infolabel": {
+      "version": "9.0.3",
+      "resolved": "https://registry.npmjs.org/@fluentui/react-infolabel/-/react-infolabel-9.0.3.tgz",
+      "integrity": "sha512-lK0rV2tB4RAsqeHc0UuFnsPFfr/gcA0TfbcdWyBCtGsRIB5RLsIGM1o3t/p0SfT1s1N0AmYi9abh5Yfhgfs7sw==",
+      "dependencies": {
+        "@fluentui/react-icons": "^2.0.217",
+        "@fluentui/react-jsx-runtime": "^9.0.19",
+        "@fluentui/react-label": "^9.1.49",
+        "@fluentui/react-popover": "^9.8.20",
+        "@fluentui/react-tabster": "^9.14.4",
+        "@fluentui/react-theme": "^9.1.16",
+        "@fluentui/react-utilities": "^9.15.2",
+        "@griffel/react": "^1.5.14",
+        "@swc/helpers": "^0.5.1"
+      },
+      "peerDependencies": {
+        "@types/react": ">=16.8.0 <19.0.0",
+        "@types/react-dom": ">=16.8.0 <19.0.0",
+        "react": ">=16.8.0 <19.0.0",
+        "react-dom": ">=16.8.0 <19.0.0"
+      }
+    },
+    "node_modules/@fluentui/react-input": {
+      "version": "9.4.51",
+      "resolved": "https://registry.npmjs.org/@fluentui/react-input/-/react-input-9.4.51.tgz",
+      "integrity": "sha512-fdjU49z+qUNiOOpCMbV/sGyFJK2A5v53iIX26Ukxw/JLxXAaGnhCsKxkZgvx4PNyYRxWuYVwfkV0kUR2jjiN9Q==",
+      "dependencies": {
+        "@fluentui/react-field": "^9.1.41",
+        "@fluentui/react-jsx-runtime": "^9.0.19",
+        "@fluentui/react-shared-contexts": "^9.12.0",
+        "@fluentui/react-theme": "^9.1.16",
+        "@fluentui/react-utilities": "^9.15.2",
+        "@griffel/react": "^1.5.14",
+        "@swc/helpers": "^0.5.1"
+      },
+      "peerDependencies": {
+        "@types/react": ">=16.14.0 <19.0.0",
+        "@types/react-dom": ">=16.14.0 <19.0.0",
+        "react": ">=16.14.0 <19.0.0",
+        "react-dom": ">=16.14.0 <19.0.0"
+      }
+    },
+    "node_modules/@fluentui/react-jsx-runtime": {
+      "version": "9.0.19",
+      "resolved": "https://registry.npmjs.org/@fluentui/react-jsx-runtime/-/react-jsx-runtime-9.0.19.tgz",
+      "integrity": "sha512-aSz/H86hsJQTQ7CkxfH4BIiwDRzIuQs9XKNCiVHNzk6AX2cEeA12SM4NSeT5VmksM+D7vL6J0EBmUGDyX6bY5A==",
+      "dependencies": {
+        "@fluentui/react-utilities": "^9.15.2",
+        "@swc/helpers": "^0.5.1",
+        "react-is": "^17.0.2"
+      },
+      "peerDependencies": {
+        "@types/react": ">=16.14.0 <19.0.0",
+        "react": ">=16.14.0 <19.0.0"
+      }
+    },
+    "node_modules/@fluentui/react-jsx-runtime/node_modules/react-is": {
+      "version": "17.0.2",
+      "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
+      "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w=="
+    },
+    "node_modules/@fluentui/react-label": {
+      "version": "9.1.49",
+      "resolved": "https://registry.npmjs.org/@fluentui/react-label/-/react-label-9.1.49.tgz",
+      "integrity": "sha512-N8Wlork7ZfJIqiKxginAPy9TrX/ZbVU3DljWyw3cD9Y9u6HAaFeYBM7heRhLgJNByN/NxcArw54/l99hBka2bg==",
+      "dependencies": {
+        "@fluentui/react-jsx-runtime": "^9.0.19",
+        "@fluentui/react-shared-contexts": "^9.12.0",
+        "@fluentui/react-theme": "^9.1.16",
+        "@fluentui/react-utilities": "^9.15.2",
+        "@griffel/react": "^1.5.14",
+        "@swc/helpers": "^0.5.1"
+      },
+      "peerDependencies": {
+        "@types/react": ">=16.14.0 <19.0.0",
+        "@types/react-dom": ">=16.14.0 <19.0.0",
+        "react": ">=16.14.0 <19.0.0",
+        "react-dom": ">=16.14.0 <19.0.0"
+      }
+    },
+    "node_modules/@fluentui/react-link": {
+      "version": "9.1.33",
+      "resolved": "https://registry.npmjs.org/@fluentui/react-link/-/react-link-9.1.33.tgz",
+      "integrity": "sha512-MXXeyIrrawilx1+R25BzQV4zrWJ5PVIXrpPsFrmj9drkBvYBFceFhwjrzUxV1O51Q59Rpsh0I2Jz7rUwoGg8Qg==",
+      "dependencies": {
+        "@fluentui/keyboard-keys": "^9.0.7",
+        "@fluentui/react-jsx-runtime": "^9.0.19",
+        "@fluentui/react-shared-contexts": "^9.12.0",
+        "@fluentui/react-tabster": "^9.14.4",
+        "@fluentui/react-theme": "^9.1.16",
+        "@fluentui/react-utilities": "^9.15.2",
+        "@griffel/react": "^1.5.14",
+        "@swc/helpers": "^0.5.1"
+      },
+      "peerDependencies": {
+        "@types/react": ">=16.14.0 <19.0.0",
+        "@types/react-dom": ">=16.14.0 <19.0.0",
+        "react": ">=16.14.0 <19.0.0",
+        "react-dom": ">=16.14.0 <19.0.0"
+      }
+    },
+    "node_modules/@fluentui/react-menu": {
+      "version": "9.12.31",
+      "resolved": "https://registry.npmjs.org/@fluentui/react-menu/-/react-menu-9.12.31.tgz",
+      "integrity": "sha512-PiWj4w9KnUU6nD+XAqDZR5a+6VquxbyL/Z6vEH+3MfU1769dR2mj68dKfLBZWmQKteSWJvqx4ZBR1KZwsYcccA==",
+      "dependencies": {
+        "@fluentui/keyboard-keys": "^9.0.7",
+        "@fluentui/react-aria": "^9.3.44",
+        "@fluentui/react-context-selector": "^9.1.42",
+        "@fluentui/react-icons": "^2.0.217",
+        "@fluentui/react-jsx-runtime": "^9.0.19",
+        "@fluentui/react-portal": "^9.4.0",
+        "@fluentui/react-positioning": "^9.10.0",
+        "@fluentui/react-shared-contexts": "^9.12.0",
+        "@fluentui/react-tabster": "^9.14.4",
+        "@fluentui/react-theme": "^9.1.16",
+        "@fluentui/react-utilities": "^9.15.2",
+        "@griffel/react": "^1.5.14",
+        "@swc/helpers": "^0.5.1"
+      },
+      "peerDependencies": {
+        "@types/react": ">=16.14.0 <19.0.0",
+        "@types/react-dom": ">=16.14.0 <19.0.0",
+        "react": ">=16.14.0 <19.0.0",
+        "react-dom": ">=16.14.0 <19.0.0",
+        "scheduler": "^0.19.0 || ^0.20.0"
+      }
+    },
+    "node_modules/@fluentui/react-message-bar": {
+      "version": "9.0.5",
+      "resolved": "https://registry.npmjs.org/@fluentui/react-message-bar/-/react-message-bar-9.0.5.tgz",
+      "integrity": "sha512-0q+ROGpIhguGKC4hbopSB0QSA8oEZKgYom/GsqX57J+OZi3sbpp7zdihS+j9pvvuHT22kKh6ASZG24rNTFtrVg==",
+      "dependencies": {
+        "@fluentui/react-button": "^9.3.54",
+        "@fluentui/react-icons": "^2.0.217",
+        "@fluentui/react-jsx-runtime": "^9.0.19",
+        "@fluentui/react-shared-contexts": "^9.12.0",
+        "@fluentui/react-theme": "^9.1.16",
+        "@fluentui/react-utilities": "^9.15.2",
+        "@griffel/react": "^1.5.14",
+        "@swc/helpers": "^0.5.1",
+        "react-transition-group": "^4.4.1"
+      },
+      "peerDependencies": {
+        "@types/react": ">=16.8.0 <19.0.0",
+        "@types/react-dom": ">=16.8.0 <19.0.0",
+        "react": ">=16.8.0 <19.0.0",
+        "react-dom": ">=16.8.0 <19.0.0"
+      }
+    },
+    "node_modules/@fluentui/react-motion-preview": {
+      "version": "0.5.1",
+      "resolved": "https://registry.npmjs.org/@fluentui/react-motion-preview/-/react-motion-preview-0.5.1.tgz",
+      "integrity": "sha512-tg7q73/mXR0ZhlZPn5nATIDmefDMN02DEnfhAjcio2by0tma15OV/RNlbEsoqUR2xDu9BSjieSS8TIZTgjq3SQ==",
+      "dependencies": {
+        "@fluentui/react-jsx-runtime": "^9.0.19",
+        "@fluentui/react-shared-contexts": "^9.12.0",
+        "@fluentui/react-theme": "^9.1.16",
+        "@fluentui/react-utilities": "^9.15.2",
+        "@griffel/react": "^1.5.14",
+        "@swc/helpers": "^0.5.1"
+      },
+      "peerDependencies": {
+        "@types/react": ">=16.14.0 <19.0.0",
+        "@types/react-dom": ">=16.14.0 <19.0.0",
+        "react": ">=16.14.0 <19.0.0",
+        "react-dom": ">=16.14.0 <19.0.0"
+      }
+    },
+    "node_modules/@fluentui/react-overflow": {
+      "version": "9.0.43",
+      "resolved": "https://registry.npmjs.org/@fluentui/react-overflow/-/react-overflow-9.0.43.tgz",
+      "integrity": "sha512-YQDar2pw3WKpgK+gYg16l6Lsfz7HF4YLckOFlT4AujhrpdN6vEwDfw9Afj8/kSvJy5iGs0rqw8s4KokRWZArxA==",
+      "dependencies": {
+        "@fluentui/priority-overflow": "^9.1.9",
+        "@fluentui/react-context-selector": "^9.1.42",
+        "@fluentui/react-theme": "^9.1.16",
+        "@fluentui/react-utilities": "^9.15.2",
+        "@griffel/react": "^1.5.14",
+        "@swc/helpers": "^0.5.1"
+      },
+      "peerDependencies": {
+        "@types/react": ">=16.14.0 <19.0.0",
+        "@types/react-dom": ">=16.14.0 <19.0.0",
+        "react": ">=16.14.0 <19.0.0",
+        "react-dom": ">=16.14.0 <19.0.0",
+        "scheduler": "^0.19.0 || ^0.20.0"
+      }
+    },
+    "node_modules/@fluentui/react-persona": {
+      "version": "9.2.55",
+      "resolved": "https://registry.npmjs.org/@fluentui/react-persona/-/react-persona-9.2.55.tgz",
+      "integrity": "sha512-/CeY60wMXyZY67OPFuhHtli+ToDq2dWHPYGUIVqCWfAuLwvvWqbi8jPTlVOflGOWJJuomVeK/7iRb0gUJPobHg==",
+      "dependencies": {
+        "@fluentui/react-avatar": "^9.5.45",
+        "@fluentui/react-badge": "^9.2.13",
+        "@fluentui/react-jsx-runtime": "^9.0.19",
+        "@fluentui/react-shared-contexts": "^9.12.0",
+        "@fluentui/react-theme": "^9.1.16",
+        "@fluentui/react-utilities": "^9.15.2",
+        "@griffel/react": "^1.5.14",
+        "@swc/helpers": "^0.5.1"
+      },
+      "peerDependencies": {
+        "@types/react": ">=16.14.0 <19.0.0",
+        "@types/react-dom": ">=16.14.0 <19.0.0",
+        "react": ">=16.14.0 <19.0.0",
+        "react-dom": ">=16.14.0 <19.0.0"
+      }
+    },
+    "node_modules/@fluentui/react-popover": {
+      "version": "9.8.20",
+      "resolved": "https://registry.npmjs.org/@fluentui/react-popover/-/react-popover-9.8.20.tgz",
+      "integrity": "sha512-Pi69IIFSTIsEre//bQaHrPKGpN64E326MpCJ7b3QS4oyS0w/z3mv0ym893bLY4ktHbw6EZSWf+WchVJpfGYybA==",
+      "dependencies": {
+        "@fluentui/keyboard-keys": "^9.0.7",
+        "@fluentui/react-aria": "^9.3.44",
+        "@fluentui/react-context-selector": "^9.1.42",
+        "@fluentui/react-jsx-runtime": "^9.0.19",
+        "@fluentui/react-portal": "^9.4.0",
+        "@fluentui/react-positioning": "^9.10.0",
+        "@fluentui/react-shared-contexts": "^9.12.0",
+        "@fluentui/react-tabster": "^9.14.4",
+        "@fluentui/react-theme": "^9.1.16",
+        "@fluentui/react-utilities": "^9.15.2",
+        "@griffel/react": "^1.5.14",
+        "@swc/helpers": "^0.5.1"
+      },
+      "peerDependencies": {
+        "@types/react": ">=16.14.0 <19.0.0",
+        "@types/react-dom": ">=16.14.0 <19.0.0",
+        "react": ">=16.14.0 <19.0.0",
+        "react-dom": ">=16.14.0 <19.0.0",
+        "scheduler": "^0.19.0 || ^0.20.0"
+      }
+    },
+    "node_modules/@fluentui/react-portal": {
+      "version": "9.4.0",
+      "resolved": "https://registry.npmjs.org/@fluentui/react-portal/-/react-portal-9.4.0.tgz",
+      "integrity": "sha512-fiL8eFC7g9yurWEbfrpoFej9dv/cmIYWZcmNmvZL9jy6HsTnFS92mE31cKmFJErpqbsIxNFWK9TMs6zT8a4fTQ==",
+      "dependencies": {
+        "@fluentui/react-shared-contexts": "^9.12.0",
+        "@fluentui/react-tabster": "^9.14.4",
+        "@fluentui/react-utilities": "^9.15.2",
+        "@griffel/react": "^1.5.14",
+        "@swc/helpers": "^0.5.1",
+        "use-disposable": "^1.0.1"
+      },
+      "peerDependencies": {
+        "@types/react": ">=16.14.0 <19.0.0",
+        "@types/react-dom": ">=16.14.0 <19.0.0",
+        "react": ">=16.14.0 <19.0.0",
+        "react-dom": ">=16.14.0 <19.0.0"
+      }
+    },
+    "node_modules/@fluentui/react-portal-compat-context": {
+      "version": "9.0.11",
+      "resolved": "https://registry.npmjs.org/@fluentui/react-portal-compat-context/-/react-portal-compat-context-9.0.11.tgz",
+      "integrity": "sha512-ubvW/ej0O+Pago9GH3mPaxzUgsNnBoqvghNamWjyKvZIViyaXUG6+sgcAl721R+qGAFac+A20akI5qDJz/xtdg==",
+      "dependencies": {
+        "@swc/helpers": "^0.5.1"
+      },
+      "peerDependencies": {
+        "@types/react": ">=16.14.0 <19.0.0",
+        "react": ">=16.14.0 <19.0.0"
+      }
+    },
+    "node_modules/@fluentui/react-positioning": {
+      "version": "9.10.0",
+      "resolved": "https://registry.npmjs.org/@fluentui/react-positioning/-/react-positioning-9.10.0.tgz",
+      "integrity": "sha512-2k6e9AUi2yB2GPvgPSCQ42rG+yDkpAs2IfQpaO5ht4L/UxXyxEQUltcPJOQDiPE271WOfPI4rX201CLluHuNSQ==",
+      "dependencies": {
+        "@floating-ui/dom": "^1.2.0",
+        "@fluentui/react-shared-contexts": "^9.12.0",
+        "@fluentui/react-theme": "^9.1.16",
+        "@fluentui/react-utilities": "^9.15.2",
+        "@griffel/react": "^1.5.14",
+        "@swc/helpers": "^0.5.1"
+      },
+      "peerDependencies": {
+        "@types/react": ">=16.14.0 <19.0.0",
+        "@types/react-dom": ">=16.14.0 <19.0.0",
+        "react": ">=16.14.0 <19.0.0",
+        "react-dom": ">=16.14.0 <19.0.0"
+      }
+    },
+    "node_modules/@fluentui/react-progress": {
+      "version": "9.1.51",
+      "resolved": "https://registry.npmjs.org/@fluentui/react-progress/-/react-progress-9.1.51.tgz",
+      "integrity": "sha512-z2evxOKqgppbwrUajG4h0LbXax0sJ15t30gKtCzfY7TuvWqtmpImod6jOFyidWh9PLnNlNZeyJj2zQZ3VNPC6g==",
+      "dependencies": {
+        "@fluentui/react-field": "^9.1.41",
+        "@fluentui/react-jsx-runtime": "^9.0.19",
+        "@fluentui/react-shared-contexts": "^9.12.0",
+        "@fluentui/react-theme": "^9.1.16",
+        "@fluentui/react-utilities": "^9.15.2",
+        "@griffel/react": "^1.5.14",
+        "@swc/helpers": "^0.5.1"
+      },
+      "peerDependencies": {
+        "@types/react": ">=16.14.0 <19.0.0",
+        "@types/react-dom": ">=16.14.0 <19.0.0",
+        "react": ">=16.14.0 <19.0.0",
+        "react-dom": ">=16.14.0 <19.0.0"
+      }
+    },
+    "node_modules/@fluentui/react-provider": {
+      "version": "9.12.0",
+      "resolved": "https://registry.npmjs.org/@fluentui/react-provider/-/react-provider-9.12.0.tgz",
+      "integrity": "sha512-ocS0247BX7x9rUIozs0mMNGfDkjNIcFRq20cwPzpEUUHgKj/Dw0Ae1sXUORRUWG/z+/nalQx49ccqf6FcqmoYw==",
+      "dependencies": {
+        "@fluentui/react-icons": "^2.0.217",
+        "@fluentui/react-jsx-runtime": "^9.0.19",
+        "@fluentui/react-shared-contexts": "^9.12.0",
+        "@fluentui/react-tabster": "^9.14.4",
+        "@fluentui/react-theme": "^9.1.16",
+        "@fluentui/react-utilities": "^9.15.2",
+        "@griffel/core": "^1.14.1",
+        "@griffel/react": "^1.5.14",
+        "@swc/helpers": "^0.5.1"
+      },
+      "peerDependencies": {
+        "@types/react": ">=16.14.0 <19.0.0",
+        "@types/react-dom": ">=16.14.0 <19.0.0",
+        "react": ">=16.14.0 <19.0.0",
+        "react-dom": ">=16.14.0 <19.0.0"
+      }
+    },
+    "node_modules/@fluentui/react-radio": {
+      "version": "9.1.55",
+      "resolved": "https://registry.npmjs.org/@fluentui/react-radio/-/react-radio-9.1.55.tgz",
+      "integrity": "sha512-WxAtrpKwLjhSVQ796DeayJ3aAe4zVYXlGgWMyN9/zjNruve7jNrybMMUw6XPBwjw+Ycfk6P3r/rCasG2SphzOg==",
+      "dependencies": {
+        "@fluentui/react-field": "^9.1.41",
+        "@fluentui/react-icons": "^2.0.217",
+        "@fluentui/react-jsx-runtime": "^9.0.19",
+        "@fluentui/react-label": "^9.1.49",
+        "@fluentui/react-shared-contexts": "^9.12.0",
+        "@fluentui/react-tabster": "^9.14.4",
+        "@fluentui/react-theme": "^9.1.16",
+        "@fluentui/react-utilities": "^9.15.2",
+        "@griffel/react": "^1.5.14",
+        "@swc/helpers": "^0.5.1"
+      },
+      "peerDependencies": {
+        "@types/react": ">=16.14.0 <19.0.0",
+        "@types/react-dom": ">=16.14.0 <19.0.0",
+        "react": ">=16.14.0 <19.0.0",
+        "react-dom": ">=16.14.0 <19.0.0",
+        "scheduler": "^0.19.0 || ^0.20.0"
+      }
+    },
+    "node_modules/@fluentui/react-select": {
+      "version": "9.1.51",
+      "resolved": "https://registry.npmjs.org/@fluentui/react-select/-/react-select-9.1.51.tgz",
+      "integrity": "sha512-sUpfOM9Aj+N9cjPkW+LcmZW+FFk1asPMt8GiMP68szFwxcLwXkOb3rvG26v6C9fexGKpk4SA9giZ0iuaTnlsJA==",
+      "dependencies": {
+        "@fluentui/react-field": "^9.1.41",
+        "@fluentui/react-icons": "^2.0.217",
+        "@fluentui/react-jsx-runtime": "^9.0.19",
+        "@fluentui/react-shared-contexts": "^9.12.0",
+        "@fluentui/react-theme": "^9.1.16",
+        "@fluentui/react-utilities": "^9.15.2",
+        "@griffel/react": "^1.5.14",
+        "@swc/helpers": "^0.5.1"
+      },
+      "peerDependencies": {
+        "@types/react": ">=16.14.0 <19.0.0",
+        "@types/react-dom": ">=16.14.0 <19.0.0",
+        "react": ">=16.14.0 <19.0.0",
+        "react-dom": ">=16.14.0 <19.0.0"
+      }
+    },
+    "node_modules/@fluentui/react-shared-contexts": {
+      "version": "9.12.0",
+      "resolved": "https://registry.npmjs.org/@fluentui/react-shared-contexts/-/react-shared-contexts-9.12.0.tgz",
+      "integrity": "sha512-1HSFgrLB9631E4XXLemotfqTSxnKEZlcx+h7kDn2Q+GtK6dvpjaDtsnEPvC0aoCbXz7UTyCsl6OIPU+yjcfhyw==",
+      "dependencies": {
+        "@fluentui/react-theme": "^9.1.16",
+        "@swc/helpers": "^0.5.1"
+      },
+      "peerDependencies": {
+        "@types/react": ">=16.14.0 <19.0.0",
+        "react": ">=16.14.0 <19.0.0"
+      }
+    },
+    "node_modules/@fluentui/react-skeleton": {
+      "version": "9.0.39",
+      "resolved": "https://registry.npmjs.org/@fluentui/react-skeleton/-/react-skeleton-9.0.39.tgz",
+      "integrity": "sha512-O5oRgbEsR8mBck39rJJKPHDCUqYsko6mOpqMrcB196BBp2vcI6usrU1i5lJ3rN48KmiT7OMaeRotwwW32ep4/A==",
+      "dependencies": {
+        "@fluentui/react-field": "^9.1.41",
+        "@fluentui/react-jsx-runtime": "^9.0.19",
+        "@fluentui/react-shared-contexts": "^9.12.0",
+        "@fluentui/react-theme": "^9.1.16",
+        "@fluentui/react-utilities": "^9.15.2",
+        "@griffel/react": "^1.5.14",
+        "@swc/helpers": "^0.5.1"
+      },
+      "peerDependencies": {
+        "@types/react": ">=16.14.0 <19.0.0",
+        "@types/react-dom": ">=16.14.0 <19.0.0",
+        "react": ">=16.14.0 <19.0.0",
+        "react-dom": ">=16.14.0 <19.0.0"
+      }
+    },
+    "node_modules/@fluentui/react-slider": {
+      "version": "9.1.55",
+      "resolved": "https://registry.npmjs.org/@fluentui/react-slider/-/react-slider-9.1.55.tgz",
+      "integrity": "sha512-wgaOkVGlvEd/d5j9mDSI93zhmoYdnkgQy7S96CKPoPbA0N0MbOIApWz5uzQBu6X0mUfmI66jaafYrQ+u1vWwgA==",
+      "dependencies": {
+        "@fluentui/react-field": "^9.1.41",
+        "@fluentui/react-jsx-runtime": "^9.0.19",
+        "@fluentui/react-shared-contexts": "^9.12.0",
+        "@fluentui/react-tabster": "^9.14.4",
+        "@fluentui/react-theme": "^9.1.16",
+        "@fluentui/react-utilities": "^9.15.2",
+        "@griffel/react": "^1.5.14",
+        "@swc/helpers": "^0.5.1"
+      },
+      "peerDependencies": {
+        "@types/react": ">=16.14.0 <19.0.0",
+        "@types/react-dom": ">=16.14.0 <19.0.0",
+        "react": ">=16.14.0 <19.0.0",
+        "react-dom": ">=16.14.0 <19.0.0"
+      }
+    },
+    "node_modules/@fluentui/react-spinbutton": {
+      "version": "9.2.51",
+      "resolved": "https://registry.npmjs.org/@fluentui/react-spinbutton/-/react-spinbutton-9.2.51.tgz",
+      "integrity": "sha512-adlILeKAobCtLVaQpJY+PvJPsMaZVM9EIIMyi2s083XzgXUij6Xwa9c/89vyUO5f5P5HkYm+V12KqnOOoXzhBQ==",
+      "dependencies": {
+        "@fluentui/keyboard-keys": "^9.0.7",
+        "@fluentui/react-field": "^9.1.41",
+        "@fluentui/react-icons": "^2.0.217",
+        "@fluentui/react-jsx-runtime": "^9.0.19",
+        "@fluentui/react-shared-contexts": "^9.12.0",
+        "@fluentui/react-theme": "^9.1.16",
+        "@fluentui/react-utilities": "^9.15.2",
+        "@griffel/react": "^1.5.14",
+        "@swc/helpers": "^0.5.1"
+      },
+      "peerDependencies": {
+        "@types/react": ">=16.14.0 <19.0.0",
+        "@types/react-dom": ">=16.14.0 <19.0.0",
+        "react": ">=16.14.0 <19.0.0",
+        "react-dom": ">=16.14.0 <19.0.0"
+      }
+    },
+    "node_modules/@fluentui/react-spinner": {
+      "version": "9.3.29",
+      "resolved": "https://registry.npmjs.org/@fluentui/react-spinner/-/react-spinner-9.3.29.tgz",
+      "integrity": "sha512-oF4HsUrtyZxMXManIH0Q0+QtRf39aPq8bFc5umItsqi2uT+hom8fSc5yPPOgFAma3E+ioUxfFbM+dC3Zapzy2Q==",
+      "dependencies": {
+        "@fluentui/react-jsx-runtime": "^9.0.19",
+        "@fluentui/react-label": "^9.1.49",
+        "@fluentui/react-shared-contexts": "^9.12.0",
+        "@fluentui/react-theme": "^9.1.16",
+        "@fluentui/react-utilities": "^9.15.2",
+        "@griffel/react": "^1.5.14",
+        "@swc/helpers": "^0.5.1"
+      },
+      "peerDependencies": {
+        "@types/react": ">=16.14.0 <19.0.0",
+        "@types/react-dom": ">=16.14.0 <19.0.0",
+        "react": ">=16.14.0 <19.0.0",
+        "react-dom": ">=16.14.0 <19.0.0"
+      }
+    },
+    "node_modules/@fluentui/react-switch": {
+      "version": "9.1.55",
+      "resolved": "https://registry.npmjs.org/@fluentui/react-switch/-/react-switch-9.1.55.tgz",
+      "integrity": "sha512-gMi9Yv4DmVYsF+DJEjdoI5hEHH8nPpdUV8l2m0hjbV3IuBpMXD2RVAGeo/T6GMHtafk9v2PFsFEy2xBjcBOiDA==",
+      "dependencies": {
+        "@fluentui/react-field": "^9.1.41",
+        "@fluentui/react-icons": "^2.0.217",
+        "@fluentui/react-jsx-runtime": "^9.0.19",
+        "@fluentui/react-label": "^9.1.49",
+        "@fluentui/react-shared-contexts": "^9.12.0",
+        "@fluentui/react-tabster": "^9.14.4",
+        "@fluentui/react-theme": "^9.1.16",
+        "@fluentui/react-utilities": "^9.15.2",
+        "@griffel/react": "^1.5.14",
+        "@swc/helpers": "^0.5.1"
+      },
+      "peerDependencies": {
+        "@types/react": ">=16.14.0 <19.0.0",
+        "@types/react-dom": ">=16.14.0 <19.0.0",
+        "react": ">=16.14.0 <19.0.0",
+        "react-dom": ">=16.14.0 <19.0.0"
+      }
+    },
+    "node_modules/@fluentui/react-table": {
+      "version": "9.10.10",
+      "resolved": "https://registry.npmjs.org/@fluentui/react-table/-/react-table-9.10.10.tgz",
+      "integrity": "sha512-spnXKUJyPx8AC+IBSIVY+4T18Cbrk0nnRu38HcBaTnnaFv2z6lr1AiYbQ0Tyul42YiQBipSpl0mUML/kk0B0+A==",
+      "dependencies": {
+        "@fluentui/keyboard-keys": "^9.0.7",
+        "@fluentui/react-aria": "^9.3.44",
+        "@fluentui/react-avatar": "^9.5.45",
+        "@fluentui/react-checkbox": "^9.1.55",
+        "@fluentui/react-context-selector": "^9.1.42",
+        "@fluentui/react-icons": "^2.0.217",
+        "@fluentui/react-jsx-runtime": "^9.0.19",
+        "@fluentui/react-radio": "^9.1.55",
+        "@fluentui/react-shared-contexts": "^9.12.0",
+        "@fluentui/react-tabster": "^9.14.4",
+        "@fluentui/react-theme": "^9.1.16",
+        "@fluentui/react-utilities": "^9.15.2",
+        "@griffel/react": "^1.5.14",
+        "@swc/helpers": "^0.5.1"
+      },
+      "peerDependencies": {
+        "@types/react": ">=16.14.0 <19.0.0",
+        "@types/react-dom": ">=16.14.0 <19.0.0",
+        "react": ">=16.14.0 <19.0.0",
+        "react-dom": ">=16.14.0 <19.0.0"
+      }
+    },
+    "node_modules/@fluentui/react-tabs": {
+      "version": "9.3.56",
+      "resolved": "https://registry.npmjs.org/@fluentui/react-tabs/-/react-tabs-9.3.56.tgz",
+      "integrity": "sha512-5uaHdXV6pNSPnfpEhar6UjkoSaUNNJZEDxe5cBECC8IkvbC9lBkq6LdO5EB+Bdnul002dy4D0Aj0SGNI7DuqvQ==",
+      "dependencies": {
+        "@fluentui/react-context-selector": "^9.1.42",
+        "@fluentui/react-jsx-runtime": "^9.0.19",
+        "@fluentui/react-shared-contexts": "^9.12.0",
+        "@fluentui/react-tabster": "^9.14.4",
+        "@fluentui/react-theme": "^9.1.16",
+        "@fluentui/react-utilities": "^9.15.2",
+        "@griffel/react": "^1.5.14",
+        "@swc/helpers": "^0.5.1"
+      },
+      "peerDependencies": {
+        "@types/react": ">=16.14.0 <19.0.0",
+        "@types/react-dom": ">=16.14.0 <19.0.0",
+        "react": ">=16.14.0 <19.0.0",
+        "react-dom": ">=16.14.0 <19.0.0",
+        "scheduler": "^0.19.0 || ^0.20.0"
+      }
+    },
+    "node_modules/@fluentui/react-tabster": {
+      "version": "9.14.4",
+      "resolved": "https://registry.npmjs.org/@fluentui/react-tabster/-/react-tabster-9.14.4.tgz",
+      "integrity": "sha512-TVsYcVoonGuoO3naHwurrWx4WcQIAefGljb8VxzRnZb5MuGY6vLk3jlsuQWYWyO24o4YH2fk7n5oSW6ugA1MAA==",
+      "dependencies": {
+        "@fluentui/react-shared-contexts": "^9.12.0",
+        "@fluentui/react-theme": "^9.1.16",
+        "@fluentui/react-utilities": "^9.15.2",
+        "@griffel/react": "^1.5.14",
+        "@swc/helpers": "^0.5.1",
+        "keyborg": "^2.1.0",
+        "tabster": "^4.8.0"
+      },
+      "peerDependencies": {
+        "@types/react": ">=16.14.0 <19.0.0",
+        "@types/react-dom": ">=16.14.0 <19.0.0",
+        "react": ">=16.14.0 <19.0.0",
+        "react-dom": ">=16.14.0 <19.0.0"
+      }
+    },
+    "node_modules/@fluentui/react-tags": {
+      "version": "9.0.9",
+      "resolved": "https://registry.npmjs.org/@fluentui/react-tags/-/react-tags-9.0.9.tgz",
+      "integrity": "sha512-zKO8+q3hjMr7b+c934tYy5sKebiSviMwPjKcRZc9cb9XuuyQwgDzul7WvuSBfZnuR9u/gk+6o7TRkQxjcQcAew==",
+      "dependencies": {
+        "@fluentui/keyboard-keys": "^9.0.7",
+        "@fluentui/react-aria": "^9.3.44",
+        "@fluentui/react-avatar": "^9.5.45",
+        "@fluentui/react-icons": "^2.0.217",
+        "@fluentui/react-jsx-runtime": "^9.0.19",
+        "@fluentui/react-shared-contexts": "^9.12.0",
+        "@fluentui/react-tabster": "^9.14.4",
+        "@fluentui/react-theme": "^9.1.16",
+        "@fluentui/react-utilities": "^9.15.2",
+        "@griffel/react": "^1.5.14",
+        "@swc/helpers": "^0.5.1"
+      },
+      "peerDependencies": {
+        "@types/react": ">=16.14.0 <19.0.0",
+        "@types/react-dom": ">=16.14.0 <19.0.0",
+        "react": ">=16.14.0 <19.0.0",
+        "react-dom": ">=16.14.0 <19.0.0"
+      }
+    },
+    "node_modules/@fluentui/react-text": {
+      "version": "9.3.46",
+      "resolved": "https://registry.npmjs.org/@fluentui/react-text/-/react-text-9.3.46.tgz",
+      "integrity": "sha512-YrRxA3SCYn/NQj2BIesilXhjD8tFedYvJUjZUQMZD1Lm9ccFYnF/sI2WNz71Ta563rl0L9Ia2KMmNwD/XMZJoA==",
+      "dependencies": {
+        "@fluentui/react-jsx-runtime": "^9.0.19",
+        "@fluentui/react-shared-contexts": "^9.12.0",
+        "@fluentui/react-theme": "^9.1.16",
+        "@fluentui/react-utilities": "^9.15.2",
+        "@griffel/react": "^1.5.14",
+        "@swc/helpers": "^0.5.1"
+      },
+      "peerDependencies": {
+        "@types/react": ">=16.14.0 <19.0.0",
+        "@types/react-dom": ">=16.14.0 <19.0.0",
+        "react": ">=16.14.0 <19.0.0",
+        "react-dom": ">=16.14.0 <19.0.0"
+      }
+    },
+    "node_modules/@fluentui/react-textarea": {
+      "version": "9.3.51",
+      "resolved": "https://registry.npmjs.org/@fluentui/react-textarea/-/react-textarea-9.3.51.tgz",
+      "integrity": "sha512-FmPzQxwC4GLpke3uRdgNVnKHJRcrKpHLrmV2yyvcVwMEHn3OnH0QxMCMZhaDdedbAGAWO6Z2+kWfsdfTnrG99A==",
+      "dependencies": {
+        "@fluentui/react-field": "^9.1.41",
+        "@fluentui/react-jsx-runtime": "^9.0.19",
+        "@fluentui/react-shared-contexts": "^9.12.0",
+        "@fluentui/react-theme": "^9.1.16",
+        "@fluentui/react-utilities": "^9.15.2",
+        "@griffel/react": "^1.5.14",
+        "@swc/helpers": "^0.5.1"
+      },
+      "peerDependencies": {
+        "@types/react": ">=16.14.0 <19.0.0",
+        "@types/react-dom": ">=16.14.0 <19.0.0",
+        "react": ">=16.14.0 <19.0.0",
+        "react-dom": ">=16.14.0 <19.0.0"
+      }
+    },
+    "node_modules/@fluentui/react-theme": {
+      "version": "9.1.16",
+      "resolved": "https://registry.npmjs.org/@fluentui/react-theme/-/react-theme-9.1.16.tgz",
+      "integrity": "sha512-QK2dGE5aQXN1UGdiEmGKpYGP3tHXIchLvFf8DEEOWnF4XBc9SiEPNFYkvLMJjHxZmDz4D670rsOPe0r5jFDEKQ==",
+      "dependencies": {
+        "@fluentui/tokens": "1.0.0-alpha.13",
+        "@swc/helpers": "^0.5.1"
+      }
+    },
+    "node_modules/@fluentui/react-toast": {
+      "version": "9.3.16",
+      "resolved": "https://registry.npmjs.org/@fluentui/react-toast/-/react-toast-9.3.16.tgz",
+      "integrity": "sha512-NGU2oz4JgmX7MaglyKnYRY2pw7uKjQbPzQj0pxPFk1hMi7l30w46xJ24m74z01kqQYCCxl5hAjfICVIGIX07MQ==",
+      "dependencies": {
+        "@fluentui/keyboard-keys": "^9.0.7",
+        "@fluentui/react-aria": "^9.3.44",
+        "@fluentui/react-icons": "^2.0.217",
+        "@fluentui/react-jsx-runtime": "^9.0.19",
+        "@fluentui/react-portal": "^9.4.0",
+        "@fluentui/react-shared-contexts": "^9.12.0",
+        "@fluentui/react-tabster": "^9.14.4",
+        "@fluentui/react-theme": "^9.1.16",
+        "@fluentui/react-utilities": "^9.15.2",
+        "@griffel/react": "^1.5.14",
+        "@swc/helpers": "^0.5.1",
+        "react-transition-group": "^4.4.1"
+      },
+      "peerDependencies": {
+        "@types/react": ">=16.14.0 <19.0.0",
+        "@types/react-dom": ">=16.14.0 <19.0.0",
+        "react": ">=16.14.0 <19.0.0",
+        "react-dom": ">=16.14.0 <19.0.0"
+      }
+    },
+    "node_modules/@fluentui/react-toolbar": {
+      "version": "9.1.55",
+      "resolved": "https://registry.npmjs.org/@fluentui/react-toolbar/-/react-toolbar-9.1.55.tgz",
+      "integrity": "sha512-Z4MDjZ4pH8P/5ttR5UlZ++aC1MzGcIHNWVqdO4DUpPHEaneBxuRzAYlMQlZW/IZLDw7JEfFwQLIP0GscfTtWUw==",
+      "dependencies": {
+        "@fluentui/react-button": "^9.3.54",
+        "@fluentui/react-context-selector": "^9.1.42",
+        "@fluentui/react-divider": "^9.2.49",
+        "@fluentui/react-jsx-runtime": "^9.0.19",
+        "@fluentui/react-radio": "^9.1.55",
+        "@fluentui/react-shared-contexts": "^9.12.0",
+        "@fluentui/react-tabster": "^9.14.4",
+        "@fluentui/react-theme": "^9.1.16",
+        "@fluentui/react-utilities": "^9.15.2",
+        "@griffel/react": "^1.5.14",
+        "@swc/helpers": "^0.5.1"
+      },
+      "peerDependencies": {
+        "@types/react": ">=16.14.0 <19.0.0",
+        "@types/react-dom": ">=16.14.0 <19.0.0",
+        "react": ">=16.14.0 <19.0.0",
+        "react-dom": ">=16.14.0 <19.0.0"
+      }
+    },
+    "node_modules/@fluentui/react-tooltip": {
+      "version": "9.3.21",
+      "resolved": "https://registry.npmjs.org/@fluentui/react-tooltip/-/react-tooltip-9.3.21.tgz",
+      "integrity": "sha512-9y77imd0lBSO/xA2fzbBHA0FRf5MMda+p1B1xQKk7cRhhz6TzVX83y7bdf6ewcWBVuZxqDCFc3SELI1gOZxEKQ==",
+      "dependencies": {
+        "@fluentui/keyboard-keys": "^9.0.7",
+        "@fluentui/react-jsx-runtime": "^9.0.19",
+        "@fluentui/react-portal": "^9.4.0",
+        "@fluentui/react-positioning": "^9.10.0",
+        "@fluentui/react-shared-contexts": "^9.12.0",
+        "@fluentui/react-theme": "^9.1.16",
+        "@fluentui/react-utilities": "^9.15.2",
+        "@griffel/react": "^1.5.14",
+        "@swc/helpers": "^0.5.1"
+      },
+      "peerDependencies": {
+        "@types/react": ">=16.14.0 <19.0.0",
+        "@types/react-dom": ">=16.14.0 <19.0.0",
+        "react": ">=16.14.0 <19.0.0",
+        "react-dom": ">=16.14.0 <19.0.0"
+      }
+    },
+    "node_modules/@fluentui/react-tree": {
+      "version": "9.4.12",
+      "resolved": "https://registry.npmjs.org/@fluentui/react-tree/-/react-tree-9.4.12.tgz",
+      "integrity": "sha512-01hBhQIVOpUHudAU/RvMk0i0yWYLnnF5rFPy6KWUgIs068gU+MEMuUn9+nCM9au5UGpGcgqr2840dmibSCGi1Q==",
+      "dependencies": {
+        "@fluentui/keyboard-keys": "^9.0.7",
+        "@fluentui/react-aria": "^9.3.44",
+        "@fluentui/react-avatar": "^9.5.45",
+        "@fluentui/react-button": "^9.3.54",
+        "@fluentui/react-checkbox": "^9.1.55",
+        "@fluentui/react-context-selector": "^9.1.42",
+        "@fluentui/react-icons": "^2.0.217",
+        "@fluentui/react-jsx-runtime": "^9.0.19",
+        "@fluentui/react-radio": "^9.1.55",
+        "@fluentui/react-shared-contexts": "^9.12.0",
+        "@fluentui/react-tabster": "^9.14.4",
+        "@fluentui/react-theme": "^9.1.16",
+        "@fluentui/react-utilities": "^9.15.2",
+        "@griffel/react": "^1.5.14",
+        "@swc/helpers": "^0.5.1"
+      },
+      "peerDependencies": {
+        "@types/react": ">=16.14.0 <19.0.0",
+        "@types/react-dom": ">=16.14.0 <19.0.0",
+        "react": ">=16.14.0 <19.0.0",
+        "react-dom": ">=16.14.0 <19.0.0"
+      }
+    },
+    "node_modules/@fluentui/react-utilities": {
+      "version": "9.15.2",
+      "resolved": "https://registry.npmjs.org/@fluentui/react-utilities/-/react-utilities-9.15.2.tgz",
+      "integrity": "sha512-Oq016/dHu7PXW5x/2RtLts1ULiyd7JctXFdvi9IacLs/J1nLfg2KSBzzLqKxtdyVvgbZ9Mlu6kPITbFtF9dsIA==",
+      "dependencies": {
+        "@fluentui/keyboard-keys": "^9.0.7",
+        "@swc/helpers": "^0.5.1"
+      },
+      "peerDependencies": {
+        "@types/react": ">=16.14.0 <19.0.0",
+        "react": ">=16.14.0 <19.0.0"
+      }
+    },
+    "node_modules/@fluentui/react-virtualizer": {
+      "version": "9.0.0-alpha.56",
+      "resolved": "https://registry.npmjs.org/@fluentui/react-virtualizer/-/react-virtualizer-9.0.0-alpha.56.tgz",
+      "integrity": "sha512-IrJKFrpPO/uLA9dVUuzUEQ5LPHtlOHhykOKiGWWWUXsjJUSekTU17PL45fylaJmwsn4bDtWIFSNBW0FSQQrkLg==",
+      "dependencies": {
+        "@fluentui/react-jsx-runtime": "^9.0.19",
+        "@fluentui/react-shared-contexts": "^9.12.0",
+        "@fluentui/react-utilities": "^9.15.2",
+        "@griffel/react": "^1.5.14",
+        "@swc/helpers": "^0.5.1"
+      },
+      "peerDependencies": {
+        "@types/react": ">=16.14.0 <19.0.0",
+        "@types/react-dom": ">=16.14.0 <19.0.0",
+        "react": ">=16.14.0 <19.0.0",
+        "react-dom": ">=16.14.0 <19.0.0"
+      }
+    },
+    "node_modules/@fluentui/react-window-provider": {
+      "version": "2.2.18",
+      "resolved": "https://registry.npmjs.org/@fluentui/react-window-provider/-/react-window-provider-2.2.18.tgz",
+      "integrity": "sha512-nBKqxd0P8NmIR0qzFvka1urE2LVbUm6cse1I1T7TcOVNYa5jDf5BrO06+JRZfwbn00IJqOnIVoP0qONqceypWQ==",
+      "dependencies": {
+        "@fluentui/set-version": "^8.2.14",
+        "tslib": "^2.1.0"
+      },
+      "peerDependencies": {
+        "@types/react": ">=16.8.0 <19.0.0",
+        "react": ">=16.8.0 <19.0.0"
+      }
+    },
+    "node_modules/@fluentui/set-version": {
+      "version": "8.2.14",
+      "resolved": "https://registry.npmjs.org/@fluentui/set-version/-/set-version-8.2.14.tgz",
+      "integrity": "sha512-f/QWJnSeyfAjGAqq57yjMb6a5ejPlwfzdExPmzFBuEOuupi8hHbV8Yno12XJcTW4I0KXEQGw+PUaM1aOf/j7jw==",
+      "dependencies": {
+        "tslib": "^2.1.0"
+      }
+    },
+    "node_modules/@fluentui/style-utilities": {
+      "version": "8.10.3",
+      "resolved": "https://registry.npmjs.org/@fluentui/style-utilities/-/style-utilities-8.10.3.tgz",
+      "integrity": "sha512-pyO9BGkwIxXaIMVT6ma98GIZAgTjGc0LZ5iUai9GLIrFLQWnIKnS//hgUx8qG4AecUeqZ26Wb0e+Ale9NyPQCQ==",
+      "dependencies": {
+        "@fluentui/merge-styles": "^8.5.15",
+        "@fluentui/set-version": "^8.2.14",
+        "@fluentui/theme": "^2.6.41",
+        "@fluentui/utilities": "^8.13.24",
+        "@microsoft/load-themed-styles": "^1.10.26",
+        "tslib": "^2.1.0"
+      }
+    },
+    "node_modules/@fluentui/theme": {
+      "version": "2.6.41",
+      "resolved": "https://registry.npmjs.org/@fluentui/theme/-/theme-2.6.41.tgz",
+      "integrity": "sha512-h9RguEzqzJ0+59ys5Kkp7JtsjhDUxBLmQunu5rpHp5Mp788OtEjI/n1a9FIcOAL/priPSQwXN7RbuDpeP7+aSw==",
+      "dependencies": {
+        "@fluentui/merge-styles": "^8.5.15",
+        "@fluentui/set-version": "^8.2.14",
+        "@fluentui/utilities": "^8.13.24",
+        "tslib": "^2.1.0"
+      },
+      "peerDependencies": {
+        "@types/react": ">=16.8.0 <19.0.0",
+        "react": ">=16.8.0 <19.0.0"
+      }
+    },
+    "node_modules/@fluentui/tokens": {
+      "version": "1.0.0-alpha.13",
+      "resolved": "https://registry.npmjs.org/@fluentui/tokens/-/tokens-1.0.0-alpha.13.tgz",
+      "integrity": "sha512-IzYysTTBkAH7tQZxYKpzhxYnTJkvwXhjhTOpmERgnqTFifHTP8/vaQjJAAm7dI/9zlDx1oN+y/I+KzL9bDLHZQ==",
+      "dependencies": {
+        "@swc/helpers": "^0.5.1"
+      }
+    },
+    "node_modules/@fluentui/utilities": {
+      "version": "8.13.24",
+      "resolved": "https://registry.npmjs.org/@fluentui/utilities/-/utilities-8.13.24.tgz",
+      "integrity": "sha512-/jo6hWCzTGCx06l2baAMwsjjBZ/dyMouls53uNaQLUGUUhUwXh/DcDDXMqLRJB3MaH9zvgfvRw61iKmm2s9fIA==",
+      "dependencies": {
+        "@fluentui/dom-utilities": "^2.2.14",
+        "@fluentui/merge-styles": "^8.5.15",
+        "@fluentui/set-version": "^8.2.14",
+        "tslib": "^2.1.0"
+      },
+      "peerDependencies": {
+        "@types/react": ">=16.8.0 <19.0.0",
+        "react": ">=16.8.0 <19.0.0"
+      }
+    },
+    "node_modules/@griffel/core": {
+      "version": "1.15.0",
+      "resolved": "https://registry.npmjs.org/@griffel/core/-/core-1.15.0.tgz",
+      "integrity": "sha512-+2Li2x6zqQdVBSMbvGSJRxbMbOrXhCEEzX0BK6OMfjdMPJLoR2aaHuAwHL3J9dOpHzFrjp9MMEo4Jzwfo4l6Xw==",
+      "dependencies": {
+        "@emotion/hash": "^0.9.0",
+        "@griffel/style-types": "^1.0.2",
+        "csstype": "^3.1.2",
+        "rtl-css-js": "^1.16.1",
+        "stylis": "^4.2.0",
+        "tslib": "^2.1.0"
+      }
+    },
+    "node_modules/@griffel/react": {
+      "version": "1.5.18",
+      "resolved": "https://registry.npmjs.org/@griffel/react/-/react-1.5.18.tgz",
+      "integrity": "sha512-Y5L2zvfE+quMPSQPtViMmuDXNCIyJaeeQc5m30VMELgXYN0uk4nbFqwKYXG0FmnHkEHy5MhiGy7q4zCR2+ubTg==",
+      "dependencies": {
+        "@griffel/core": "^1.15.0",
+        "tslib": "^2.1.0"
+      },
+      "peerDependencies": {
+        "react": ">=16.8.0 <19.0.0"
+      }
+    },
+    "node_modules/@griffel/style-types": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/@griffel/style-types/-/style-types-1.0.2.tgz",
+      "integrity": "sha512-ka/Tpl1WU8js88LObwB/4EvpgXzx/EEJfbHhAr4ZNt29hrQKgL93X1zSY6M/FRhMhWrGIawauWkZP6/y6w/WiQ==",
+      "dependencies": {
+        "csstype": "^3.1.2"
+      }
+    },
+    "node_modules/@humanwhocodes/config-array": {
+      "version": "0.11.11",
+      "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.11.tgz",
+      "integrity": "sha512-N2brEuAadi0CcdeMXUkhbZB84eskAc8MEX1By6qEchoVywSgXPIjou4rYsl0V3Hj0ZnuGycGCjdNgockbzeWNA==",
+      "dev": true,
+      "dependencies": {
+        "@humanwhocodes/object-schema": "^1.2.1",
+        "debug": "^4.1.1",
+        "minimatch": "^3.0.5"
+      },
+      "engines": {
+        "node": ">=10.10.0"
+      }
+    },
+    "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": "1.2.1",
+      "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz",
+      "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==",
+      "dev": true
+    },
+    "node_modules/@jridgewell/gen-mapping": {
+      "version": "0.3.3",
+      "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz",
+      "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==",
+      "dev": true,
+      "dependencies": {
+        "@jridgewell/set-array": "^1.0.1",
+        "@jridgewell/sourcemap-codec": "^1.4.10",
+        "@jridgewell/trace-mapping": "^0.3.9"
+      },
+      "engines": {
+        "node": ">=6.0.0"
+      }
+    },
+    "node_modules/@jridgewell/resolve-uri": {
+      "version": "3.1.1",
+      "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz",
+      "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==",
+      "dev": true,
+      "engines": {
+        "node": ">=6.0.0"
+      }
+    },
+    "node_modules/@jridgewell/set-array": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz",
+      "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==",
+      "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==",
+      "dev": true
+    },
+    "node_modules/@jridgewell/trace-mapping": {
+      "version": "0.3.19",
+      "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.19.tgz",
+      "integrity": "sha512-kf37QtfW+Hwx/buWGMPcR60iF9ziHa6r/CZJIHbmcm4+0qrXiVdxegAH0F6yddEVQ7zdkjcGCgCzUu+BcbhQxw==",
+      "dev": true,
+      "dependencies": {
+        "@jridgewell/resolve-uri": "^3.1.0",
+        "@jridgewell/sourcemap-codec": "^1.4.14"
+      }
+    },
+    "node_modules/@microsoft/load-themed-styles": {
+      "version": "1.10.295",
+      "resolved": "https://registry.npmjs.org/@microsoft/load-themed-styles/-/load-themed-styles-1.10.295.tgz",
+      "integrity": "sha512-W+IzEBw8a6LOOfRJM02dTT7BDZijxm+Z7lhtOAz1+y9vQm1Kdz9jlAO+qCEKsfxtUOmKilW8DIRqFw2aUgKeGg=="
+    },
+    "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/@remix-run/router": {
+      "version": "1.9.0",
+      "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.9.0.tgz",
+      "integrity": "sha512-bV63itrKBC0zdT27qYm6SDZHlkXwFL1xMBuhkn+X7l0+IIhNaH5wuuvZKp6eKhCD4KFhujhfhCT1YxXW6esUIA==",
+      "engines": {
+        "node": ">=14.0.0"
+      }
+    },
+    "node_modules/@swc/helpers": {
+      "version": "0.5.3",
+      "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.3.tgz",
+      "integrity": "sha512-FaruWX6KdudYloq1AHD/4nU+UsMTdNE8CKyrseXWEcgjDAbvkwJg2QGPAnfIJLIWsjZOSPLOAykK6fuYp4vp4A==",
+      "dependencies": {
+        "tslib": "^2.4.0"
+      }
+    },
+    "node_modules/@types/babel__core": {
+      "version": "7.20.2",
+      "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.2.tgz",
+      "integrity": "sha512-pNpr1T1xLUc2l3xJKuPtsEky3ybxN3m4fJkknfIpTCTfIZCDW57oAg+EfCgIIp2rvCe0Wn++/FfodDS4YXxBwA==",
+      "dev": true,
+      "dependencies": {
+        "@babel/parser": "^7.20.7",
+        "@babel/types": "^7.20.7",
+        "@types/babel__generator": "*",
+        "@types/babel__template": "*",
+        "@types/babel__traverse": "*"
+      }
+    },
+    "node_modules/@types/babel__generator": {
+      "version": "7.6.5",
+      "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.5.tgz",
+      "integrity": "sha512-h9yIuWbJKdOPLJTbmSpPzkF67e659PbQDba7ifWm5BJ8xTv+sDmS7rFmywkWOvXedGTivCdeGSIIX8WLcRTz8w==",
+      "dev": true,
+      "dependencies": {
+        "@babel/types": "^7.0.0"
+      }
+    },
+    "node_modules/@types/babel__template": {
+      "version": "7.4.2",
+      "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.2.tgz",
+      "integrity": "sha512-/AVzPICMhMOMYoSx9MoKpGDKdBRsIXMNByh1PXSZoa+v6ZoLa8xxtsT/uLQ/NJm0XVAWl/BvId4MlDeXJaeIZQ==",
+      "dev": true,
+      "dependencies": {
+        "@babel/parser": "^7.1.0",
+        "@babel/types": "^7.0.0"
+      }
+    },
+    "node_modules/@types/babel__traverse": {
+      "version": "7.20.2",
+      "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.2.tgz",
+      "integrity": "sha512-ojlGK1Hsfce93J0+kn3H5R73elidKUaZonirN33GSmgTUMpzI/MIFfSpF3haANe3G1bEBS9/9/QEqwTzwqFsKw==",
+      "dev": true,
+      "dependencies": {
+        "@babel/types": "^7.20.7"
+      }
+    },
+    "node_modules/@types/debug": {
+      "version": "4.1.12",
+      "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz",
+      "integrity": "sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==",
+      "dependencies": {
+        "@types/ms": "*"
+      }
+    },
+    "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=="
+    },
+    "node_modules/@types/estree-jsx": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/@types/estree-jsx/-/estree-jsx-1.0.3.tgz",
+      "integrity": "sha512-pvQ+TKeRHeiUGRhvYwRrQ/ISnohKkSJR14fT2yqyZ4e9K5vqc7hrtY2Y1Dw0ZwAzQ6DQsxsaCUuSIIi8v0Cq6w==",
+      "dependencies": {
+        "@types/estree": "*"
+      }
+    },
+    "node_modules/@types/hast": {
+      "version": "3.0.3",
+      "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.3.tgz",
+      "integrity": "sha512-2fYGlaDy/qyLlhidX42wAH0KBi2TCjKMH8CHmBXgRlJ3Y+OXTiqsPQ6IWarZKwF1JoUcAJdPogv1d4b0COTpmQ==",
+      "dependencies": {
+        "@types/unist": "*"
+      }
+    },
+    "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/mdast": {
+      "version": "4.0.3",
+      "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.3.tgz",
+      "integrity": "sha512-LsjtqsyF+d2/yFOYaN22dHZI1Cpwkrj+g06G8+qtUKlhovPW89YhqSnfKtMbkgmEtYpH2gydRNULd6y8mciAFg==",
+      "dependencies": {
+        "@types/unist": "*"
+      }
+    },
+    "node_modules/@types/ms": {
+      "version": "0.7.34",
+      "resolved": "https://registry.npmjs.org/@types/ms/-/ms-0.7.34.tgz",
+      "integrity": "sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g=="
+    },
+    "node_modules/@types/prop-types": {
+      "version": "15.7.8",
+      "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.8.tgz",
+      "integrity": "sha512-kMpQpfZKSCBqltAJwskgePRaYRFukDkm1oItcAbC3gNELR20XIBcN9VRgg4+m8DKsTfkWeA4m4Imp4DDuWy7FQ=="
+    },
+    "node_modules/@types/react": {
+      "version": "18.2.27",
+      "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.27.tgz",
+      "integrity": "sha512-Wfv7B7FZiR2r3MIqbAlXoY1+tXm4bOqfz4oRr+nyXdBqapDBZ0l/IGcSlAfvxIHEEJjkPU0MYAc/BlFPOcrgLw==",
+      "dependencies": {
+        "@types/prop-types": "*",
+        "@types/scheduler": "*",
+        "csstype": "^3.0.2"
+      }
+    },
+    "node_modules/@types/react-dom": {
+      "version": "18.2.12",
+      "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.2.12.tgz",
+      "integrity": "sha512-QWZuiA/7J/hPIGocXreCRbx7wyoeet9ooxfbSA+zbIWqyQEE7GMtRn4A37BdYyksnN+/NDnWgfxZH9UVGDw1hg==",
+      "dependencies": {
+        "@types/react": "*"
+      }
+    },
+    "node_modules/@types/scheduler": {
+      "version": "0.16.4",
+      "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.4.tgz",
+      "integrity": "sha512-2L9ifAGl7wmXwP4v3pN4p2FLhD0O1qsJpvKmNin5VA8+UvNVb447UDaAEV6UdrkA+m/Xs58U1RFps44x6TFsVQ=="
+    },
+    "node_modules/@types/semver": {
+      "version": "7.5.5",
+      "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.5.tgz",
+      "integrity": "sha512-+d+WYC1BxJ6yVOgUgzK8gWvp5qF8ssV5r4nsDcZWKRWcDQLQ619tvWAxJQYGgBrO1MnLJC7a5GtiYsAoQ47dJg==",
+      "dev": true
+    },
+    "node_modules/@types/unist": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.2.tgz",
+      "integrity": "sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ=="
+    },
+    "node_modules/@typescript-eslint/eslint-plugin": {
+      "version": "6.10.0",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.10.0.tgz",
+      "integrity": "sha512-uoLj4g2OTL8rfUQVx2AFO1hp/zja1wABJq77P6IclQs6I/m9GLrm7jCdgzZkvWdDCQf1uEvoa8s8CupsgWQgVg==",
+      "dev": true,
+      "dependencies": {
+        "@eslint-community/regexpp": "^4.5.1",
+        "@typescript-eslint/scope-manager": "6.10.0",
+        "@typescript-eslint/type-utils": "6.10.0",
+        "@typescript-eslint/utils": "6.10.0",
+        "@typescript-eslint/visitor-keys": "6.10.0",
+        "debug": "^4.3.4",
+        "graphemer": "^1.4.0",
+        "ignore": "^5.2.4",
+        "natural-compare": "^1.4.0",
+        "semver": "^7.5.4",
+        "ts-api-utils": "^1.0.1"
+      },
+      "engines": {
+        "node": "^16.0.0 || >=18.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/typescript-eslint"
+      },
+      "peerDependencies": {
+        "@typescript-eslint/parser": "^6.0.0 || ^6.0.0-alpha",
+        "eslint": "^7.0.0 || ^8.0.0"
+      },
+      "peerDependenciesMeta": {
+        "typescript": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/@typescript-eslint/eslint-plugin/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/@typescript-eslint/eslint-plugin/node_modules/semver": {
+      "version": "7.5.4",
+      "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz",
+      "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==",
+      "dev": true,
+      "dependencies": {
+        "lru-cache": "^6.0.0"
+      },
+      "bin": {
+        "semver": "bin/semver.js"
+      },
+      "engines": {
+        "node": ">=10"
+      }
+    },
+    "node_modules/@typescript-eslint/eslint-plugin/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/@typescript-eslint/parser": {
+      "version": "6.10.0",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.10.0.tgz",
+      "integrity": "sha512-+sZwIj+s+io9ozSxIWbNB5873OSdfeBEH/FR0re14WLI6BaKuSOnnwCJ2foUiu8uXf4dRp1UqHP0vrZ1zXGrog==",
+      "dev": true,
+      "dependencies": {
+        "@typescript-eslint/scope-manager": "6.10.0",
+        "@typescript-eslint/types": "6.10.0",
+        "@typescript-eslint/typescript-estree": "6.10.0",
+        "@typescript-eslint/visitor-keys": "6.10.0",
+        "debug": "^4.3.4"
+      },
+      "engines": {
+        "node": "^16.0.0 || >=18.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/typescript-eslint"
+      },
+      "peerDependencies": {
+        "eslint": "^7.0.0 || ^8.0.0"
+      },
+      "peerDependenciesMeta": {
+        "typescript": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/@typescript-eslint/scope-manager": {
+      "version": "6.10.0",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.10.0.tgz",
+      "integrity": "sha512-TN/plV7dzqqC2iPNf1KrxozDgZs53Gfgg5ZHyw8erd6jd5Ta/JIEcdCheXFt9b1NYb93a1wmIIVW/2gLkombDg==",
+      "dev": true,
+      "dependencies": {
+        "@typescript-eslint/types": "6.10.0",
+        "@typescript-eslint/visitor-keys": "6.10.0"
+      },
+      "engines": {
+        "node": "^16.0.0 || >=18.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/typescript-eslint"
+      }
+    },
+    "node_modules/@typescript-eslint/type-utils": {
+      "version": "6.10.0",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.10.0.tgz",
+      "integrity": "sha512-wYpPs3hgTFblMYwbYWPT3eZtaDOjbLyIYuqpwuLBBqhLiuvJ+9sEp2gNRJEtR5N/c9G1uTtQQL5AhV0fEPJYcg==",
+      "dev": true,
+      "dependencies": {
+        "@typescript-eslint/typescript-estree": "6.10.0",
+        "@typescript-eslint/utils": "6.10.0",
+        "debug": "^4.3.4",
+        "ts-api-utils": "^1.0.1"
+      },
+      "engines": {
+        "node": "^16.0.0 || >=18.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/typescript-eslint"
+      },
+      "peerDependencies": {
+        "eslint": "^7.0.0 || ^8.0.0"
+      },
+      "peerDependenciesMeta": {
+        "typescript": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/@typescript-eslint/types": {
+      "version": "6.10.0",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.10.0.tgz",
+      "integrity": "sha512-36Fq1PWh9dusgo3vH7qmQAj5/AZqARky1Wi6WpINxB6SkQdY5vQoT2/7rW7uBIsPDcvvGCLi4r10p0OJ7ITAeg==",
+      "dev": true,
+      "engines": {
+        "node": "^16.0.0 || >=18.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/typescript-eslint"
+      }
+    },
+    "node_modules/@typescript-eslint/typescript-estree": {
+      "version": "6.10.0",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.10.0.tgz",
+      "integrity": "sha512-ek0Eyuy6P15LJVeghbWhSrBCj/vJpPXXR+EpaRZqou7achUWL8IdYnMSC5WHAeTWswYQuP2hAZgij/bC9fanBg==",
+      "dev": true,
+      "dependencies": {
+        "@typescript-eslint/types": "6.10.0",
+        "@typescript-eslint/visitor-keys": "6.10.0",
+        "debug": "^4.3.4",
+        "globby": "^11.1.0",
+        "is-glob": "^4.0.3",
+        "semver": "^7.5.4",
+        "ts-api-utils": "^1.0.1"
+      },
+      "engines": {
+        "node": "^16.0.0 || >=18.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/typescript-eslint"
+      },
+      "peerDependenciesMeta": {
+        "typescript": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/@typescript-eslint/typescript-estree/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/@typescript-eslint/typescript-estree/node_modules/semver": {
+      "version": "7.5.4",
+      "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz",
+      "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==",
+      "dev": true,
+      "dependencies": {
+        "lru-cache": "^6.0.0"
+      },
+      "bin": {
+        "semver": "bin/semver.js"
+      },
+      "engines": {
+        "node": ">=10"
+      }
+    },
+    "node_modules/@typescript-eslint/typescript-estree/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/@typescript-eslint/utils": {
+      "version": "6.10.0",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.10.0.tgz",
+      "integrity": "sha512-v+pJ1/RcVyRc0o4wAGux9x42RHmAjIGzPRo538Z8M1tVx6HOnoQBCX/NoadHQlZeC+QO2yr4nNSFWOoraZCAyg==",
+      "dev": true,
+      "dependencies": {
+        "@eslint-community/eslint-utils": "^4.4.0",
+        "@types/json-schema": "^7.0.12",
+        "@types/semver": "^7.5.0",
+        "@typescript-eslint/scope-manager": "6.10.0",
+        "@typescript-eslint/types": "6.10.0",
+        "@typescript-eslint/typescript-estree": "6.10.0",
+        "semver": "^7.5.4"
+      },
+      "engines": {
+        "node": "^16.0.0 || >=18.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/typescript-eslint"
+      },
+      "peerDependencies": {
+        "eslint": "^7.0.0 || ^8.0.0"
+      }
+    },
+    "node_modules/@typescript-eslint/utils/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/@typescript-eslint/utils/node_modules/semver": {
+      "version": "7.5.4",
+      "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz",
+      "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==",
+      "dev": true,
+      "dependencies": {
+        "lru-cache": "^6.0.0"
+      },
+      "bin": {
+        "semver": "bin/semver.js"
+      },
+      "engines": {
+        "node": ">=10"
+      }
+    },
+    "node_modules/@typescript-eslint/utils/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/@typescript-eslint/visitor-keys": {
+      "version": "6.10.0",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.10.0.tgz",
+      "integrity": "sha512-xMGluxQIEtOM7bqFCo+rCMh5fqI+ZxV5RUUOa29iVPz1OgCZrtc7rFnz5cLUazlkPKYqX+75iuDq7m0HQ48nCg==",
+      "dev": true,
+      "dependencies": {
+        "@typescript-eslint/types": "6.10.0",
+        "eslint-visitor-keys": "^3.4.1"
+      },
+      "engines": {
+        "node": "^16.0.0 || >=18.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=="
+    },
+    "node_modules/@vitejs/plugin-react": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-4.1.0.tgz",
+      "integrity": "sha512-rM0SqazU9iqPUraQ2JlIvReeaxOoRj6n+PzB1C0cBzIbd8qP336nC39/R9yPi3wVcah7E7j/kdU1uCUqMEU4OQ==",
+      "dev": true,
+      "dependencies": {
+        "@babel/core": "^7.22.20",
+        "@babel/plugin-transform-react-jsx-self": "^7.22.5",
+        "@babel/plugin-transform-react-jsx-source": "^7.22.5",
+        "@types/babel__core": "^7.20.2",
+        "react-refresh": "^0.14.0"
+      },
+      "engines": {
+        "node": "^14.18.0 || >=16.0.0"
+      },
+      "peerDependencies": {
+        "vite": "^4.2.0"
+      }
+    },
+    "node_modules/acorn": {
+      "version": "8.10.0",
+      "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz",
+      "integrity": "sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==",
+      "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/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/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": "3.2.1",
+      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+      "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+      "dev": true,
+      "dependencies": {
+        "color-convert": "^1.9.0"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "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-buffer-byte-length": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.0.tgz",
+      "integrity": "sha512-LPuwb2P+NrQw3XhxGc36+XSvuBPopovXYTR9Ew++Du9Yb/bx5AzBfrIsBoj0EZUifjQU+sHL21sseZ3jerWO/A==",
+      "dev": true,
+      "dependencies": {
+        "call-bind": "^1.0.2",
+        "is-array-buffer": "^3.0.1"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/array-includes": {
+      "version": "3.1.7",
+      "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.7.tgz",
+      "integrity": "sha512-dlcsNBIiWhPkHdOEEKnehA+RNUWDc4UqFtnIXU4uuYDPtA4LDkr7qip2p0VvFAEXNDr0yWZ9PJyIRiGjRLQzwQ==",
+      "dev": true,
+      "dependencies": {
+        "call-bind": "^1.0.2",
+        "define-properties": "^1.2.0",
+        "es-abstract": "^1.22.1",
+        "get-intrinsic": "^1.2.1",
+        "is-string": "^1.0.7"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "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/array.prototype.flat": {
+      "version": "1.3.2",
+      "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.2.tgz",
+      "integrity": "sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA==",
+      "dev": true,
+      "dependencies": {
+        "call-bind": "^1.0.2",
+        "define-properties": "^1.2.0",
+        "es-abstract": "^1.22.1",
+        "es-shim-unscopables": "^1.0.0"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/array.prototype.flatmap": {
+      "version": "1.3.2",
+      "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.2.tgz",
+      "integrity": "sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ==",
+      "dev": true,
+      "dependencies": {
+        "call-bind": "^1.0.2",
+        "define-properties": "^1.2.0",
+        "es-abstract": "^1.22.1",
+        "es-shim-unscopables": "^1.0.0"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/array.prototype.tosorted": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/array.prototype.tosorted/-/array.prototype.tosorted-1.1.2.tgz",
+      "integrity": "sha512-HuQCHOlk1Weat5jzStICBCd83NxiIMwqDg/dHEsoefabn/hJRj5pVdWcPUSpRrwhwxZOsQassMpgN/xRYFBMIg==",
+      "dev": true,
+      "dependencies": {
+        "call-bind": "^1.0.2",
+        "define-properties": "^1.2.0",
+        "es-abstract": "^1.22.1",
+        "es-shim-unscopables": "^1.0.0",
+        "get-intrinsic": "^1.2.1"
+      }
+    },
+    "node_modules/arraybuffer.prototype.slice": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.2.tgz",
+      "integrity": "sha512-yMBKppFur/fbHu9/6USUe03bZ4knMYiwFBcyiaXB8Go0qNehwX6inYPzK9U0NeQvGxKthcmHcaR8P5MStSRBAw==",
+      "dev": true,
+      "dependencies": {
+        "array-buffer-byte-length": "^1.0.0",
+        "call-bind": "^1.0.2",
+        "define-properties": "^1.2.0",
+        "es-abstract": "^1.22.1",
+        "get-intrinsic": "^1.2.1",
+        "is-array-buffer": "^3.0.2",
+        "is-shared-array-buffer": "^1.0.2"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/asynciterator.prototype": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/asynciterator.prototype/-/asynciterator.prototype-1.0.0.tgz",
+      "integrity": "sha512-wwHYEIS0Q80f5mosx3L/dfG5t5rjEa9Ft51GTaNt862EnpyGHpgz2RkZvLPp1oF5TnAiTohkEKVEu8pQPJI7Vg==",
+      "dev": true,
+      "dependencies": {
+        "has-symbols": "^1.0.3"
+      }
+    },
+    "node_modules/available-typed-arrays": {
+      "version": "1.0.5",
+      "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz",
+      "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==",
+      "dev": true,
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/bail": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.2.tgz",
+      "integrity": "sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==",
+      "funding": {
+        "type": "github",
+        "url": "https://github.com/sponsors/wooorm"
+      }
+    },
+    "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/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/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.22.1",
+      "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.22.1.tgz",
+      "integrity": "sha512-FEVc202+2iuClEhZhrWy6ZiAcRLvNMyYcxZ8raemul1DYVOVdFsbqckWLdsixQZCpJlwe77Z3UTalE7jsjnKfQ==",
+      "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.30001541",
+        "electron-to-chromium": "^1.4.535",
+        "node-releases": "^2.0.13",
+        "update-browserslist-db": "^1.0.13"
+      },
+      "bin": {
+        "browserslist": "cli.js"
+      },
+      "engines": {
+        "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7"
+      }
+    },
+    "node_modules/call-bind": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz",
+      "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==",
+      "dev": true,
+      "dependencies": {
+        "function-bind": "^1.1.1",
+        "get-intrinsic": "^1.0.2"
+      },
+      "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/caniuse-lite": {
+      "version": "1.0.30001547",
+      "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001547.tgz",
+      "integrity": "sha512-W7CrtIModMAxobGhz8iXmDfuJiiKg1WADMO/9x7/CLNin5cpSbuBjooyoIUVB5eyCc36QuTVlkVa1iB2S5+/eA==",
+      "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/ccount": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/ccount/-/ccount-2.0.1.tgz",
+      "integrity": "sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==",
+      "funding": {
+        "type": "github",
+        "url": "https://github.com/sponsors/wooorm"
+      }
+    },
+    "node_modules/chalk": {
+      "version": "2.4.2",
+      "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
+      "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
+      "dev": true,
+      "dependencies": {
+        "ansi-styles": "^3.2.1",
+        "escape-string-regexp": "^1.0.5",
+        "supports-color": "^5.3.0"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/character-entities": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-2.0.2.tgz",
+      "integrity": "sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==",
+      "funding": {
+        "type": "github",
+        "url": "https://github.com/sponsors/wooorm"
+      }
+    },
+    "node_modules/character-entities-html4": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/character-entities-html4/-/character-entities-html4-2.1.0.tgz",
+      "integrity": "sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==",
+      "funding": {
+        "type": "github",
+        "url": "https://github.com/sponsors/wooorm"
+      }
+    },
+    "node_modules/character-entities-legacy": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-3.0.0.tgz",
+      "integrity": "sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==",
+      "funding": {
+        "type": "github",
+        "url": "https://github.com/sponsors/wooorm"
+      }
+    },
+    "node_modules/character-reference-invalid": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-2.0.1.tgz",
+      "integrity": "sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw==",
+      "funding": {
+        "type": "github",
+        "url": "https://github.com/sponsors/wooorm"
+      }
+    },
+    "node_modules/color-convert": {
+      "version": "1.9.3",
+      "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
+      "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
+      "dev": true,
+      "dependencies": {
+        "color-name": "1.1.3"
+      }
+    },
+    "node_modules/color-name": {
+      "version": "1.1.3",
+      "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
+      "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==",
+      "dev": true
+    },
+    "node_modules/comma-separated-tokens": {
+      "version": "2.0.3",
+      "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-2.0.3.tgz",
+      "integrity": "sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==",
+      "funding": {
+        "type": "github",
+        "url": "https://github.com/sponsors/wooorm"
+      }
+    },
+    "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/convert-source-map": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz",
+      "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==",
+      "dev": true
+    },
+    "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/csstype": {
+      "version": "3.1.2",
+      "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.2.tgz",
+      "integrity": "sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ=="
+    },
+    "node_modules/dayjs": {
+      "version": "1.11.10",
+      "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.10.tgz",
+      "integrity": "sha512-vjAczensTgRcqDERK0SR2XMwsF/tSvnvlv6VcF2GIhg6Sx4yOIt/irsr1RDJsKiIyBzJDpCoXiWWq28MqH2cnQ=="
+    },
+    "node_modules/debug": {
+      "version": "4.3.4",
+      "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
+      "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
+      "dependencies": {
+        "ms": "2.1.2"
+      },
+      "engines": {
+        "node": ">=6.0"
+      },
+      "peerDependenciesMeta": {
+        "supports-color": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/decode-named-character-reference": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/decode-named-character-reference/-/decode-named-character-reference-1.0.2.tgz",
+      "integrity": "sha512-O8x12RzrUF8xyVcY0KJowWsmaJxQbmy0/EtnNtHRpsOcT7dFk5W598coHqBVpmWo1oQQfsCqfCmkZN5DJrZVdg==",
+      "dependencies": {
+        "character-entities": "^2.0.0"
+      },
+      "funding": {
+        "type": "github",
+        "url": "https://github.com/sponsors/wooorm"
+      }
+    },
+    "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.0",
+      "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.0.tgz",
+      "integrity": "sha512-UzGwzcjyv3OtAvolTj1GoyNYzfFR+iqbGjcnBEENZVCpM4/Ng1yhGNvS3lR/xDS74Tb2wGG9WzNSNIOS9UVb2g==",
+      "dev": true,
+      "dependencies": {
+        "get-intrinsic": "^1.2.1",
+        "gopd": "^1.0.1",
+        "has-property-descriptors": "^1.0.0"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
+    "node_modules/define-properties": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz",
+      "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==",
+      "dev": true,
+      "dependencies": {
+        "define-data-property": "^1.0.1",
+        "has-property-descriptors": "^1.0.0",
+        "object-keys": "^1.1.1"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/dequal": {
+      "version": "2.0.3",
+      "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz",
+      "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==",
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/devlop": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/devlop/-/devlop-1.1.0.tgz",
+      "integrity": "sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==",
+      "dependencies": {
+        "dequal": "^2.0.0"
+      },
+      "funding": {
+        "type": "github",
+        "url": "https://github.com/sponsors/wooorm"
+      }
+    },
+    "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/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/dom-helpers": {
+      "version": "5.2.1",
+      "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.2.1.tgz",
+      "integrity": "sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==",
+      "dependencies": {
+        "@babel/runtime": "^7.8.7",
+        "csstype": "^3.0.2"
+      }
+    },
+    "node_modules/electron-to-chromium": {
+      "version": "1.4.548",
+      "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.548.tgz",
+      "integrity": "sha512-R77KD6mXv37DOyKLN/eW1rGS61N6yHOfapNSX9w+y9DdPG83l9Gkuv7qkCFZ4Ta4JPhrjgQfYbv4Y3TnM1Hi2Q==",
+      "dev": true
+    },
+    "node_modules/es-abstract": {
+      "version": "1.22.2",
+      "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.22.2.tgz",
+      "integrity": "sha512-YoxfFcDmhjOgWPWsV13+2RNjq1F6UQnfs+8TftwNqtzlmFzEXvlUwdrNrYeaizfjQzRMxkZ6ElWMOJIFKdVqwA==",
+      "dev": true,
+      "dependencies": {
+        "array-buffer-byte-length": "^1.0.0",
+        "arraybuffer.prototype.slice": "^1.0.2",
+        "available-typed-arrays": "^1.0.5",
+        "call-bind": "^1.0.2",
+        "es-set-tostringtag": "^2.0.1",
+        "es-to-primitive": "^1.2.1",
+        "function.prototype.name": "^1.1.6",
+        "get-intrinsic": "^1.2.1",
+        "get-symbol-description": "^1.0.0",
+        "globalthis": "^1.0.3",
+        "gopd": "^1.0.1",
+        "has": "^1.0.3",
+        "has-property-descriptors": "^1.0.0",
+        "has-proto": "^1.0.1",
+        "has-symbols": "^1.0.3",
+        "internal-slot": "^1.0.5",
+        "is-array-buffer": "^3.0.2",
+        "is-callable": "^1.2.7",
+        "is-negative-zero": "^2.0.2",
+        "is-regex": "^1.1.4",
+        "is-shared-array-buffer": "^1.0.2",
+        "is-string": "^1.0.7",
+        "is-typed-array": "^1.1.12",
+        "is-weakref": "^1.0.2",
+        "object-inspect": "^1.12.3",
+        "object-keys": "^1.1.1",
+        "object.assign": "^4.1.4",
+        "regexp.prototype.flags": "^1.5.1",
+        "safe-array-concat": "^1.0.1",
+        "safe-regex-test": "^1.0.0",
+        "string.prototype.trim": "^1.2.8",
+        "string.prototype.trimend": "^1.0.7",
+        "string.prototype.trimstart": "^1.0.7",
+        "typed-array-buffer": "^1.0.0",
+        "typed-array-byte-length": "^1.0.0",
+        "typed-array-byte-offset": "^1.0.0",
+        "typed-array-length": "^1.0.4",
+        "unbox-primitive": "^1.0.2",
+        "which-typed-array": "^1.1.11"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/es-iterator-helpers": {
+      "version": "1.0.15",
+      "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.0.15.tgz",
+      "integrity": "sha512-GhoY8uYqd6iwUl2kgjTm4CZAf6oo5mHK7BPqx3rKgx893YSsy0LGHV6gfqqQvZt/8xM8xeOnfXBCfqclMKkJ5g==",
+      "dev": true,
+      "dependencies": {
+        "asynciterator.prototype": "^1.0.0",
+        "call-bind": "^1.0.2",
+        "define-properties": "^1.2.1",
+        "es-abstract": "^1.22.1",
+        "es-set-tostringtag": "^2.0.1",
+        "function-bind": "^1.1.1",
+        "get-intrinsic": "^1.2.1",
+        "globalthis": "^1.0.3",
+        "has-property-descriptors": "^1.0.0",
+        "has-proto": "^1.0.1",
+        "has-symbols": "^1.0.3",
+        "internal-slot": "^1.0.5",
+        "iterator.prototype": "^1.1.2",
+        "safe-array-concat": "^1.0.1"
+      }
+    },
+    "node_modules/es-set-tostringtag": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.1.tgz",
+      "integrity": "sha512-g3OMbtlwY3QewlqAiMLI47KywjWZoEytKr8pf6iTC8uJq5bIAH52Z9pnQ8pVL6whrCto53JZDuUIsifGeLorTg==",
+      "dev": true,
+      "dependencies": {
+        "get-intrinsic": "^1.1.3",
+        "has": "^1.0.3",
+        "has-tostringtag": "^1.0.0"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
+    "node_modules/es-shim-unscopables": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.0.tgz",
+      "integrity": "sha512-Jm6GPcCdC30eMLbZ2x8z2WuRwAws3zTBBKuusffYVUrNj/GVSUAZ+xKMaUpfNDR5IbyNA5LJbaecoUVbmUcB1w==",
+      "dev": true,
+      "dependencies": {
+        "has": "^1.0.3"
+      }
+    },
+    "node_modules/es-to-primitive": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz",
+      "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==",
+      "dev": true,
+      "dependencies": {
+        "is-callable": "^1.1.4",
+        "is-date-object": "^1.0.1",
+        "is-symbol": "^1.0.2"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/esbuild": {
+      "version": "0.18.20",
+      "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.20.tgz",
+      "integrity": "sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==",
+      "dev": true,
+      "hasInstallScript": true,
+      "bin": {
+        "esbuild": "bin/esbuild"
+      },
+      "engines": {
+        "node": ">=12"
+      },
+      "optionalDependencies": {
+        "@esbuild/android-arm": "0.18.20",
+        "@esbuild/android-arm64": "0.18.20",
+        "@esbuild/android-x64": "0.18.20",
+        "@esbuild/darwin-arm64": "0.18.20",
+        "@esbuild/darwin-x64": "0.18.20",
+        "@esbuild/freebsd-arm64": "0.18.20",
+        "@esbuild/freebsd-x64": "0.18.20",
+        "@esbuild/linux-arm": "0.18.20",
+        "@esbuild/linux-arm64": "0.18.20",
+        "@esbuild/linux-ia32": "0.18.20",
+        "@esbuild/linux-loong64": "0.18.20",
+        "@esbuild/linux-mips64el": "0.18.20",
+        "@esbuild/linux-ppc64": "0.18.20",
+        "@esbuild/linux-riscv64": "0.18.20",
+        "@esbuild/linux-s390x": "0.18.20",
+        "@esbuild/linux-x64": "0.18.20",
+        "@esbuild/netbsd-x64": "0.18.20",
+        "@esbuild/openbsd-x64": "0.18.20",
+        "@esbuild/sunos-x64": "0.18.20",
+        "@esbuild/win32-arm64": "0.18.20",
+        "@esbuild/win32-ia32": "0.18.20",
+        "@esbuild/win32-x64": "0.18.20"
+      }
+    },
+    "node_modules/escalade": {
+      "version": "3.1.1",
+      "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz",
+      "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==",
+      "dev": true,
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "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/eslint": {
+      "version": "8.51.0",
+      "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.51.0.tgz",
+      "integrity": "sha512-2WuxRZBrlwnXi+/vFSJyjMqrNjtJqiasMzehF0shoLaW7DzS3/9Yvrmq5JiT66+pNjiX4UBnLDiKHcWAr/OInA==",
+      "dev": true,
+      "dependencies": {
+        "@eslint-community/eslint-utils": "^4.2.0",
+        "@eslint-community/regexpp": "^4.6.1",
+        "@eslint/eslintrc": "^2.1.2",
+        "@eslint/js": "8.51.0",
+        "@humanwhocodes/config-array": "^0.11.11",
+        "@humanwhocodes/module-importer": "^1.0.1",
+        "@nodelib/fs.walk": "^1.2.8",
+        "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-plugin-react": {
+      "version": "7.33.2",
+      "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.33.2.tgz",
+      "integrity": "sha512-73QQMKALArI8/7xGLNI/3LylrEYrlKZSb5C9+q3OtOewTnMQi5cT+aE9E41sLCmli3I9PGGmD1yiZydyo4FEPw==",
+      "dev": true,
+      "dependencies": {
+        "array-includes": "^3.1.6",
+        "array.prototype.flatmap": "^1.3.1",
+        "array.prototype.tosorted": "^1.1.1",
+        "doctrine": "^2.1.0",
+        "es-iterator-helpers": "^1.0.12",
+        "estraverse": "^5.3.0",
+        "jsx-ast-utils": "^2.4.1 || ^3.0.0",
+        "minimatch": "^3.1.2",
+        "object.entries": "^1.1.6",
+        "object.fromentries": "^2.0.6",
+        "object.hasown": "^1.1.2",
+        "object.values": "^1.1.6",
+        "prop-types": "^15.8.1",
+        "resolve": "^2.0.0-next.4",
+        "semver": "^6.3.1",
+        "string.prototype.matchall": "^4.0.8"
+      },
+      "engines": {
+        "node": ">=4"
+      },
+      "peerDependencies": {
+        "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8"
+      }
+    },
+    "node_modules/eslint-plugin-react-hooks": {
+      "version": "4.6.0",
+      "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.6.0.tgz",
+      "integrity": "sha512-oFc7Itz9Qxh2x4gNHStv3BqJq54ExXmfC+a1NjAta66IAN87Wu0R/QArgIS9qKzX3dXKPI9H5crl9QchNMY9+g==",
+      "dev": true,
+      "engines": {
+        "node": ">=10"
+      },
+      "peerDependencies": {
+        "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0"
+      }
+    },
+    "node_modules/eslint-plugin-react-refresh": {
+      "version": "0.4.3",
+      "resolved": "https://registry.npmjs.org/eslint-plugin-react-refresh/-/eslint-plugin-react-refresh-0.4.3.tgz",
+      "integrity": "sha512-Hh0wv8bUNY877+sI0BlCUlsS0TYYQqvzEwJsJJPM2WF4RnTStSnSR3zdJYa2nPOJgg3UghXi54lVyMSmpCalzA==",
+      "dev": true,
+      "peerDependencies": {
+        "eslint": ">=7"
+      }
+    },
+    "node_modules/eslint-plugin-react/node_modules/doctrine": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz",
+      "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==",
+      "dev": true,
+      "dependencies": {
+        "esutils": "^2.0.2"
+      },
+      "engines": {
+        "node": ">=0.10.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/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/eslint/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/eslint/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/eslint/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/eslint/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/node_modules/globals": {
+      "version": "13.23.0",
+      "resolved": "https://registry.npmjs.org/globals/-/globals-13.23.0.tgz",
+      "integrity": "sha512-XAmF0RjlrjY23MA51q3HltdlGxUpXPvg0GioKiD9X6HD28iMjo2dKC8Vqwm7lne4GNr78+RHTfliktR6ZH09wA==",
+      "dev": true,
+      "dependencies": {
+        "type-fest": "^0.20.2"
+      },
+      "engines": {
+        "node": ">=8"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/eslint/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/eslint/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/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-util-is-identifier-name": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/estree-util-is-identifier-name/-/estree-util-is-identifier-name-3.0.0.tgz",
+      "integrity": "sha512-hFtqIDZTIUZ9BXLb8y4pYGyk6+wekIivNVTcmvk8NoOh+VeRn5y6cEHzbURrWbfp1fIqdVipilzj+lfaadNZmg==",
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/unified"
+      }
+    },
+    "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/extend": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
+      "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g=="
+    },
+    "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-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.15.0",
+      "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz",
+      "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==",
+      "dev": true,
+      "dependencies": {
+        "reusify": "^1.0.4"
+      }
+    },
+    "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.1.1",
+      "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.1.1.tgz",
+      "integrity": "sha512-/qM2b3LUIaIgviBQovTLvijfyOQXPtSRnRK26ksj2J7rzPIecePUIpJsZ4T02Qg+xiAEKIs5K8dsHEd+VaKa/Q==",
+      "dev": true,
+      "dependencies": {
+        "flatted": "^3.2.9",
+        "keyv": "^4.5.3",
+        "rimraf": "^3.0.2"
+      },
+      "engines": {
+        "node": ">=12.0.0"
+      }
+    },
+    "node_modules/flatted": {
+      "version": "3.2.9",
+      "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.9.tgz",
+      "integrity": "sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ==",
+      "dev": true
+    },
+    "node_modules/for-each": {
+      "version": "0.3.3",
+      "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz",
+      "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==",
+      "dev": true,
+      "dependencies": {
+        "is-callable": "^1.1.3"
+      }
+    },
+    "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.1",
+      "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
+      "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==",
+      "dev": true
+    },
+    "node_modules/function.prototype.name": {
+      "version": "1.1.6",
+      "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.6.tgz",
+      "integrity": "sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==",
+      "dev": true,
+      "dependencies": {
+        "call-bind": "^1.0.2",
+        "define-properties": "^1.2.0",
+        "es-abstract": "^1.22.1",
+        "functions-have-names": "^1.2.3"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/functions-have-names": {
+      "version": "1.2.3",
+      "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz",
+      "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==",
+      "dev": true,
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/gensync": {
+      "version": "1.0.0-beta.2",
+      "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz",
+      "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==",
+      "dev": true,
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/get-intrinsic": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.1.tgz",
+      "integrity": "sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw==",
+      "dev": true,
+      "dependencies": {
+        "function-bind": "^1.1.1",
+        "has": "^1.0.3",
+        "has-proto": "^1.0.1",
+        "has-symbols": "^1.0.3"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/get-symbol-description": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz",
+      "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==",
+      "dev": true,
+      "dependencies": {
+        "call-bind": "^1.0.2",
+        "get-intrinsic": "^1.1.1"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "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/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/globals": {
+      "version": "11.12.0",
+      "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz",
+      "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==",
+      "dev": true,
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/globalthis": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.3.tgz",
+      "integrity": "sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==",
+      "dev": true,
+      "dependencies": {
+        "define-properties": "^1.1.3"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "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/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": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/has/-/has-1.0.4.tgz",
+      "integrity": "sha512-qdSAmqLF6209RFj4VVItywPMbm3vWylknmB3nvNiUIs72xAimcM8nVYxYr7ncvZq5qzk9MKIZR8ijqD/1QuYjQ==",
+      "dev": true,
+      "engines": {
+        "node": ">= 0.4.0"
+      }
+    },
+    "node_modules/has-bigints": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz",
+      "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==",
+      "dev": true,
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/has-flag": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
+      "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
+      "dev": true,
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/has-property-descriptors": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz",
+      "integrity": "sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==",
+      "dev": true,
+      "dependencies": {
+        "get-intrinsic": "^1.1.1"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/has-proto": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz",
+      "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==",
+      "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/has-tostringtag": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz",
+      "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==",
+      "dev": true,
+      "dependencies": {
+        "has-symbols": "^1.0.2"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/hast-util-to-jsx-runtime": {
+      "version": "2.3.0",
+      "resolved": "https://registry.npmjs.org/hast-util-to-jsx-runtime/-/hast-util-to-jsx-runtime-2.3.0.tgz",
+      "integrity": "sha512-H/y0+IWPdsLLS738P8tDnrQ8Z+dj12zQQ6WC11TIM21C8WFVoIxcqWXf2H3hiTVZjF1AWqoimGwrTWecWrnmRQ==",
+      "dependencies": {
+        "@types/estree": "^1.0.0",
+        "@types/hast": "^3.0.0",
+        "@types/unist": "^3.0.0",
+        "comma-separated-tokens": "^2.0.0",
+        "devlop": "^1.0.0",
+        "estree-util-is-identifier-name": "^3.0.0",
+        "hast-util-whitespace": "^3.0.0",
+        "mdast-util-mdx-expression": "^2.0.0",
+        "mdast-util-mdx-jsx": "^3.0.0",
+        "mdast-util-mdxjs-esm": "^2.0.0",
+        "property-information": "^6.0.0",
+        "space-separated-tokens": "^2.0.0",
+        "style-to-object": "^1.0.0",
+        "unist-util-position": "^5.0.0",
+        "vfile-message": "^4.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/unified"
+      }
+    },
+    "node_modules/hast-util-whitespace": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/hast-util-whitespace/-/hast-util-whitespace-3.0.0.tgz",
+      "integrity": "sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==",
+      "dependencies": {
+        "@types/hast": "^3.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/unified"
+      }
+    },
+    "node_modules/html-url-attributes": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/html-url-attributes/-/html-url-attributes-3.0.0.tgz",
+      "integrity": "sha512-/sXbVCWayk6GDVg3ctOX6nxaVj7So40FcFAnWlWGNAB1LpYKcV5Cd10APjPjW80O7zYW2MsjBV4zZ7IZO5fVow==",
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/unified"
+      }
+    },
+    "node_modules/ignore": {
+      "version": "5.2.4",
+      "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz",
+      "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==",
+      "dev": true,
+      "engines": {
+        "node": ">= 4"
+      }
+    },
+    "node_modules/immediate": {
+      "version": "3.0.6",
+      "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz",
+      "integrity": "sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ=="
+    },
+    "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/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/inline-style-parser": {
+      "version": "0.2.2",
+      "resolved": "https://registry.npmjs.org/inline-style-parser/-/inline-style-parser-0.2.2.tgz",
+      "integrity": "sha512-EcKzdTHVe8wFVOGEYXiW9WmJXPjqi1T+234YpJr98RiFYKHV3cdy1+3mkTE+KHTHxFFLH51SfaGOoUdW+v7ViQ=="
+    },
+    "node_modules/internal-slot": {
+      "version": "1.0.5",
+      "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.5.tgz",
+      "integrity": "sha512-Y+R5hJrzs52QCG2laLn4udYVnxsfny9CpOhNhUvk/SSSVyF6T27FzRbF0sroPidSu3X8oEAkOn2K804mjpt6UQ==",
+      "dev": true,
+      "dependencies": {
+        "get-intrinsic": "^1.2.0",
+        "has": "^1.0.3",
+        "side-channel": "^1.0.4"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
+    "node_modules/is-alphabetical": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-2.0.1.tgz",
+      "integrity": "sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ==",
+      "funding": {
+        "type": "github",
+        "url": "https://github.com/sponsors/wooorm"
+      }
+    },
+    "node_modules/is-alphanumerical": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-2.0.1.tgz",
+      "integrity": "sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw==",
+      "dependencies": {
+        "is-alphabetical": "^2.0.0",
+        "is-decimal": "^2.0.0"
+      },
+      "funding": {
+        "type": "github",
+        "url": "https://github.com/sponsors/wooorm"
+      }
+    },
+    "node_modules/is-array-buffer": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.2.tgz",
+      "integrity": "sha512-y+FyyR/w8vfIRq4eQcM1EYgSTnmHXPqaF+IgzgraytCFq5Xh8lllDVmAZolPJiZttZLeFSINPYMaEJ7/vWUa1w==",
+      "dev": true,
+      "dependencies": {
+        "call-bind": "^1.0.2",
+        "get-intrinsic": "^1.2.0",
+        "is-typed-array": "^1.1.10"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/is-async-function": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/is-async-function/-/is-async-function-2.0.0.tgz",
+      "integrity": "sha512-Y1JXKrfykRJGdlDwdKlLpLyMIiWqWvuSd17TvZk68PLAOGOoF4Xyav1z0Xhoi+gCYjZVeC5SI+hYFOfvXmGRCA==",
+      "dev": true,
+      "dependencies": {
+        "has-tostringtag": "^1.0.0"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/is-bigint": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz",
+      "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==",
+      "dev": true,
+      "dependencies": {
+        "has-bigints": "^1.0.1"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/is-boolean-object": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz",
+      "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==",
+      "dev": true,
+      "dependencies": {
+        "call-bind": "^1.0.2",
+        "has-tostringtag": "^1.0.0"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/is-callable": {
+      "version": "1.2.7",
+      "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz",
+      "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==",
+      "dev": true,
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/is-core-module": {
+      "version": "2.13.0",
+      "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.0.tgz",
+      "integrity": "sha512-Z7dk6Qo8pOCp3l4tsX2C5ZVas4V+UxwQodwZhLopL91TX8UyyHEXafPcyoeeWuLrwzHcr3igO78wNLwHJHsMCQ==",
+      "dev": true,
+      "dependencies": {
+        "has": "^1.0.3"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/is-date-object": {
+      "version": "1.0.5",
+      "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz",
+      "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==",
+      "dev": true,
+      "dependencies": {
+        "has-tostringtag": "^1.0.0"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/is-decimal": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-2.0.1.tgz",
+      "integrity": "sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A==",
+      "funding": {
+        "type": "github",
+        "url": "https://github.com/sponsors/wooorm"
+      }
+    },
+    "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-finalizationregistry": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/is-finalizationregistry/-/is-finalizationregistry-1.0.2.tgz",
+      "integrity": "sha512-0by5vtUJs8iFQb5TYUHHPudOR+qXYIMKtiUzvLIZITZUjknFmziyBJuLhVRc+Ds0dREFlskDNJKYIdIzu/9pfw==",
+      "dev": true,
+      "dependencies": {
+        "call-bind": "^1.0.2"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/is-generator-function": {
+      "version": "1.0.10",
+      "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz",
+      "integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==",
+      "dev": true,
+      "dependencies": {
+        "has-tostringtag": "^1.0.0"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "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-hexadecimal": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-2.0.1.tgz",
+      "integrity": "sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg==",
+      "funding": {
+        "type": "github",
+        "url": "https://github.com/sponsors/wooorm"
+      }
+    },
+    "node_modules/is-map": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.2.tgz",
+      "integrity": "sha512-cOZFQQozTha1f4MxLFzlgKYPTyj26picdZTx82hbc/Xf4K/tZOOXSCkMvU4pKioRXGDLJRn0GM7Upe7kR721yg==",
+      "dev": true,
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/is-negative-zero": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz",
+      "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==",
+      "dev": true,
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "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-number-object": {
+      "version": "1.0.7",
+      "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz",
+      "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==",
+      "dev": true,
+      "dependencies": {
+        "has-tostringtag": "^1.0.0"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "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-plain-obj": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz",
+      "integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==",
+      "engines": {
+        "node": ">=12"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/is-regex": {
+      "version": "1.1.4",
+      "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz",
+      "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==",
+      "dev": true,
+      "dependencies": {
+        "call-bind": "^1.0.2",
+        "has-tostringtag": "^1.0.0"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/is-set": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.2.tgz",
+      "integrity": "sha512-+2cnTEZeY5z/iXGbLhPrOAaK/Mau5k5eXq9j14CpRTftq0pAJu2MwVRSZhyZWBzx3o6X795Lz6Bpb6R0GKf37g==",
+      "dev": true,
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/is-shared-array-buffer": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz",
+      "integrity": "sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==",
+      "dev": true,
+      "dependencies": {
+        "call-bind": "^1.0.2"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/is-string": {
+      "version": "1.0.7",
+      "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz",
+      "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==",
+      "dev": true,
+      "dependencies": {
+        "has-tostringtag": "^1.0.0"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/is-symbol": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz",
+      "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==",
+      "dev": true,
+      "dependencies": {
+        "has-symbols": "^1.0.2"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/is-typed-array": {
+      "version": "1.1.12",
+      "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.12.tgz",
+      "integrity": "sha512-Z14TF2JNG8Lss5/HMqt0//T9JeHXttXy5pH/DBU4vi98ozO2btxzq9MwYDZYnKwU8nRsz/+GVFVRDq3DkVuSPg==",
+      "dev": true,
+      "dependencies": {
+        "which-typed-array": "^1.1.11"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/is-weakmap": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.1.tgz",
+      "integrity": "sha512-NSBR4kH5oVj1Uwvv970ruUkCV7O1mzgVFO4/rev2cLRda9Tm9HrL70ZPut4rOHgY0FNrUu9BCbXA2sdQ+x0chA==",
+      "dev": true,
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/is-weakref": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz",
+      "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==",
+      "dev": true,
+      "dependencies": {
+        "call-bind": "^1.0.2"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/is-weakset": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.2.tgz",
+      "integrity": "sha512-t2yVvttHkQktwnNNmBQ98AhENLdPUTDTE21uPqAQ0ARwQfGeQKRVS0NNurH7bTf7RrvcVn1OOge45CnBeHCSmg==",
+      "dev": true,
+      "dependencies": {
+        "call-bind": "^1.0.2",
+        "get-intrinsic": "^1.1.1"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/isarray": {
+      "version": "2.0.5",
+      "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz",
+      "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==",
+      "dev": true
+    },
+    "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/iterator.prototype": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/iterator.prototype/-/iterator.prototype-1.1.2.tgz",
+      "integrity": "sha512-DR33HMMr8EzwuRL8Y9D3u2BMj8+RqSE850jfGu59kS7tbmPLzGkZmVSfyCFSDxuZiEY6Rzt3T2NA/qU+NwVj1w==",
+      "dev": true,
+      "dependencies": {
+        "define-properties": "^1.2.1",
+        "get-intrinsic": "^1.2.1",
+        "has-symbols": "^1.0.3",
+        "reflect.getprototypeof": "^1.0.4",
+        "set-function-name": "^2.0.1"
+      }
+    },
+    "node_modules/js-tokens": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
+      "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="
+    },
+    "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/jsesc": {
+      "version": "2.5.2",
+      "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz",
+      "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==",
+      "dev": true,
+      "bin": {
+        "jsesc": "bin/jsesc"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "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-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/json5": {
+      "version": "2.2.3",
+      "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
+      "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",
+      "dev": true,
+      "bin": {
+        "json5": "lib/cli.js"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/jsx-ast-utils": {
+      "version": "3.3.5",
+      "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.5.tgz",
+      "integrity": "sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==",
+      "dev": true,
+      "dependencies": {
+        "array-includes": "^3.1.6",
+        "array.prototype.flat": "^1.3.1",
+        "object.assign": "^4.1.4",
+        "object.values": "^1.1.6"
+      },
+      "engines": {
+        "node": ">=4.0"
+      }
+    },
+    "node_modules/keyborg": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/keyborg/-/keyborg-2.1.0.tgz",
+      "integrity": "sha512-0+v3/GIYG6gClwBOXrHet31n1UJW49xbKgVPUu6we41aq9tAmMosVXEdctZxsQdebyxtrcxVTkvHjBD1XPOHwg=="
+    },
+    "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/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/lie": {
+      "version": "3.1.1",
+      "resolved": "https://registry.npmjs.org/lie/-/lie-3.1.1.tgz",
+      "integrity": "sha512-RiNhHysUjhrDQntfYSfY4MU24coXXdEOgw9WGcKHNeEwffDYbF//u87M1EWaMGzuFoSbqW0C9C6lEEhDOAswfw==",
+      "dependencies": {
+        "immediate": "~3.0.5"
+      }
+    },
+    "node_modules/localforage": {
+      "version": "1.10.0",
+      "resolved": "https://registry.npmjs.org/localforage/-/localforage-1.10.0.tgz",
+      "integrity": "sha512-14/H1aX7hzBBmmh7sGPd+AOMkkIrHM3Z1PAyGgZigA1H1p5O5ANnMyWzvpAETtG68/dC4pC0ncy3+PPGzXZHPg==",
+      "dependencies": {
+        "lie": "3.1.1"
+      }
+    },
+    "node_modules/localstorage-slim": {
+      "version": "2.7.0",
+      "resolved": "https://registry.npmjs.org/localstorage-slim/-/localstorage-slim-2.7.0.tgz",
+      "integrity": "sha512-velxCZhb0mODaD9noe4pu3+OYnMKC66itqDqHMRsVpXKAJYU2+cUX09KRxoZ/nlVwitVgjlG2BZSEaP6RPJmgw=="
+    },
+    "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.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/longest-streak": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-3.1.0.tgz",
+      "integrity": "sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==",
+      "funding": {
+        "type": "github",
+        "url": "https://github.com/sponsors/wooorm"
+      }
+    },
+    "node_modules/loose-envify": {
+      "version": "1.4.0",
+      "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
+      "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==",
+      "dependencies": {
+        "js-tokens": "^3.0.0 || ^4.0.0"
+      },
+      "bin": {
+        "loose-envify": "cli.js"
+      }
+    },
+    "node_modules/lru-cache": {
+      "version": "5.1.1",
+      "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
+      "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==",
+      "dev": true,
+      "dependencies": {
+        "yallist": "^3.0.2"
+      }
+    },
+    "node_modules/match-sorter": {
+      "version": "6.3.1",
+      "resolved": "https://registry.npmjs.org/match-sorter/-/match-sorter-6.3.1.tgz",
+      "integrity": "sha512-mxybbo3pPNuA+ZuCUhm5bwNkXrJTbsk5VWbR5wiwz/GC6LIiegBGn2w3O08UG/jdbYLinw51fSQ5xNU1U3MgBw==",
+      "dependencies": {
+        "@babel/runtime": "^7.12.5",
+        "remove-accents": "0.4.2"
+      }
+    },
+    "node_modules/mdast-util-from-markdown": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-2.0.0.tgz",
+      "integrity": "sha512-n7MTOr/z+8NAX/wmhhDji8O3bRvPTV/U0oTCaZJkjhPSKTPhS3xufVhKGF8s1pJ7Ox4QgoIU7KHseh09S+9rTA==",
+      "dependencies": {
+        "@types/mdast": "^4.0.0",
+        "@types/unist": "^3.0.0",
+        "decode-named-character-reference": "^1.0.0",
+        "devlop": "^1.0.0",
+        "mdast-util-to-string": "^4.0.0",
+        "micromark": "^4.0.0",
+        "micromark-util-decode-numeric-character-reference": "^2.0.0",
+        "micromark-util-decode-string": "^2.0.0",
+        "micromark-util-normalize-identifier": "^2.0.0",
+        "micromark-util-symbol": "^2.0.0",
+        "micromark-util-types": "^2.0.0",
+        "unist-util-stringify-position": "^4.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/unified"
+      }
+    },
+    "node_modules/mdast-util-mdx-expression": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/mdast-util-mdx-expression/-/mdast-util-mdx-expression-2.0.0.tgz",
+      "integrity": "sha512-fGCu8eWdKUKNu5mohVGkhBXCXGnOTLuFqOvGMvdikr+J1w7lDJgxThOKpwRWzzbyXAU2hhSwsmssOY4yTokluw==",
+      "dependencies": {
+        "@types/estree-jsx": "^1.0.0",
+        "@types/hast": "^3.0.0",
+        "@types/mdast": "^4.0.0",
+        "devlop": "^1.0.0",
+        "mdast-util-from-markdown": "^2.0.0",
+        "mdast-util-to-markdown": "^2.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/unified"
+      }
+    },
+    "node_modules/mdast-util-mdx-jsx": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/mdast-util-mdx-jsx/-/mdast-util-mdx-jsx-3.0.0.tgz",
+      "integrity": "sha512-XZuPPzQNBPAlaqsTTgRrcJnyFbSOBovSadFgbFu8SnuNgm+6Bdx1K+IWoitsmj6Lq6MNtI+ytOqwN70n//NaBA==",
+      "dependencies": {
+        "@types/estree-jsx": "^1.0.0",
+        "@types/hast": "^3.0.0",
+        "@types/mdast": "^4.0.0",
+        "@types/unist": "^3.0.0",
+        "ccount": "^2.0.0",
+        "devlop": "^1.1.0",
+        "mdast-util-from-markdown": "^2.0.0",
+        "mdast-util-to-markdown": "^2.0.0",
+        "parse-entities": "^4.0.0",
+        "stringify-entities": "^4.0.0",
+        "unist-util-remove-position": "^5.0.0",
+        "unist-util-stringify-position": "^4.0.0",
+        "vfile-message": "^4.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/unified"
+      }
+    },
+    "node_modules/mdast-util-mdxjs-esm": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/mdast-util-mdxjs-esm/-/mdast-util-mdxjs-esm-2.0.1.tgz",
+      "integrity": "sha512-EcmOpxsZ96CvlP03NghtH1EsLtr0n9Tm4lPUJUBccV9RwUOneqSycg19n5HGzCf+10LozMRSObtVr3ee1WoHtg==",
+      "dependencies": {
+        "@types/estree-jsx": "^1.0.0",
+        "@types/hast": "^3.0.0",
+        "@types/mdast": "^4.0.0",
+        "devlop": "^1.0.0",
+        "mdast-util-from-markdown": "^2.0.0",
+        "mdast-util-to-markdown": "^2.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/unified"
+      }
+    },
+    "node_modules/mdast-util-phrasing": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/mdast-util-phrasing/-/mdast-util-phrasing-4.0.0.tgz",
+      "integrity": "sha512-xadSsJayQIucJ9n053dfQwVu1kuXg7jCTdYsMK8rqzKZh52nLfSH/k0sAxE0u+pj/zKZX+o5wB+ML5mRayOxFA==",
+      "dependencies": {
+        "@types/mdast": "^4.0.0",
+        "unist-util-is": "^6.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/unified"
+      }
+    },
+    "node_modules/mdast-util-to-hast": {
+      "version": "13.0.2",
+      "resolved": "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-13.0.2.tgz",
+      "integrity": "sha512-U5I+500EOOw9e3ZrclN3Is3fRpw8c19SMyNZlZ2IS+7vLsNzb2Om11VpIVOR+/0137GhZsFEF6YiKD5+0Hr2Og==",
+      "dependencies": {
+        "@types/hast": "^3.0.0",
+        "@types/mdast": "^4.0.0",
+        "@ungap/structured-clone": "^1.0.0",
+        "devlop": "^1.0.0",
+        "micromark-util-sanitize-uri": "^2.0.0",
+        "trim-lines": "^3.0.0",
+        "unist-util-position": "^5.0.0",
+        "unist-util-visit": "^5.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/unified"
+      }
+    },
+    "node_modules/mdast-util-to-markdown": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-2.1.0.tgz",
+      "integrity": "sha512-SR2VnIEdVNCJbP6y7kVTJgPLifdr8WEU440fQec7qHoHOUz/oJ2jmNRqdDQ3rbiStOXb2mCDGTuwsK5OPUgYlQ==",
+      "dependencies": {
+        "@types/mdast": "^4.0.0",
+        "@types/unist": "^3.0.0",
+        "longest-streak": "^3.0.0",
+        "mdast-util-phrasing": "^4.0.0",
+        "mdast-util-to-string": "^4.0.0",
+        "micromark-util-decode-string": "^2.0.0",
+        "unist-util-visit": "^5.0.0",
+        "zwitch": "^2.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/unified"
+      }
+    },
+    "node_modules/mdast-util-to-string": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-4.0.0.tgz",
+      "integrity": "sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==",
+      "dependencies": {
+        "@types/mdast": "^4.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/unified"
+      }
+    },
+    "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/micromark": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/micromark/-/micromark-4.0.0.tgz",
+      "integrity": "sha512-o/sd0nMof8kYff+TqcDx3VSrgBTcZpSvYcAHIfHhv5VAuNmisCxjhx6YmxS8PFEpb9z5WKWKPdzf0jM23ro3RQ==",
+      "funding": [
+        {
+          "type": "GitHub Sponsors",
+          "url": "https://github.com/sponsors/unifiedjs"
+        },
+        {
+          "type": "OpenCollective",
+          "url": "https://opencollective.com/unified"
+        }
+      ],
+      "dependencies": {
+        "@types/debug": "^4.0.0",
+        "debug": "^4.0.0",
+        "decode-named-character-reference": "^1.0.0",
+        "devlop": "^1.0.0",
+        "micromark-core-commonmark": "^2.0.0",
+        "micromark-factory-space": "^2.0.0",
+        "micromark-util-character": "^2.0.0",
+        "micromark-util-chunked": "^2.0.0",
+        "micromark-util-combine-extensions": "^2.0.0",
+        "micromark-util-decode-numeric-character-reference": "^2.0.0",
+        "micromark-util-encode": "^2.0.0",
+        "micromark-util-normalize-identifier": "^2.0.0",
+        "micromark-util-resolve-all": "^2.0.0",
+        "micromark-util-sanitize-uri": "^2.0.0",
+        "micromark-util-subtokenize": "^2.0.0",
+        "micromark-util-symbol": "^2.0.0",
+        "micromark-util-types": "^2.0.0"
+      }
+    },
+    "node_modules/micromark-core-commonmark": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-2.0.0.tgz",
+      "integrity": "sha512-jThOz/pVmAYUtkroV3D5c1osFXAMv9e0ypGDOIZuCeAe91/sD6BoE2Sjzt30yuXtwOYUmySOhMas/PVyh02itA==",
+      "funding": [
+        {
+          "type": "GitHub Sponsors",
+          "url": "https://github.com/sponsors/unifiedjs"
+        },
+        {
+          "type": "OpenCollective",
+          "url": "https://opencollective.com/unified"
+        }
+      ],
+      "dependencies": {
+        "decode-named-character-reference": "^1.0.0",
+        "devlop": "^1.0.0",
+        "micromark-factory-destination": "^2.0.0",
+        "micromark-factory-label": "^2.0.0",
+        "micromark-factory-space": "^2.0.0",
+        "micromark-factory-title": "^2.0.0",
+        "micromark-factory-whitespace": "^2.0.0",
+        "micromark-util-character": "^2.0.0",
+        "micromark-util-chunked": "^2.0.0",
+        "micromark-util-classify-character": "^2.0.0",
+        "micromark-util-html-tag-name": "^2.0.0",
+        "micromark-util-normalize-identifier": "^2.0.0",
+        "micromark-util-resolve-all": "^2.0.0",
+        "micromark-util-subtokenize": "^2.0.0",
+        "micromark-util-symbol": "^2.0.0",
+        "micromark-util-types": "^2.0.0"
+      }
+    },
+    "node_modules/micromark-factory-destination": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-2.0.0.tgz",
+      "integrity": "sha512-j9DGrQLm/Uhl2tCzcbLhy5kXsgkHUrjJHg4fFAeoMRwJmJerT9aw4FEhIbZStWN8A3qMwOp1uzHr4UL8AInxtA==",
+      "funding": [
+        {
+          "type": "GitHub Sponsors",
+          "url": "https://github.com/sponsors/unifiedjs"
+        },
+        {
+          "type": "OpenCollective",
+          "url": "https://opencollective.com/unified"
+        }
+      ],
+      "dependencies": {
+        "micromark-util-character": "^2.0.0",
+        "micromark-util-symbol": "^2.0.0",
+        "micromark-util-types": "^2.0.0"
+      }
+    },
+    "node_modules/micromark-factory-label": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/micromark-factory-label/-/micromark-factory-label-2.0.0.tgz",
+      "integrity": "sha512-RR3i96ohZGde//4WSe/dJsxOX6vxIg9TimLAS3i4EhBAFx8Sm5SmqVfR8E87DPSR31nEAjZfbt91OMZWcNgdZw==",
+      "funding": [
+        {
+          "type": "GitHub Sponsors",
+          "url": "https://github.com/sponsors/unifiedjs"
+        },
+        {
+          "type": "OpenCollective",
+          "url": "https://opencollective.com/unified"
+        }
+      ],
+      "dependencies": {
+        "devlop": "^1.0.0",
+        "micromark-util-character": "^2.0.0",
+        "micromark-util-symbol": "^2.0.0",
+        "micromark-util-types": "^2.0.0"
+      }
+    },
+    "node_modules/micromark-factory-space": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz",
+      "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==",
+      "funding": [
+        {
+          "type": "GitHub Sponsors",
+          "url": "https://github.com/sponsors/unifiedjs"
+        },
+        {
+          "type": "OpenCollective",
+          "url": "https://opencollective.com/unified"
+        }
+      ],
+      "dependencies": {
+        "micromark-util-character": "^2.0.0",
+        "micromark-util-types": "^2.0.0"
+      }
+    },
+    "node_modules/micromark-factory-title": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/micromark-factory-title/-/micromark-factory-title-2.0.0.tgz",
+      "integrity": "sha512-jY8CSxmpWLOxS+t8W+FG3Xigc0RDQA9bKMY/EwILvsesiRniiVMejYTE4wumNc2f4UbAa4WsHqe3J1QS1sli+A==",
+      "funding": [
+        {
+          "type": "GitHub Sponsors",
+          "url": "https://github.com/sponsors/unifiedjs"
+        },
+        {
+          "type": "OpenCollective",
+          "url": "https://opencollective.com/unified"
+        }
+      ],
+      "dependencies": {
+        "micromark-factory-space": "^2.0.0",
+        "micromark-util-character": "^2.0.0",
+        "micromark-util-symbol": "^2.0.0",
+        "micromark-util-types": "^2.0.0"
+      }
+    },
+    "node_modules/micromark-factory-whitespace": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/micromark-factory-whitespace/-/micromark-factory-whitespace-2.0.0.tgz",
+      "integrity": "sha512-28kbwaBjc5yAI1XadbdPYHX/eDnqaUFVikLwrO7FDnKG7lpgxnvk/XGRhX/PN0mOZ+dBSZ+LgunHS+6tYQAzhA==",
+      "funding": [
+        {
+          "type": "GitHub Sponsors",
+          "url": "https://github.com/sponsors/unifiedjs"
+        },
+        {
+          "type": "OpenCollective",
+          "url": "https://opencollective.com/unified"
+        }
+      ],
+      "dependencies": {
+        "micromark-factory-space": "^2.0.0",
+        "micromark-util-character": "^2.0.0",
+        "micromark-util-symbol": "^2.0.0",
+        "micromark-util-types": "^2.0.0"
+      }
+    },
+    "node_modules/micromark-util-character": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.0.1.tgz",
+      "integrity": "sha512-3wgnrmEAJ4T+mGXAUfMvMAbxU9RDG43XmGce4j6CwPtVxB3vfwXSZ6KhFwDzZ3mZHhmPimMAXg71veiBGzeAZw==",
+      "funding": [
+        {
+          "type": "GitHub Sponsors",
+          "url": "https://github.com/sponsors/unifiedjs"
+        },
+        {
+          "type": "OpenCollective",
+          "url": "https://opencollective.com/unified"
+        }
+      ],
+      "dependencies": {
+        "micromark-util-symbol": "^2.0.0",
+        "micromark-util-types": "^2.0.0"
+      }
+    },
+    "node_modules/micromark-util-chunked": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/micromark-util-chunked/-/micromark-util-chunked-2.0.0.tgz",
+      "integrity": "sha512-anK8SWmNphkXdaKgz5hJvGa7l00qmcaUQoMYsBwDlSKFKjc6gjGXPDw3FNL3Nbwq5L8gE+RCbGqTw49FK5Qyvg==",
+      "funding": [
+        {
+          "type": "GitHub Sponsors",
+          "url": "https://github.com/sponsors/unifiedjs"
+        },
+        {
+          "type": "OpenCollective",
+          "url": "https://opencollective.com/unified"
+        }
+      ],
+      "dependencies": {
+        "micromark-util-symbol": "^2.0.0"
+      }
+    },
+    "node_modules/micromark-util-classify-character": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/micromark-util-classify-character/-/micromark-util-classify-character-2.0.0.tgz",
+      "integrity": "sha512-S0ze2R9GH+fu41FA7pbSqNWObo/kzwf8rN/+IGlW/4tC6oACOs8B++bh+i9bVyNnwCcuksbFwsBme5OCKXCwIw==",
+      "funding": [
+        {
+          "type": "GitHub Sponsors",
+          "url": "https://github.com/sponsors/unifiedjs"
+        },
+        {
+          "type": "OpenCollective",
+          "url": "https://opencollective.com/unified"
+        }
+      ],
+      "dependencies": {
+        "micromark-util-character": "^2.0.0",
+        "micromark-util-symbol": "^2.0.0",
+        "micromark-util-types": "^2.0.0"
+      }
+    },
+    "node_modules/micromark-util-combine-extensions": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/micromark-util-combine-extensions/-/micromark-util-combine-extensions-2.0.0.tgz",
+      "integrity": "sha512-vZZio48k7ON0fVS3CUgFatWHoKbbLTK/rT7pzpJ4Bjp5JjkZeasRfrS9wsBdDJK2cJLHMckXZdzPSSr1B8a4oQ==",
+      "funding": [
+        {
+          "type": "GitHub Sponsors",
+          "url": "https://github.com/sponsors/unifiedjs"
+        },
+        {
+          "type": "OpenCollective",
+          "url": "https://opencollective.com/unified"
+        }
+      ],
+      "dependencies": {
+        "micromark-util-chunked": "^2.0.0",
+        "micromark-util-types": "^2.0.0"
+      }
+    },
+    "node_modules/micromark-util-decode-numeric-character-reference": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-2.0.1.tgz",
+      "integrity": "sha512-bmkNc7z8Wn6kgjZmVHOX3SowGmVdhYS7yBpMnuMnPzDq/6xwVA604DuOXMZTO1lvq01g+Adfa0pE2UKGlxL1XQ==",
+      "funding": [
+        {
+          "type": "GitHub Sponsors",
+          "url": "https://github.com/sponsors/unifiedjs"
+        },
+        {
+          "type": "OpenCollective",
+          "url": "https://opencollective.com/unified"
+        }
+      ],
+      "dependencies": {
+        "micromark-util-symbol": "^2.0.0"
+      }
+    },
+    "node_modules/micromark-util-decode-string": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/micromark-util-decode-string/-/micromark-util-decode-string-2.0.0.tgz",
+      "integrity": "sha512-r4Sc6leeUTn3P6gk20aFMj2ntPwn6qpDZqWvYmAG6NgvFTIlj4WtrAudLi65qYoaGdXYViXYw2pkmn7QnIFasA==",
+      "funding": [
+        {
+          "type": "GitHub Sponsors",
+          "url": "https://github.com/sponsors/unifiedjs"
+        },
+        {
+          "type": "OpenCollective",
+          "url": "https://opencollective.com/unified"
+        }
+      ],
+      "dependencies": {
+        "decode-named-character-reference": "^1.0.0",
+        "micromark-util-character": "^2.0.0",
+        "micromark-util-decode-numeric-character-reference": "^2.0.0",
+        "micromark-util-symbol": "^2.0.0"
+      }
+    },
+    "node_modules/micromark-util-encode": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-2.0.0.tgz",
+      "integrity": "sha512-pS+ROfCXAGLWCOc8egcBvT0kf27GoWMqtdarNfDcjb6YLuV5cM3ioG45Ys2qOVqeqSbjaKg72vU+Wby3eddPsA==",
+      "funding": [
+        {
+          "type": "GitHub Sponsors",
+          "url": "https://github.com/sponsors/unifiedjs"
+        },
+        {
+          "type": "OpenCollective",
+          "url": "https://opencollective.com/unified"
+        }
+      ]
+    },
+    "node_modules/micromark-util-html-tag-name": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/micromark-util-html-tag-name/-/micromark-util-html-tag-name-2.0.0.tgz",
+      "integrity": "sha512-xNn4Pqkj2puRhKdKTm8t1YHC/BAjx6CEwRFXntTaRf/x16aqka6ouVoutm+QdkISTlT7e2zU7U4ZdlDLJd2Mcw==",
+      "funding": [
+        {
+          "type": "GitHub Sponsors",
+          "url": "https://github.com/sponsors/unifiedjs"
+        },
+        {
+          "type": "OpenCollective",
+          "url": "https://opencollective.com/unified"
+        }
+      ]
+    },
+    "node_modules/micromark-util-normalize-identifier": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-2.0.0.tgz",
+      "integrity": "sha512-2xhYT0sfo85FMrUPtHcPo2rrp1lwbDEEzpx7jiH2xXJLqBuy4H0GgXk5ToU8IEwoROtXuL8ND0ttVa4rNqYK3w==",
+      "funding": [
+        {
+          "type": "GitHub Sponsors",
+          "url": "https://github.com/sponsors/unifiedjs"
+        },
+        {
+          "type": "OpenCollective",
+          "url": "https://opencollective.com/unified"
+        }
+      ],
+      "dependencies": {
+        "micromark-util-symbol": "^2.0.0"
+      }
+    },
+    "node_modules/micromark-util-resolve-all": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/micromark-util-resolve-all/-/micromark-util-resolve-all-2.0.0.tgz",
+      "integrity": "sha512-6KU6qO7DZ7GJkaCgwBNtplXCvGkJToU86ybBAUdavvgsCiG8lSSvYxr9MhwmQ+udpzywHsl4RpGJsYWG1pDOcA==",
+      "funding": [
+        {
+          "type": "GitHub Sponsors",
+          "url": "https://github.com/sponsors/unifiedjs"
+        },
+        {
+          "type": "OpenCollective",
+          "url": "https://opencollective.com/unified"
+        }
+      ],
+      "dependencies": {
+        "micromark-util-types": "^2.0.0"
+      }
+    },
+    "node_modules/micromark-util-sanitize-uri": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-2.0.0.tgz",
+      "integrity": "sha512-WhYv5UEcZrbAtlsnPuChHUAsu/iBPOVaEVsntLBIdpibO0ddy8OzavZz3iL2xVvBZOpolujSliP65Kq0/7KIYw==",
+      "funding": [
+        {
+          "type": "GitHub Sponsors",
+          "url": "https://github.com/sponsors/unifiedjs"
+        },
+        {
+          "type": "OpenCollective",
+          "url": "https://opencollective.com/unified"
+        }
+      ],
+      "dependencies": {
+        "micromark-util-character": "^2.0.0",
+        "micromark-util-encode": "^2.0.0",
+        "micromark-util-symbol": "^2.0.0"
+      }
+    },
+    "node_modules/micromark-util-subtokenize": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/micromark-util-subtokenize/-/micromark-util-subtokenize-2.0.0.tgz",
+      "integrity": "sha512-vc93L1t+gpR3p8jxeVdaYlbV2jTYteDje19rNSS/H5dlhxUYll5Fy6vJ2cDwP8RnsXi818yGty1ayP55y3W6fg==",
+      "funding": [
+        {
+          "type": "GitHub Sponsors",
+          "url": "https://github.com/sponsors/unifiedjs"
+        },
+        {
+          "type": "OpenCollective",
+          "url": "https://opencollective.com/unified"
+        }
+      ],
+      "dependencies": {
+        "devlop": "^1.0.0",
+        "micromark-util-chunked": "^2.0.0",
+        "micromark-util-symbol": "^2.0.0",
+        "micromark-util-types": "^2.0.0"
+      }
+    },
+    "node_modules/micromark-util-symbol": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz",
+      "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==",
+      "funding": [
+        {
+          "type": "GitHub Sponsors",
+          "url": "https://github.com/sponsors/unifiedjs"
+        },
+        {
+          "type": "OpenCollective",
+          "url": "https://opencollective.com/unified"
+        }
+      ]
+    },
+    "node_modules/micromark-util-types": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-2.0.0.tgz",
+      "integrity": "sha512-oNh6S2WMHWRZrmutsRmDDfkzKtxF+bc2VxLC9dvtrDIRFln627VsFP6fLMgTryGDljgLPjkrzQSDcPrjPyDJ5w==",
+      "funding": [
+        {
+          "type": "GitHub Sponsors",
+          "url": "https://github.com/sponsors/unifiedjs"
+        },
+        {
+          "type": "OpenCollective",
+          "url": "https://opencollective.com/unified"
+        }
+      ]
+    },
+    "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/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/ms": {
+      "version": "2.1.2",
+      "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+      "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
+    },
+    "node_modules/nanoid": {
+      "version": "3.3.6",
+      "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz",
+      "integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==",
+      "dev": true,
+      "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.13",
+      "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.13.tgz",
+      "integrity": "sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ==",
+      "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==",
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/object-inspect": {
+      "version": "1.12.3",
+      "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.3.tgz",
+      "integrity": "sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==",
+      "dev": true,
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/object-keys": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz",
+      "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==",
+      "dev": true,
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
+    "node_modules/object-path": {
+      "version": "0.6.0",
+      "resolved": "https://registry.npmjs.org/object-path/-/object-path-0.6.0.tgz",
+      "integrity": "sha512-fxrwsCFi3/p+LeLOAwo/wyRMODZxdGBtUlWRzsEpsUVrisZbEfZ21arxLGfaWfcnqb8oHPNihIb4XPE8CQPN5A==",
+      "engines": {
+        "node": ">=0.8.0"
+      }
+    },
+    "node_modules/object.assign": {
+      "version": "4.1.4",
+      "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.4.tgz",
+      "integrity": "sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==",
+      "dev": true,
+      "dependencies": {
+        "call-bind": "^1.0.2",
+        "define-properties": "^1.1.4",
+        "has-symbols": "^1.0.3",
+        "object-keys": "^1.1.1"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/object.entries": {
+      "version": "1.1.7",
+      "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.7.tgz",
+      "integrity": "sha512-jCBs/0plmPsOnrKAfFQXRG2NFjlhZgjjcBLSmTnEhU8U6vVTsVe8ANeQJCHTl3gSsI4J+0emOoCgoKlmQPMgmA==",
+      "dev": true,
+      "dependencies": {
+        "call-bind": "^1.0.2",
+        "define-properties": "^1.2.0",
+        "es-abstract": "^1.22.1"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
+    "node_modules/object.fromentries": {
+      "version": "2.0.7",
+      "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.7.tgz",
+      "integrity": "sha512-UPbPHML6sL8PI/mOqPwsH4G6iyXcCGzLin8KvEPenOZN5lpCNBZZQ+V62vdjB1mQHrmqGQt5/OJzemUA+KJmEA==",
+      "dev": true,
+      "dependencies": {
+        "call-bind": "^1.0.2",
+        "define-properties": "^1.2.0",
+        "es-abstract": "^1.22.1"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/object.hasown": {
+      "version": "1.1.3",
+      "resolved": "https://registry.npmjs.org/object.hasown/-/object.hasown-1.1.3.tgz",
+      "integrity": "sha512-fFI4VcYpRHvSLXxP7yiZOMAd331cPfd2p7PFDVbgUsYOfCT3tICVqXWngbjr4m49OvsBwUBQ6O2uQoJvy3RexA==",
+      "dev": true,
+      "dependencies": {
+        "define-properties": "^1.2.0",
+        "es-abstract": "^1.22.1"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/object.values": {
+      "version": "1.1.7",
+      "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.7.tgz",
+      "integrity": "sha512-aU6xnDFYT3x17e/f0IiiwlGPTy2jzMySGfUB4fq6z7CV8l85CWHDk5ErhyhpfDHhrOMwGFhSQkhMGHaIotA6Ng==",
+      "dev": true,
+      "dependencies": {
+        "call-bind": "^1.0.2",
+        "define-properties": "^1.2.0",
+        "es-abstract": "^1.22.1"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "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/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/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/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/parse-entities": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-4.0.1.tgz",
+      "integrity": "sha512-SWzvYcSJh4d/SGLIOQfZ/CoNv6BTlI6YEQ7Nj82oDVnRpwe/Z/F1EMx42x3JAOwGBlCjeCH0BRJQbQ/opHL17w==",
+      "dependencies": {
+        "@types/unist": "^2.0.0",
+        "character-entities": "^2.0.0",
+        "character-entities-legacy": "^3.0.0",
+        "character-reference-invalid": "^2.0.0",
+        "decode-named-character-reference": "^1.0.0",
+        "is-alphanumerical": "^2.0.0",
+        "is-decimal": "^2.0.0",
+        "is-hexadecimal": "^2.0.0"
+      },
+      "funding": {
+        "type": "github",
+        "url": "https://github.com/sponsors/wooorm"
+      }
+    },
+    "node_modules/parse-entities/node_modules/@types/unist": {
+      "version": "2.0.10",
+      "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.10.tgz",
+      "integrity": "sha512-IfYcSBWE3hLpBg8+X2SEa8LVkJdJEkT2Ese2aaLs3ptGdVtABxndrMaxuFlQ1qdFf9Q5rDvDpxI3WwgvKFAsQA=="
+    },
+    "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-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/picocolors": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
+      "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==",
+      "dev": true
+    },
+    "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/postcss": {
+      "version": "8.4.31",
+      "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz",
+      "integrity": "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==",
+      "dev": true,
+      "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.6",
+        "picocolors": "^1.0.0",
+        "source-map-js": "^1.0.2"
+      },
+      "engines": {
+        "node": "^10 || ^12 || >=14"
+      }
+    },
+    "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/prop-types": {
+      "version": "15.8.1",
+      "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz",
+      "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==",
+      "dependencies": {
+        "loose-envify": "^1.4.0",
+        "object-assign": "^4.1.1",
+        "react-is": "^16.13.1"
+      }
+    },
+    "node_modules/property-information": {
+      "version": "6.4.0",
+      "resolved": "https://registry.npmjs.org/property-information/-/property-information-6.4.0.tgz",
+      "integrity": "sha512-9t5qARVofg2xQqKtytzt+lZ4d1Qvj8t5B8fEwXK6qOfgRLgH/b13QlgEyDh033NOS31nXeFbYv7CLUDG1CeifQ==",
+      "funding": {
+        "type": "github",
+        "url": "https://github.com/sponsors/wooorm"
+      }
+    },
+    "node_modules/punycode": {
+      "version": "2.3.0",
+      "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz",
+      "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==",
+      "dev": true,
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "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": {
+      "version": "18.2.0",
+      "resolved": "https://registry.npmjs.org/react/-/react-18.2.0.tgz",
+      "integrity": "sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==",
+      "dependencies": {
+        "loose-envify": "^1.1.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/react-dom": {
+      "version": "18.2.0",
+      "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz",
+      "integrity": "sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==",
+      "dependencies": {
+        "loose-envify": "^1.1.0",
+        "scheduler": "^0.23.0"
+      },
+      "peerDependencies": {
+        "react": "^18.2.0"
+      }
+    },
+    "node_modules/react-dom/node_modules/scheduler": {
+      "version": "0.23.0",
+      "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz",
+      "integrity": "sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==",
+      "dependencies": {
+        "loose-envify": "^1.1.0"
+      }
+    },
+    "node_modules/react-is": {
+      "version": "16.13.1",
+      "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
+      "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
+    },
+    "node_modules/react-markdown": {
+      "version": "9.0.1",
+      "resolved": "https://registry.npmjs.org/react-markdown/-/react-markdown-9.0.1.tgz",
+      "integrity": "sha512-186Gw/vF1uRkydbsOIkcGXw7aHq0sZOCRFFjGrr7b9+nVZg4UfA4enXCaxm4fUzecU38sWfrNDitGhshuU7rdg==",
+      "dependencies": {
+        "@types/hast": "^3.0.0",
+        "devlop": "^1.0.0",
+        "hast-util-to-jsx-runtime": "^2.0.0",
+        "html-url-attributes": "^3.0.0",
+        "mdast-util-to-hast": "^13.0.0",
+        "remark-parse": "^11.0.0",
+        "remark-rehype": "^11.0.0",
+        "unified": "^11.0.0",
+        "unist-util-visit": "^5.0.0",
+        "vfile": "^6.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/unified"
+      },
+      "peerDependencies": {
+        "@types/react": ">=18",
+        "react": ">=18"
+      }
+    },
+    "node_modules/react-refresh": {
+      "version": "0.14.0",
+      "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.14.0.tgz",
+      "integrity": "sha512-wViHqhAd8OHeLS/IRMJjTSDHF3U9eWi62F/MledQGPdJGDhodXJ9PBLNGr6WWL7qlH12Mt3TyTpbS+hGXMjCzQ==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/react-router": {
+      "version": "6.16.0",
+      "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.16.0.tgz",
+      "integrity": "sha512-VT4Mmc4jj5YyjpOi5jOf0I+TYzGpvzERy4ckNSvSh2RArv8LLoCxlsZ2D+tc7zgjxcY34oTz2hZaeX5RVprKqA==",
+      "dependencies": {
+        "@remix-run/router": "1.9.0"
+      },
+      "engines": {
+        "node": ">=14.0.0"
+      },
+      "peerDependencies": {
+        "react": ">=16.8"
+      }
+    },
+    "node_modules/react-router-dom": {
+      "version": "6.16.0",
+      "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.16.0.tgz",
+      "integrity": "sha512-aTfBLv3mk/gaKLxgRDUPbPw+s4Y/O+ma3rEN1u8EgEpLpPe6gNjIsWt9rxushMHHMb7mSwxRGdGlGdvmFsyPIg==",
+      "dependencies": {
+        "@remix-run/router": "1.9.0",
+        "react-router": "6.16.0"
+      },
+      "engines": {
+        "node": ">=14.0.0"
+      },
+      "peerDependencies": {
+        "react": ">=16.8",
+        "react-dom": ">=16.8"
+      }
+    },
+    "node_modules/react-transition-group": {
+      "version": "4.4.5",
+      "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.5.tgz",
+      "integrity": "sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==",
+      "dependencies": {
+        "@babel/runtime": "^7.5.5",
+        "dom-helpers": "^5.0.1",
+        "loose-envify": "^1.4.0",
+        "prop-types": "^15.6.2"
+      },
+      "peerDependencies": {
+        "react": ">=16.6.0",
+        "react-dom": ">=16.6.0"
+      }
+    },
+    "node_modules/reflect.getprototypeof": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.4.tgz",
+      "integrity": "sha512-ECkTw8TmJwW60lOTR+ZkODISW6RQ8+2CL3COqtiJKLd6MmB45hN51HprHFziKLGkAuTGQhBb91V8cy+KHlaCjw==",
+      "dev": true,
+      "dependencies": {
+        "call-bind": "^1.0.2",
+        "define-properties": "^1.2.0",
+        "es-abstract": "^1.22.1",
+        "get-intrinsic": "^1.2.1",
+        "globalthis": "^1.0.3",
+        "which-builtin-type": "^1.1.3"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/regenerator-runtime": {
+      "version": "0.14.0",
+      "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.0.tgz",
+      "integrity": "sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA=="
+    },
+    "node_modules/regexp.prototype.flags": {
+      "version": "1.5.1",
+      "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.1.tgz",
+      "integrity": "sha512-sy6TXMN+hnP/wMy+ISxg3krXx7BAtWVO4UouuCN/ziM9UEne0euamVNafDfvC83bRNr95y0V5iijeDQFUNpvrg==",
+      "dev": true,
+      "dependencies": {
+        "call-bind": "^1.0.2",
+        "define-properties": "^1.2.0",
+        "set-function-name": "^2.0.0"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/remark-parse": {
+      "version": "11.0.0",
+      "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-11.0.0.tgz",
+      "integrity": "sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA==",
+      "dependencies": {
+        "@types/mdast": "^4.0.0",
+        "mdast-util-from-markdown": "^2.0.0",
+        "micromark-util-types": "^2.0.0",
+        "unified": "^11.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/unified"
+      }
+    },
+    "node_modules/remark-rehype": {
+      "version": "11.0.0",
+      "resolved": "https://registry.npmjs.org/remark-rehype/-/remark-rehype-11.0.0.tgz",
+      "integrity": "sha512-vx8x2MDMcxuE4lBmQ46zYUDfcFMmvg80WYX+UNLeG6ixjdCCLcw1lrgAukwBTuOFsS78eoAedHGn9sNM0w7TPw==",
+      "dependencies": {
+        "@types/hast": "^3.0.0",
+        "@types/mdast": "^4.0.0",
+        "mdast-util-to-hast": "^13.0.0",
+        "unified": "^11.0.0",
+        "vfile": "^6.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/unified"
+      }
+    },
+    "node_modules/remove-accents": {
+      "version": "0.4.2",
+      "resolved": "https://registry.npmjs.org/remove-accents/-/remove-accents-0.4.2.tgz",
+      "integrity": "sha512-7pXIJqJOq5tFgG1A2Zxti3Ht8jJF337m4sowbuHsW30ZnkQFnDzy9qBNhgzX8ZLW4+UBcXiiR7SwR6pokHsxiA=="
+    },
+    "node_modules/resolve": {
+      "version": "2.0.0-next.4",
+      "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.4.tgz",
+      "integrity": "sha512-iMDbmAWtfU+MHpxt/I5iWI7cY6YVEZUQ3MBgPQ++XD1PELuJHIl82xBmObyP2KyQmkNB2dsqF7seoQQiAn5yDQ==",
+      "dev": true,
+      "dependencies": {
+        "is-core-module": "^2.9.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/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/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/rollup": {
+      "version": "3.29.4",
+      "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.29.4.tgz",
+      "integrity": "sha512-oWzmBZwvYrU0iJHtDmhsm662rC15FRXmcjCk1xD771dFDx5jJ02ufAQQTn0etB2emNk4J9EZg/yWKpsn9BWGRw==",
+      "dev": true,
+      "bin": {
+        "rollup": "dist/bin/rollup"
+      },
+      "engines": {
+        "node": ">=14.18.0",
+        "npm": ">=8.0.0"
+      },
+      "optionalDependencies": {
+        "fsevents": "~2.3.2"
+      }
+    },
+    "node_modules/rtl-css-js": {
+      "version": "1.16.1",
+      "resolved": "https://registry.npmjs.org/rtl-css-js/-/rtl-css-js-1.16.1.tgz",
+      "integrity": "sha512-lRQgou1mu19e+Ya0LsTvKrVJ5TYUbqCVPAiImX3UfLTenarvPUl1QFdvu5Z3PYmHT9RCcwIfbjRQBntExyj3Zg==",
+      "dependencies": {
+        "@babel/runtime": "^7.1.2"
+      }
+    },
+    "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/safe-array-concat": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.0.1.tgz",
+      "integrity": "sha512-6XbUAseYE2KtOuGueyeobCySj9L4+66Tn6KQMOPQJrAJEowYKW/YR/MGJZl7FdydUdaFu4LYyDZjxf4/Nmo23Q==",
+      "dev": true,
+      "dependencies": {
+        "call-bind": "^1.0.2",
+        "get-intrinsic": "^1.2.1",
+        "has-symbols": "^1.0.3",
+        "isarray": "^2.0.5"
+      },
+      "engines": {
+        "node": ">=0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/safe-regex-test": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.0.tgz",
+      "integrity": "sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA==",
+      "dev": true,
+      "dependencies": {
+        "call-bind": "^1.0.2",
+        "get-intrinsic": "^1.1.3",
+        "is-regex": "^1.1.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/scheduler": {
+      "version": "0.20.2",
+      "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.20.2.tgz",
+      "integrity": "sha512-2eWfGgAqqWFGqtdMmcL5zCMK1U8KlXv8SQFGglL3CEtd0aDVDWgeF/YoCmvln55m5zSk3J/20hTaSBeSObsQDQ==",
+      "peer": true,
+      "dependencies": {
+        "loose-envify": "^1.1.0",
+        "object-assign": "^4.1.1"
+      }
+    },
+    "node_modules/semver": {
+      "version": "6.3.1",
+      "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
+      "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
+      "dev": true,
+      "bin": {
+        "semver": "bin/semver.js"
+      }
+    },
+    "node_modules/set-function-name": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.1.tgz",
+      "integrity": "sha512-tMNCiqYVkXIZgc2Hnoy2IvC/f8ezc5koaRFkCjrpWzGpCd3qbZXPzVy9MAZzK1ch/X0jvSkojys3oqJN0qCmdA==",
+      "dev": true,
+      "dependencies": {
+        "define-data-property": "^1.0.1",
+        "functions-have-names": "^1.2.3",
+        "has-property-descriptors": "^1.0.0"
+      },
+      "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/side-channel": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz",
+      "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==",
+      "dev": true,
+      "dependencies": {
+        "call-bind": "^1.0.0",
+        "get-intrinsic": "^1.0.2",
+        "object-inspect": "^1.9.0"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "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/sort-by": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/sort-by/-/sort-by-1.2.0.tgz",
+      "integrity": "sha512-aRyW65r3xMnf4nxJRluCg0H/woJpksU1dQxRtXYzau30sNBOmf5HACpDd9MZDhKh7ALQ5FgSOfMPwZEtUmMqcg==",
+      "dependencies": {
+        "object-path": "0.6.0"
+      }
+    },
+    "node_modules/source-map-js": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz",
+      "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/space-separated-tokens": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-2.0.2.tgz",
+      "integrity": "sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==",
+      "funding": {
+        "type": "github",
+        "url": "https://github.com/sponsors/wooorm"
+      }
+    },
+    "node_modules/string.prototype.matchall": {
+      "version": "4.0.10",
+      "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.10.tgz",
+      "integrity": "sha512-rGXbGmOEosIQi6Qva94HUjgPs9vKW+dkG7Y8Q5O2OYkWL6wFaTRZO8zM4mhP94uX55wgyrXzfS2aGtGzUL7EJQ==",
+      "dev": true,
+      "dependencies": {
+        "call-bind": "^1.0.2",
+        "define-properties": "^1.2.0",
+        "es-abstract": "^1.22.1",
+        "get-intrinsic": "^1.2.1",
+        "has-symbols": "^1.0.3",
+        "internal-slot": "^1.0.5",
+        "regexp.prototype.flags": "^1.5.0",
+        "set-function-name": "^2.0.0",
+        "side-channel": "^1.0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/string.prototype.trim": {
+      "version": "1.2.8",
+      "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.8.tgz",
+      "integrity": "sha512-lfjY4HcixfQXOfaqCvcBuOIapyaroTXhbkfJN3gcB1OtyupngWK4sEET9Knd0cXd28kTUqu/kHoV4HKSJdnjiQ==",
+      "dev": true,
+      "dependencies": {
+        "call-bind": "^1.0.2",
+        "define-properties": "^1.2.0",
+        "es-abstract": "^1.22.1"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/string.prototype.trimend": {
+      "version": "1.0.7",
+      "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.7.tgz",
+      "integrity": "sha512-Ni79DqeB72ZFq1uH/L6zJ+DKZTkOtPIHovb3YZHQViE+HDouuU4mBrLOLDn5Dde3RF8qw5qVETEjhu9locMLvA==",
+      "dev": true,
+      "dependencies": {
+        "call-bind": "^1.0.2",
+        "define-properties": "^1.2.0",
+        "es-abstract": "^1.22.1"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/string.prototype.trimstart": {
+      "version": "1.0.7",
+      "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.7.tgz",
+      "integrity": "sha512-NGhtDFu3jCEm7B4Fy0DpLewdJQOZcQ0rGbwQ/+stjnrp2i+rlKeCvos9hOIeCmqwratM47OBxY7uFZzjxHXmrg==",
+      "dev": true,
+      "dependencies": {
+        "call-bind": "^1.0.2",
+        "define-properties": "^1.2.0",
+        "es-abstract": "^1.22.1"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/stringify-entities": {
+      "version": "4.0.3",
+      "resolved": "https://registry.npmjs.org/stringify-entities/-/stringify-entities-4.0.3.tgz",
+      "integrity": "sha512-BP9nNHMhhfcMbiuQKCqMjhDP5yBCAxsPu4pHFFzJ6Alo9dZgY4VLDPutXqIjpRiMoKdp7Av85Gr73Q5uH9k7+g==",
+      "dependencies": {
+        "character-entities-html4": "^2.0.0",
+        "character-entities-legacy": "^3.0.0"
+      },
+      "funding": {
+        "type": "github",
+        "url": "https://github.com/sponsors/wooorm"
+      }
+    },
+    "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-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/style-to-object": {
+      "version": "1.0.5",
+      "resolved": "https://registry.npmjs.org/style-to-object/-/style-to-object-1.0.5.tgz",
+      "integrity": "sha512-rDRwHtoDD3UMMrmZ6BzOW0naTjMsVZLIjsGleSKS/0Oz+cgCfAPRspaqJuE8rDzpKha/nEvnM0IF4seEAZUTKQ==",
+      "dependencies": {
+        "inline-style-parser": "0.2.2"
+      }
+    },
+    "node_modules/stylis": {
+      "version": "4.3.0",
+      "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.3.0.tgz",
+      "integrity": "sha512-E87pIogpwUsUwXw7dNyU4QDjdgVMy52m+XEOPEKUn161cCzWjjhPSQhByfd1CcNvrOLnXQ6OnnZDwnJrz/Z4YQ=="
+    },
+    "node_modules/supports-color": {
+      "version": "5.5.0",
+      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+      "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+      "dev": true,
+      "dependencies": {
+        "has-flag": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "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/tabster": {
+      "version": "4.9.0",
+      "resolved": "https://registry.npmjs.org/tabster/-/tabster-4.9.0.tgz",
+      "integrity": "sha512-wcXpMQxLA7OFcL4ci6Spsv0C1S26HtCD4904XTW78mQ2iPsKyo+SdjBUZ4SHhNMpa1y4P1cByc6dPJ0n+9yVzA==",
+      "dependencies": {
+        "keyborg": "^2.0.0",
+        "tslib": "^2.3.1"
+      }
+    },
+    "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/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/trim-lines": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/trim-lines/-/trim-lines-3.0.1.tgz",
+      "integrity": "sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==",
+      "funding": {
+        "type": "github",
+        "url": "https://github.com/sponsors/wooorm"
+      }
+    },
+    "node_modules/trough": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/trough/-/trough-2.1.0.tgz",
+      "integrity": "sha512-AqTiAOLcj85xS7vQ8QkAV41hPDIJ71XJB4RCUrzo/1GM2CQwhkJGaf9Hgr7BOugMRpgGUrqRg/DrBDl4H40+8g==",
+      "funding": {
+        "type": "github",
+        "url": "https://github.com/sponsors/wooorm"
+      }
+    },
+    "node_modules/ts-api-utils": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.0.3.tgz",
+      "integrity": "sha512-wNMeqtMz5NtwpT/UZGY5alT+VoKdSsOOP/kqHFcUW1P/VRhH2wJ48+DN2WwUliNbQ976ETwDL0Ifd2VVvgonvg==",
+      "dev": true,
+      "engines": {
+        "node": ">=16.13.0"
+      },
+      "peerDependencies": {
+        "typescript": ">=4.2.0"
+      }
+    },
+    "node_modules/tslib": {
+      "version": "2.6.2",
+      "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz",
+      "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q=="
+    },
+    "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-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/typed-array-buffer": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.0.tgz",
+      "integrity": "sha512-Y8KTSIglk9OZEr8zywiIHG/kmQ7KWyjseXs1CbSo8vC42w7hg2HgYTxSWwP0+is7bWDc1H+Fo026CpHFwm8tkw==",
+      "dev": true,
+      "dependencies": {
+        "call-bind": "^1.0.2",
+        "get-intrinsic": "^1.2.1",
+        "is-typed-array": "^1.1.10"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
+    "node_modules/typed-array-byte-length": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.0.tgz",
+      "integrity": "sha512-Or/+kvLxNpeQ9DtSydonMxCx+9ZXOswtwJn17SNLvhptaXYDJvkFFP5zbfU/uLmvnBJlI4yrnXRxpdWH/M5tNA==",
+      "dev": true,
+      "dependencies": {
+        "call-bind": "^1.0.2",
+        "for-each": "^0.3.3",
+        "has-proto": "^1.0.1",
+        "is-typed-array": "^1.1.10"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/typed-array-byte-offset": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.0.tgz",
+      "integrity": "sha512-RD97prjEt9EL8YgAgpOkf3O4IF9lhJFr9g0htQkm0rchFp/Vx7LW5Q8fSXXub7BXAODyUQohRMyOc3faCPd0hg==",
+      "dev": true,
+      "dependencies": {
+        "available-typed-arrays": "^1.0.5",
+        "call-bind": "^1.0.2",
+        "for-each": "^0.3.3",
+        "has-proto": "^1.0.1",
+        "is-typed-array": "^1.1.10"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/typed-array-length": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.4.tgz",
+      "integrity": "sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng==",
+      "dev": true,
+      "dependencies": {
+        "call-bind": "^1.0.2",
+        "for-each": "^0.3.3",
+        "is-typed-array": "^1.1.9"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/typescript": {
+      "version": "5.2.2",
+      "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz",
+      "integrity": "sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==",
+      "dev": true,
+      "bin": {
+        "tsc": "bin/tsc",
+        "tsserver": "bin/tsserver"
+      },
+      "engines": {
+        "node": ">=14.17"
+      }
+    },
+    "node_modules/unbox-primitive": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz",
+      "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==",
+      "dev": true,
+      "dependencies": {
+        "call-bind": "^1.0.2",
+        "has-bigints": "^1.0.2",
+        "has-symbols": "^1.0.3",
+        "which-boxed-primitive": "^1.0.2"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/unified": {
+      "version": "11.0.4",
+      "resolved": "https://registry.npmjs.org/unified/-/unified-11.0.4.tgz",
+      "integrity": "sha512-apMPnyLjAX+ty4OrNap7yumyVAMlKx5IWU2wlzzUdYJO9A8f1p9m/gywF/GM2ZDFcjQPrx59Mc90KwmxsoklxQ==",
+      "dependencies": {
+        "@types/unist": "^3.0.0",
+        "bail": "^2.0.0",
+        "devlop": "^1.0.0",
+        "extend": "^3.0.0",
+        "is-plain-obj": "^4.0.0",
+        "trough": "^2.0.0",
+        "vfile": "^6.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/unified"
+      }
+    },
+    "node_modules/unist-util-is": {
+      "version": "6.0.0",
+      "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.0.tgz",
+      "integrity": "sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==",
+      "dependencies": {
+        "@types/unist": "^3.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/unified"
+      }
+    },
+    "node_modules/unist-util-position": {
+      "version": "5.0.0",
+      "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-5.0.0.tgz",
+      "integrity": "sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==",
+      "dependencies": {
+        "@types/unist": "^3.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/unified"
+      }
+    },
+    "node_modules/unist-util-remove-position": {
+      "version": "5.0.0",
+      "resolved": "https://registry.npmjs.org/unist-util-remove-position/-/unist-util-remove-position-5.0.0.tgz",
+      "integrity": "sha512-Hp5Kh3wLxv0PHj9m2yZhhLt58KzPtEYKQQ4yxfYFEO7EvHwzyDYnduhHnY1mDxoqr7VUwVuHXk9RXKIiYS1N8Q==",
+      "dependencies": {
+        "@types/unist": "^3.0.0",
+        "unist-util-visit": "^5.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/unified"
+      }
+    },
+    "node_modules/unist-util-stringify-position": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz",
+      "integrity": "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==",
+      "dependencies": {
+        "@types/unist": "^3.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/unified"
+      }
+    },
+    "node_modules/unist-util-visit": {
+      "version": "5.0.0",
+      "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-5.0.0.tgz",
+      "integrity": "sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==",
+      "dependencies": {
+        "@types/unist": "^3.0.0",
+        "unist-util-is": "^6.0.0",
+        "unist-util-visit-parents": "^6.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/unified"
+      }
+    },
+    "node_modules/unist-util-visit-parents": {
+      "version": "6.0.1",
+      "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-6.0.1.tgz",
+      "integrity": "sha512-L/PqWzfTP9lzzEa6CKs0k2nARxTdZduw3zyh8d2NVBnsyvHjSX4TWse388YrrQKbvI8w20fGjGlhgT96WwKykw==",
+      "dependencies": {
+        "@types/unist": "^3.0.0",
+        "unist-util-is": "^6.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/unified"
+      }
+    },
+    "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/use-disposable": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/use-disposable/-/use-disposable-1.0.2.tgz",
+      "integrity": "sha512-UMaXVlV77dWOu4GqAFNjRzHzowYKUKbJBQfCexvahrYeIz4OkUYUjna4Tjjdf92NH8Nm8J7wEfFRgTIwYjO5jg==",
+      "peerDependencies": {
+        "@types/react": ">=16.8.0 <19.0.0",
+        "@types/react-dom": ">=16.8.0 <19.0.0",
+        "react": ">=16.8.0 <19.0.0",
+        "react-dom": ">=16.8.0 <19.0.0"
+      }
+    },
+    "node_modules/vfile": {
+      "version": "6.0.1",
+      "resolved": "https://registry.npmjs.org/vfile/-/vfile-6.0.1.tgz",
+      "integrity": "sha512-1bYqc7pt6NIADBJ98UiG0Bn/CHIVOoZ/IyEkqIruLg0mE1BKzkOXY2D6CSqQIcKqgadppE5lrxgWXJmXd7zZJw==",
+      "dependencies": {
+        "@types/unist": "^3.0.0",
+        "unist-util-stringify-position": "^4.0.0",
+        "vfile-message": "^4.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/unified"
+      }
+    },
+    "node_modules/vfile-message": {
+      "version": "4.0.2",
+      "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.2.tgz",
+      "integrity": "sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw==",
+      "dependencies": {
+        "@types/unist": "^3.0.0",
+        "unist-util-stringify-position": "^4.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/unified"
+      }
+    },
+    "node_modules/vite": {
+      "version": "4.5.2",
+      "resolved": "https://registry.npmjs.org/vite/-/vite-4.5.2.tgz",
+      "integrity": "sha512-tBCZBNSBbHQkaGyhGCDUGqeo2ph8Fstyp6FMSvTtsXeZSPpSMGlviAOav2hxVTqFcx8Hj/twtWKsMJXNY0xI8w==",
+      "dev": true,
+      "dependencies": {
+        "esbuild": "^0.18.10",
+        "postcss": "^8.4.27",
+        "rollup": "^3.27.1"
+      },
+      "bin": {
+        "vite": "bin/vite.js"
+      },
+      "engines": {
+        "node": "^14.18.0 || >=16.0.0"
+      },
+      "funding": {
+        "url": "https://github.com/vitejs/vite?sponsor=1"
+      },
+      "optionalDependencies": {
+        "fsevents": "~2.3.2"
+      },
+      "peerDependencies": {
+        "@types/node": ">= 14",
+        "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/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/which-boxed-primitive": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz",
+      "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==",
+      "dev": true,
+      "dependencies": {
+        "is-bigint": "^1.0.1",
+        "is-boolean-object": "^1.1.0",
+        "is-number-object": "^1.0.4",
+        "is-string": "^1.0.5",
+        "is-symbol": "^1.0.3"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/which-builtin-type": {
+      "version": "1.1.3",
+      "resolved": "https://registry.npmjs.org/which-builtin-type/-/which-builtin-type-1.1.3.tgz",
+      "integrity": "sha512-YmjsSMDBYsM1CaFiayOVT06+KJeXf0o5M/CAd4o1lTadFAtacTUM49zoYxr/oroopFDfhvN6iEcBxUyc3gvKmw==",
+      "dev": true,
+      "dependencies": {
+        "function.prototype.name": "^1.1.5",
+        "has-tostringtag": "^1.0.0",
+        "is-async-function": "^2.0.0",
+        "is-date-object": "^1.0.5",
+        "is-finalizationregistry": "^1.0.2",
+        "is-generator-function": "^1.0.10",
+        "is-regex": "^1.1.4",
+        "is-weakref": "^1.0.2",
+        "isarray": "^2.0.5",
+        "which-boxed-primitive": "^1.0.2",
+        "which-collection": "^1.0.1",
+        "which-typed-array": "^1.1.9"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/which-collection": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.1.tgz",
+      "integrity": "sha512-W8xeTUwaln8i3K/cY1nGXzdnVZlidBcagyNFtBdD5kxnb4TvGKR7FfSIS3mYpwWS1QUCutfKz8IY8RjftB0+1A==",
+      "dev": true,
+      "dependencies": {
+        "is-map": "^2.0.1",
+        "is-set": "^2.0.1",
+        "is-weakmap": "^2.0.1",
+        "is-weakset": "^2.0.1"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/which-typed-array": {
+      "version": "1.1.11",
+      "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.11.tgz",
+      "integrity": "sha512-qe9UWWpkeG5yzZ0tNYxDmd7vo58HDBc39mZ0xWWpolAGADdFOzkfamWLDxkOWcvHQKVmdTyQdLD4NOfjLWTKew==",
+      "dev": true,
+      "dependencies": {
+        "available-typed-arrays": "^1.0.5",
+        "call-bind": "^1.0.2",
+        "for-each": "^0.3.3",
+        "gopd": "^1.0.1",
+        "has-tostringtag": "^1.0.0"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "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/yallist": {
+      "version": "3.1.1",
+      "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
+      "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==",
+      "dev": true
+    },
+    "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"
+      }
+    },
+    "node_modules/zwitch": {
+      "version": "2.0.4",
+      "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-2.0.4.tgz",
+      "integrity": "sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==",
+      "funding": {
+        "type": "github",
+        "url": "https://github.com/sponsors/wooorm"
+      }
+    }
+  }
+}
diff --git a/client/package.json b/client/package.json
new file mode 100644
index 0000000..7881ade
--- /dev/null
+++ b/client/package.json
@@ -0,0 +1,38 @@
+{
+  "name": "client",
+  "private": true,
+  "version": "0.0.0",
+  "type": "module",
+  "scripts": {
+    "dev": "vite",
+    "build": "vite build",
+    "lint": "eslint . --ext js,jsx --report-unused-disable-directives --max-warnings 0",
+    "preview": "vite preview"
+  },
+  "dependencies": {
+    "@fluentui/react": "^8.115.5",
+    "@fluentui/react-components": "^9.38.0",
+    "dayjs": "^1.11.10",
+    "localforage": "^1.10.0",
+    "localstorage-slim": "^2.7.0",
+    "match-sorter": "^6.3.1",
+    "react": "^18.2.0",
+    "react-dom": "^18.2.0",
+    "react-markdown": "^9.0.1",
+    "react-router-dom": "^6.16.0",
+    "sort-by": "^1.2.0"
+  },
+  "devDependencies": {
+    "@types/react": "^18.2.15",
+    "@types/react-dom": "^18.2.7",
+    "@typescript-eslint/eslint-plugin": "^6.10.0",
+    "@typescript-eslint/parser": "^6.10.0",
+    "@vitejs/plugin-react": "^4.0.3",
+    "eslint": "^8.45.0",
+    "eslint-plugin-react": "^7.32.2",
+    "eslint-plugin-react-hooks": "^4.6.0",
+    "eslint-plugin-react-refresh": "^0.4.3",
+    "typescript": "^5.2.2",
+    "vite": "^4.5.2"
+  }
+}
diff --git a/client/src/Main.tsx b/client/src/Main.tsx
new file mode 100644
index 0000000..a314e35
--- /dev/null
+++ b/client/src/Main.tsx
@@ -0,0 +1,43 @@
+import * as React from "react";
+import * as ReactDOM from "react-dom/client";
+import { createBrowserRouter, RouterProvider } from "react-router-dom";
+import { FluentProvider, webLightTheme } from "@fluentui/react-components";
+
+import Root from "./pages/Root";
+import SessionSearch, { loader as sessionsListLoader } from "./pages/Search";
+import { Chat, action as chatAction } from "./pages/Chat";
+import { About, loader as aboutLoader } from "./pages/About";
+
+const router = createBrowserRouter([
+  {
+    path: "/",
+    element: <Root />,
+    children: [
+      {
+        index: true,
+        element: <Chat />,        
+        action: chatAction,
+      },
+      {
+        index: false,
+        element: <SessionSearch />,
+        path: "/search",
+        loader: sessionsListLoader,
+      },
+      {
+        index: false,
+        element: <About />,
+        path: "/about",
+        loader: aboutLoader,
+      },
+    ],
+  },
+]);
+
+ReactDOM.createRoot(document.getElementById("root")!).render(
+  <React.StrictMode>
+    <FluentProvider theme={webLightTheme}>
+      <RouterProvider router={router} />
+    </FluentProvider>
+  </React.StrictMode>
+);
diff --git a/client/src/api/chat.ts b/client/src/api/chat.ts
new file mode 100644
index 0000000..540bb75
--- /dev/null
+++ b/client/src/api/chat.ts
@@ -0,0 +1,57 @@
+import { AskResponse } from "../models";
+
+type ChatTurn = {
+  userPrompt: string;
+  responseMessage?: string;
+};
+
+type UserQuestion = {
+  question: string;
+  askedOn: Date;
+};
+
+function sleep(ms: number) {
+  return new Promise((resolve) => setTimeout(resolve, ms));
+}
+
+let questionAndAnswers: Record<number, [UserQuestion, AskResponse?]> = {};
+
+export const ask = async (prompt: string) => {
+  const history: ChatTurn[] = [];
+  const currentMessageId = Date.now();
+  const currentQuestion = {
+    question: prompt,
+    askedOn: new Date(),
+  };
+  questionAndAnswers[currentMessageId] = [currentQuestion, undefined];
+
+  for (let id in questionAndAnswers) {
+    const [question, answer] = questionAndAnswers[id];
+    history.push({
+      userPrompt: question.question,
+      responseMessage: answer?.answer,
+    });
+  }
+
+  const response = await fetch("/api/ask", {
+    method: "POST",
+    headers: {
+      "Content-Type": "application/json",
+    },
+    body: JSON.stringify(history),
+  });
+
+  const askResponse: AskResponse = await response.json();
+
+  questionAndAnswers[currentMessageId] = [
+    currentQuestion,
+    {
+      answer: askResponse.answer,
+      thoughts: askResponse.thoughts,
+      dataPoints: askResponse.dataPoints,
+      citationBaseUrl: askResponse.citationBaseUrl,
+    },
+  ];
+
+  return await Promise.resolve(questionAndAnswers);
+};
diff --git a/client/src/api/sessions.ts b/client/src/api/sessions.ts
new file mode 100644
index 0000000..49791ab
--- /dev/null
+++ b/client/src/api/sessions.ts
@@ -0,0 +1,72 @@
+export type ErrorInfo = {
+  errorSource?: string;
+  errorCode?: number;
+  errorMessage: string;
+};
+
+export type SessionInfo = {
+  id: string;
+  external_id: string;
+  title: string;
+  abstract: string;
+  start_time_PST: string;
+  end_time_PST: string;
+  cosine_similarity: number;
+  speakers: string;
+};
+
+export type SessionsResponse = {
+  sessions: SessionInfo[];
+  errorInfo?: ErrorInfo;
+};
+
+export async function getSessions(content: string): Promise<SessionsResponse> {
+  const settings = {
+    method: "post",
+    headers: {
+      Accept: "application/json",
+      "Content-Type": "application/json",
+    },
+    body: JSON.stringify({
+      text: content,
+    }),
+  };
+
+  const response = await fetch("/data-api/rest/find", settings);
+  if (!response.ok) {
+    return {
+      sessions: [],
+      errorInfo: {
+        errorSource: "Server",
+        errorCode: response.status,
+        errorMessage: response.statusText,
+      },
+    };
+  }
+
+  var sessions = [];
+  var errorInfo = undefined;
+  const data = await response.json();
+
+  if (data.value.length > 0) {
+    if (data.value[0].error_code) {
+      errorInfo = {
+        errorSource: data.value[0].error_source as string,
+        errorCode: data.value[0].error_code as number,
+        errorMessage: data.value[0].error_message as string,
+      };
+    } else {
+      sessions = data.value;
+    }
+  }
+
+  return { sessions: sessions, errorInfo: errorInfo };
+}
+
+export async function getSessionsCount(): Promise<number | string> {
+  const response = await fetch("/data-api/rest/sessions-count");
+  if (!response.ok) return "n/a";
+  const data = await response.json();
+  const totalCount = data ? data.value[0].total_sessions : "n/a";
+  return totalCount;
+}
diff --git a/client/src/components/FancyText.tsx b/client/src/components/FancyText.tsx
new file mode 100644
index 0000000..25bab70
--- /dev/null
+++ b/client/src/components/FancyText.tsx
@@ -0,0 +1,36 @@
+import { makeStyles, Text, TextProps } from "@fluentui/react-components";
+
+const useStyles = makeStyles({
+  fancy: {
+    fontSize: "1.125rem",
+    fontFamily: "var(--base-font-family)",
+    fontWeight: 600,
+    fontStyle: "normal",
+    lineHeight: "1.688rem",
+    marginTop: "-0.1rem",
+    textDecorationColor: "none",
+    textDecorationLine: "none",
+    textTransform: "none",
+    color: "var(--color-title-font)",
+  },
+});
+
+export const FancyText = ({
+  children,
+  className,
+  block,
+  as,
+  ...rest
+}: TextProps) => {
+  const classes = useStyles();
+  return (
+    <Text
+      {...rest}
+      className={`${classes.fancy} ${className}`}
+      as="p"
+      block={true}
+    >
+      {children}
+    </Text>
+  );
+};
diff --git a/client/src/components/Header.tsx b/client/src/components/Header.tsx
new file mode 100644
index 0000000..b59952d
--- /dev/null
+++ b/client/src/components/Header.tsx
@@ -0,0 +1,10 @@
+import { Title1 } from "@fluentui/react-components";
+import siteConfig from "../site";
+
+export const Header = () => {
+  return (
+    <Title1>
+      🤖 <a href={siteConfig.website} target="_blank">{siteConfig.name}</a> - Conference AI Assistant      
+    </Title1>
+  );
+};
diff --git a/client/src/components/Navigation.tsx b/client/src/components/Navigation.tsx
new file mode 100644
index 0000000..e1f0785
--- /dev/null
+++ b/client/src/components/Navigation.tsx
@@ -0,0 +1,33 @@
+import { Divider, Tab, TabList } from "@fluentui/react-components";
+import { SearchRegular, ChatRegular, InfoRegular } from "@fluentui/react-icons";
+import { useNavigate } from "react-router-dom";
+
+export const Navigation = () => {
+  const navigate = useNavigate();
+
+  return (
+    <>
+      <TabList
+        onTabSelect={(_, data) => {
+          navigate(data.value === "chat" ? "/" : `/${data.value}`);
+        }}
+        selectedValue={
+          window.location.pathname === "/" ? "chat" : window.location.pathname.substring(1)
+        }
+      >
+        <Tab id="chat" value="chat" icon={<ChatRegular />}>
+          Ask
+        </Tab>
+        <Tab id="search" value="search" icon={<SearchRegular />}>
+          Search
+        </Tab>
+        <Tab id="about" value="about" icon={<InfoRegular />}>
+          About
+        </Tab>
+      </TabList>
+      <div style={{ paddingBottom: "10px" }}></div>
+      <Divider />
+      <div style={{ paddingBottom: "20px" }}></div>
+    </>
+  );
+};
diff --git a/client/src/components/NoSessions.tsx b/client/src/components/NoSessions.tsx
new file mode 100644
index 0000000..5b06ea0
--- /dev/null
+++ b/client/src/components/NoSessions.tsx
@@ -0,0 +1,9 @@
+export function NoSessions() {
+  return (
+    <center>
+      <p>
+        <i>No session found</i>
+      </p>
+    </center>
+  );
+}
diff --git a/client/src/components/PrimaryButton.tsx b/client/src/components/PrimaryButton.tsx
new file mode 100644
index 0000000..d9391f0
--- /dev/null
+++ b/client/src/components/PrimaryButton.tsx
@@ -0,0 +1,21 @@
+import { Button, ButtonProps, makeStyles } from "@fluentui/react-components";
+
+const useStyles = makeStyles({
+  button: {
+    boxShadow: "0 0 1px #0009, 0 1px 2px #0003",
+  },
+});
+
+export const PrimaryButton = ({ children, ...rest }: ButtonProps) => {
+  const classes = useStyles();
+  return (
+    <Button
+      {...rest}
+      type="submit"
+      appearance="primary"
+      className={classes.button}
+    >
+      {children}
+    </Button>
+  );
+};
diff --git a/client/src/components/Session.tsx b/client/src/components/Session.tsx
new file mode 100644
index 0000000..cbdf7d0
--- /dev/null
+++ b/client/src/components/Session.tsx
@@ -0,0 +1,45 @@
+import { SessionInfo } from "../api/sessions";
+import { Text, Title2 } from "@fluentui/react-components";
+import { FancyText } from "./FancyText";
+import dayjs from "dayjs";
+import siteConfig from "../site";
+
+function formatSubtitle(session: SessionInfo) {
+  const speakers = JSON.parse(session.speakers).join(", ");
+
+  const startTime = dayjs(session.start_time_PST);
+  const endTime = dayjs(session.end_time_PST);
+
+  const day = startTime.format("dddd")
+  const start = startTime.format("hh:mm A");
+  const end = endTime.format("hh:mm A");
+
+  return `${speakers} | ${day}, ${start}-${end} | Similarity: ${session.cosine_similarity.toFixed(6)}`;
+}
+
+function formatSessionLink(session: SessionInfo) {
+    const startTime = dayjs(session.start_time_PST);
+
+    const day = startTime.format("D")    
+    const url = new URL(`session-list.aspx?EventDay=${day}`, siteConfig.sessionUrl);
+
+    return url;
+}
+
+export const Session = ({ session }: { session: SessionInfo }) => {
+  return (
+    <div key={session.external_id}>
+      <Title2 as="h2" block={true} style={{ marginBottom: "3px" }}>
+        <a href={formatSessionLink(session)}>
+          {session.title}
+        </a>
+      </Title2>
+      <Text className="session-similarity" weight="bold" size={400}>
+        {formatSubtitle(session)}
+      </Text>
+      <FancyText weight="semibold" size={500} className="abstract" style={{ marginTop: "3px"}}>
+        {session.abstract}
+      </FancyText>
+    </div>
+  );
+};
diff --git a/client/src/components/SessionsList.tsx b/client/src/components/SessionsList.tsx
new file mode 100644
index 0000000..fa05cc1
--- /dev/null
+++ b/client/src/components/SessionsList.tsx
@@ -0,0 +1,12 @@
+import { SessionInfo } from "../api/sessions";
+import { Session } from "./Session";
+
+export const SessionList = ({ sessions }: { sessions: SessionInfo[] }) => {
+  return (
+    <section className="agenda-group">
+      {sessions.map((session) => (
+        <Session session={session} key={session.external_id} />
+      ))}
+    </section>
+  );
+};
diff --git a/client/src/models.ts b/client/src/models.ts
new file mode 100644
index 0000000..aaeabb8
--- /dev/null
+++ b/client/src/models.ts
@@ -0,0 +1,14 @@
+export type SupportingContentRecord = {
+  title: string;
+  content: string;
+  url: string;
+  similarity: number;
+};
+
+export type AskResponse = {
+  answer: string;
+  thoughts?: string;
+  dataPoints: SupportingContentRecord[];
+  citationBaseUrl: string;
+  error?: string | null;
+};
diff --git a/client/src/pages/About.tsx b/client/src/pages/About.tsx
new file mode 100644
index 0000000..2214408
--- /dev/null
+++ b/client/src/pages/About.tsx
@@ -0,0 +1,56 @@
+import { Suspense } from "react";
+import { Await, LoaderFunction, defer, useLoaderData } from "react-router-dom";
+import ls from "localstorage-slim";
+import { getSessionsCount } from "../api/sessions";
+import { FancyText } from "../components/FancyText";
+import siteConfig from "../site";
+
+function showSessionCount(
+  sessionsCount: string | undefined | null = undefined
+) {
+  var sc = sessionsCount;
+  if (sc === undefined) {
+    sc = ls.get("sessionsCount");
+    console.log("sessionsCount", sc);
+  } else {
+    ls.set("sessionsCount", sc, { ttl: 60 * 60 * 24 * 7 });
+  }
+  if (sc == null) {
+    return <FancyText>Loading session count...</FancyText>;
+  }
+  return (
+    <FancyText>
+      There are <a href={siteConfig.website}>{sc} sessions indexed</a> so far.
+    </FancyText>
+  );
+}
+
+export const loader: LoaderFunction = async () => {
+  const sessionsCount = getSessionsCount();
+  return defer({ sessionsCount });
+};
+
+export const About = () => {
+  const { sessionsCount } = useLoaderData() as {
+    sessionsCount: string | number;
+  };
+
+  return (
+    <>
+      <FancyText>
+        Source code and and related articles are <a href="https://github.com/Azure-Samples/azure-sql-db-session-recommender-v2">available on GitHub.</a>{" "}
+        The AI model used generate embeddings is the <i>text-embedding-ada-002</i> and the AI model used to process and generate natural language content is <i>gpt-4 turbo</i>.
+      </FancyText>
+      <Suspense fallback={showSessionCount()}>
+        <Await
+          resolve={sessionsCount}
+          errorElement={
+            <FancyText>Unable to load session count 😥...</FancyText>
+          }
+        >
+          {(sessionsCount) => showSessionCount(sessionsCount)}
+        </Await>
+      </Suspense>
+    </>
+  );
+};
diff --git a/client/src/pages/Chat.tsx b/client/src/pages/Chat.tsx
new file mode 100644
index 0000000..5782ccc
--- /dev/null
+++ b/client/src/pages/Chat.tsx
@@ -0,0 +1,137 @@
+import {
+  Body1,
+  Card,
+  CardHeader,
+  Textarea,
+  TextareaProps,
+  Text,
+  makeStyles,
+  CardFooter,
+  Spinner,
+  Title2
+} from "@fluentui/react-components";
+import { SendRegular } from "@fluentui/react-icons";
+import { useState } from "react";
+import { ActionFunctionArgs, useFetcher } from "react-router-dom";
+import { ask } from "../api/chat";
+import { FancyText } from "../components/FancyText";
+import { PrimaryButton } from "../components/PrimaryButton";
+import ReactMarkdown from "react-markdown";
+
+const useClasses = makeStyles({
+  container: {},
+  chatArea: {},
+  card: {},
+  rm: { marginBottom: "-1em", marginTop: "-1em"},
+  answersArea: { marginTop: "1em"},
+  textarea: { width: "100%", marginBottom: "1rem" },
+});
+
+export async function action({ request }: ActionFunctionArgs) {
+  let formData = await request.formData();
+  const prompt = formData.get("prompt");
+  if (!prompt) {
+    return null;
+  }
+
+  const data = await ask(prompt.toString());
+  return data;
+}
+
+const Answers = ({ data }: { data: Awaited<ReturnType<typeof action>> }) => {
+  if (!data) {
+    return null;
+  }
+  const components = [];
+  const classes = useClasses();
+  
+  var cid:number = 0
+  for (const id in data) { cid = Number(id) }
+  const [question, answer] = data[cid];    
+      
+  components.push(
+    <Card key={cid} className={classes.card}>        
+      <Title2 as="h2" block={true} style={{ marginBottom: "0em", marginTop:"0px" }}>Your question</Title2>
+      <FancyText>
+        {question.question}
+      </FancyText>
+      <Title2 as="h2" block={true} style={{ marginBottom: "0em" }}>My answer</Title2>
+      <FancyText>
+        <ReactMarkdown className={classes.rm}>{answer?.answer}</ReactMarkdown>
+      </FancyText>
+      <Title2 as="h2" block={true} style={{ marginBottom: "0em" }}>My thoughts</Title2>
+      <FancyText>
+        {answer?.thoughts}
+      </FancyText>
+    </Card>
+  );
+
+  return <>{components}</>;
+};
+
+export const Chat = () => {
+  const fetcher = useFetcher<Awaited<ReturnType<typeof action>>>();
+  const classes = useClasses();
+
+  const submitting = fetcher.state !== "idle";
+  const data = fetcher.data;  
+
+  const [prompt, setPrompt] = useState("");
+
+  const onChange: TextareaProps["onChange"] = (_, data) =>
+    setPrompt(() => data.value);
+
+  const onKeyDown: TextareaProps["onKeyDown"] = (e) => {
+    if (!prompt) {
+      return;
+    }
+
+    if (e.key === "Enter" && !e.shiftKey) {
+      const formData = new FormData();
+      formData.append("prompt", prompt);
+      fetcher.submit(formData, { method: "POST" });      
+    }
+  };
+
+  return (
+    <div className={classes.container}>
+      <div>
+        <FancyText>
+          <>
+          Ask questions to the AI model in natural language and get meaningful answers 
+          to help you navigate the conferences sessions and find the best ones for you.           
+          Thanks to <a href="https://en.wikipedia.org/wiki/Prompt_engineering" target="_blank">Prompt Engineering</a> and <a href="https://learn.microsoft.com/en-us/azure/search/retrieval-augmented-generation-overview" target="_blank">Retrieval Augmented Generation (RAG) </a> finding
+          details and recommendations on what session to attend is easier than ever. Please note that the AI model will remember your questions and answers to improve the quality of the answers and get more context on your requests.           
+          If you want to start from scratch, <a href="/">click here</a> or refresh the page.
+          </>
+        </FancyText>        
+      </div>
+      <div className={classes.chatArea}>
+        <fetcher.Form method="POST">
+          <Textarea
+            className={classes.textarea}
+            resize="vertical"
+            size="large"
+            placeholder="Ask a question..."
+            name="prompt"
+            id="prompt"
+            disabled={submitting}
+            onChange={onChange}
+            value={prompt}
+            onKeyDown={onKeyDown}
+          ></Textarea>
+          <PrimaryButton
+            icon={<SendRegular />}
+            disabled={submitting || !prompt}
+          >
+            Ask
+          </PrimaryButton>
+          {submitting && <Spinner label="Thinking..." />}
+        </fetcher.Form>
+      </div>
+      <div className={classes.answersArea}>
+        {!submitting && data && <Answers data={data} />}
+      </div>
+    </div>
+  );
+};
diff --git a/client/src/pages/Root.tsx b/client/src/pages/Root.tsx
new file mode 100644
index 0000000..2a0c472
--- /dev/null
+++ b/client/src/pages/Root.tsx
@@ -0,0 +1,35 @@
+import { Outlet } from "react-router-dom";
+import { makeStyles, shorthands } from "@fluentui/react-components";
+import { Header } from "../components/Header";
+import { Navigation } from "../components/Navigation";
+
+const margin = shorthands.margin("1rem", "3rem", "1rem");
+const useStyles = makeStyles({
+  root: {
+    display: "grid",
+    gridTemplateRows: "auto 1fr",
+    gridTemplateAreas: `
+      "header"
+      "main"
+    `,
+    height: `calc(100vh - ${margin.marginTop} - ${margin.marginBottom})`,
+    ...margin,
+  },
+});
+
+export default function Root() {
+  const classes = useStyles();
+  return (
+    <>
+      <div className={classes.root}>
+        <div>
+          <Header />
+          <Navigation />
+        </div>
+        <div>
+          <Outlet />
+        </div>
+      </div>
+    </>
+  );
+}
diff --git a/client/src/pages/Search.tsx b/client/src/pages/Search.tsx
new file mode 100644
index 0000000..6e7aefb
--- /dev/null
+++ b/client/src/pages/Search.tsx
@@ -0,0 +1,102 @@
+import { Input, Spinner } from "@fluentui/react-components";
+import { Search24Regular } from "@fluentui/react-icons";
+import {
+  Form,
+  LoaderFunction,
+  useLoaderData,
+  useNavigation,
+} from "react-router-dom";
+import { NoSessions } from "../components/NoSessions";
+import { SessionList } from "../components/SessionsList";
+import type { ErrorInfo, SessionInfo } from "../api/sessions";
+import { getSessions } from "../api/sessions";
+import { FancyText } from "../components/FancyText";
+import { PrimaryButton } from "../components/PrimaryButton";
+
+type LoaderData = {
+  sessions: SessionInfo[];
+  searchQuery: string;
+  isSearch: boolean;
+  errorInfo: ErrorInfo | null;
+};
+
+const SEARCH_INPUT_ID = "q";
+
+export const loader: LoaderFunction = async ({ request }) => {
+  const url = new URL(request.url);
+  const searchQuery = url.searchParams.get(SEARCH_INPUT_ID) ?? "";
+  const isSearch = searchQuery !== "";
+
+  if (!isSearch) {
+    return { sessions: [] };
+  }
+
+  let { sessions, errorInfo } = await getSessions(searchQuery);
+  if (!Array.isArray(sessions)) {
+    errorInfo = { errorMessage: "Error: sessions is not an array" };
+    sessions = [];
+  }
+  return { sessions, searchQuery, isSearch, errorInfo };
+};
+
+export default function SessionSearch() {
+  const { sessions, searchQuery, isSearch, errorInfo } = useLoaderData() as LoaderData;
+  const navigation = useNavigation();
+
+  const searching =
+    navigation.location &&
+    new URLSearchParams(navigation.location.search).has(SEARCH_INPUT_ID);
+
+  return (
+    <>
+      <FancyText>
+        <>
+          Use OpenAI to search for interesting sessions. Write the topic you're
+          interested in, and (up to) the top ten most interesting and related
+          session will be returned. The search is done using <a href="https://learn.microsoft.com/en-us/azure/ai-services/openai/concepts/models#embeddings-models" target="_blank">text embeddings</a> and 
+          then using <a href="https://en.wikipedia.org/wiki/Cosine_similarity" target="_blank">cosine similarity</a> to find the most similar sessions.
+        </>
+      </FancyText>
+      <div id="searchbox">
+        <div>
+          <Form id="search-form" role="search">
+            <div>
+              <Input
+                id={SEARCH_INPUT_ID}
+                size="large"                
+                aria-label="Search sessions"
+                placeholder="Search"
+                type="search"
+                name="q"
+                defaultValue={searchQuery}
+                style={{ width: "100%", marginBottom: "1rem" }}
+                autoComplete="off"
+              />
+              <PrimaryButton
+              icon={<Search24Regular />}              
+            >Search</PrimaryButton>
+              
+            </div>
+            {searching && <Spinner label="Searching..." />}
+            <div className="sr-only" aria-live="polite"></div>
+          </Form>
+        </div>
+      </div>
+      <div
+        id="sessions"
+        className={navigation.state === "loading" ? "loading" : ""}
+      >
+        {!errorInfo ? (
+          ""
+        ) : (
+          <p id="error">
+            <i>{"Error" + errorInfo.errorMessage}</i>
+          </p>
+        )}
+        {sessions.length > 0 && <SessionList sessions={sessions} />}
+        {sessions.length === 0 && isSearch && <NoSessions />}
+      </div>
+    </>
+  );
+}
+
diff --git a/client/src/site.ts b/client/src/site.ts
new file mode 100644
index 0000000..d521ed9
--- /dev/null
+++ b/client/src/site.ts
@@ -0,0 +1,7 @@
+const siteConfig = {
+    name: 'VSLive! Las Vegas 2024',
+    website: 'https://vslive.com/events/las-vegas-2024',
+    sessionUrl: 'https://vslive.com/Events/Las-Vegas-2024/Sessions/',
+}
+
+export default siteConfig;
\ No newline at end of file
diff --git a/client/src/user.ts b/client/src/user.ts
new file mode 100644
index 0000000..d153ebf
--- /dev/null
+++ b/client/src/user.ts
@@ -0,0 +1,8 @@
+export async function getUserInfo() 
+{
+    const response = await fetch('/.auth/me');
+    const payload = await response.json();
+    const { clientPrincipal } = payload;
+    return clientPrincipal;
+}
+
diff --git a/client/staticwebapp.config.json b/client/staticwebapp.config.json
new file mode 100644
index 0000000..1e812ac
--- /dev/null
+++ b/client/staticwebapp.config.json
@@ -0,0 +1,5 @@
+{
+    "navigationFallback": {
+        "rewrite": "/"
+    }
+}
\ No newline at end of file
diff --git a/client/tsconfig.json b/client/tsconfig.json
new file mode 100644
index 0000000..a7fc6fb
--- /dev/null
+++ b/client/tsconfig.json
@@ -0,0 +1,25 @@
+{
+  "compilerOptions": {
+    "target": "ES2020",
+    "useDefineForClassFields": true,
+    "lib": ["ES2020", "DOM", "DOM.Iterable"],
+    "module": "ESNext",
+    "skipLibCheck": true,
+
+    /* Bundler mode */
+    "moduleResolution": "bundler",
+    "allowImportingTsExtensions": true,
+    "resolveJsonModule": true,
+    "isolatedModules": true,
+    "noEmit": true,
+    "jsx": "react-jsx",
+
+    /* Linting */
+    "strict": true,
+    "noUnusedLocals": true,
+    "noUnusedParameters": true,
+    "noFallthroughCasesInSwitch": true
+  },
+  "include": ["src"],
+  "references": [{ "path": "./tsconfig.node.json" }]
+}
diff --git a/client/tsconfig.node.json b/client/tsconfig.node.json
new file mode 100644
index 0000000..42872c5
--- /dev/null
+++ b/client/tsconfig.node.json
@@ -0,0 +1,10 @@
+{
+  "compilerOptions": {
+    "composite": true,
+    "skipLibCheck": true,
+    "module": "ESNext",
+    "moduleResolution": "bundler",
+    "allowSyntheticDefaultImports": true
+  },
+  "include": ["vite.config.ts"]
+}
diff --git a/client/vite.config.ts b/client/vite.config.ts
new file mode 100644
index 0000000..5a33944
--- /dev/null
+++ b/client/vite.config.ts
@@ -0,0 +1,7 @@
+import { defineConfig } from 'vite'
+import react from '@vitejs/plugin-react'
+
+// https://vitejs.dev/config/
+export default defineConfig({
+  plugins: [react()],
+})
diff --git a/database/SessionRecommender/Script.PostDeployment.sql b/database/SessionRecommender/Script.PostDeployment.sql
new file mode 100644
index 0000000..2157524
--- /dev/null
+++ b/database/SessionRecommender/Script.PostDeployment.sql
@@ -0,0 +1,7 @@
+-- This file contains SQL statements that will be executed after the build script.
+
+alter table [web].[sessions] enable change_tracking with (track_columns_updated = off);
+go
+
+alter table [web].[speakers] enable change_tracking with (track_columns_updated = off);
+go
diff --git a/database/SessionRecommender/Script.PreDeployment.sql b/database/SessionRecommender/Script.PreDeployment.sql
new file mode 100644
index 0000000..ac90e05
--- /dev/null
+++ b/database/SessionRecommender/Script.PreDeployment.sql
@@ -0,0 +1,15 @@
+if not exists(select * from sys.symmetric_keys where [name] = '##MS_DatabaseMasterKey##')
+begin
+    create master key encryption by password = N'V3RYStr0NGP@ssw0rd!';
+end
+go
+
+if exists(select * from sys.[database_scoped_credentials] where name = '$(OPEN_AI_ENDPOINT)')
+begin
+	drop database scoped credential [$(OPEN_AI_ENDPOINT)];
+end
+go
+
+create database scoped credential [$(OPEN_AI_ENDPOINT)]
+with identity = 'HTTPEndpointHeaders', secret = '{"api-key":"$(OPEN_AI_KEY)"}';
+go
diff --git a/database/SessionRecommender/Security/db_owner.sql b/database/SessionRecommender/Security/db_owner.sql
new file mode 100644
index 0000000..4113d8c
--- /dev/null
+++ b/database/SessionRecommender/Security/db_owner.sql
@@ -0,0 +1 @@
+alter role [db_owner] add member [session_recommender_app];
\ No newline at end of file
diff --git a/database/SessionRecommender/Security/session_recommender_app.sql b/database/SessionRecommender/Security/session_recommender_app.sql
new file mode 100644
index 0000000..beef9d7
--- /dev/null
+++ b/database/SessionRecommender/Security/session_recommender_app.sql
@@ -0,0 +1,2 @@
+create user [session_recommender_app] with password = '$(APP_USER_PASSWORD)';
+go
diff --git a/database/SessionRecommender/Security/web.sql b/database/SessionRecommender/Security/web.sql
new file mode 100644
index 0000000..c9ff839
--- /dev/null
+++ b/database/SessionRecommender/Security/web.sql
@@ -0,0 +1,4 @@
+CREATE SCHEMA [web]
+    AUTHORIZATION [dbo];
+GO
+
diff --git a/database/SessionRecommender/Sequences/global_id.sql b/database/SessionRecommender/Sequences/global_id.sql
new file mode 100644
index 0000000..85ee211
--- /dev/null
+++ b/database/SessionRecommender/Sequences/global_id.sql
@@ -0,0 +1,6 @@
+CREATE SEQUENCE [web].[global_id]
+    AS INT
+    START WITH 1
+    INCREMENT BY 1;
+GO
+
diff --git a/database/SessionRecommender/StoredProcedures/find_sessions.sql b/database/SessionRecommender/StoredProcedures/find_sessions.sql
new file mode 100644
index 0000000..b43cbb9
--- /dev/null
+++ b/database/SessionRecommender/StoredProcedures/find_sessions.sql
@@ -0,0 +1,146 @@
+create procedure [web].[find_sessions]
+@text nvarchar(max),
+@top int = 10,
+@min_similarity decimal(19,16) = 0.75
+as
+if (@text is null) return;
+
+declare @sid as int = -1;
+if (@text like N'***%') begin    
+    set @text = trim(cast(substring(@text, 4, len(@text) - 3) as nvarchar(max)));    
+end else begin
+    insert into web.searched_text (searched_text) values (@text);
+    set @sid = scope_identity();
+end;
+
+declare @startTime as datetime2(7) = sysdatetime()
+
+declare @retval int, @response nvarchar(max);
+declare @payload nvarchar(max);
+set @payload = json_object('input': @text);
+
+begin try
+    exec @retval = sp_invoke_external_rest_endpoint
+        @url = '$(OPEN_AI_ENDPOINT)/openai/deployments/$(OPEN_AI_DEPLOYMENT)/embeddings?api-version=2023-03-15-preview',
+        @method = 'POST',
+        @credential = [$(OPEN_AI_ENDPOINT)],
+        @payload = @payload,
+        @response = @response output;
+end try
+begin catch
+    select 
+        'SQL' as error_source, 
+        error_number() as error_code,
+        error_message() as error_message
+    return;
+end catch
+
+if (@retval != 0) begin
+    select 
+        'OPENAI' as error_source, 
+        json_value(@response, '$.result.error.code') as error_code,
+        json_value(@response, '$.result.error.message') as error_message,
+        @response as error_response
+    return;
+end;
+
+declare @endTime1 as datetime2(7) = sysdatetime();
+update [web].[searched_text] set ms_rest_call = datediff(ms, @startTime, @endTime1) where id = @sid;
+
+with cteVector as
+(
+    select 
+        cast([key] as int) as [vector_value_id],
+        cast([value] as float) as [vector_value]
+    from 
+        openjson(json_query(@response, '$.result.data[0].embedding'))
+),
+cteSimilarSpeakers as 
+(
+    select 
+        v2.id as speaker_id, 
+        -- Optimized as per https://platform.openai.com/docs/guides/embeddings/which-distance-function-should-i-use
+        sum(v1.[vector_value] * v2.[vector_value]) as cosine_similarity
+    from 
+        cteVector v1
+    inner join 
+        web.speakers_embeddings v2 on v1.vector_value_id = v2.vector_value_id
+    group by
+        v2.id
+
+),
+cteSimilar as
+(
+    select 
+        v2.id as session_id, 
+        -- Optimized as per https://platform.openai.com/docs/guides/embeddings/which-distance-function-should-i-use
+        sum(v1.[vector_value] * v2.[vector_value]) as cosine_similarity
+    from 
+        cteVector v1
+    inner join 
+        web.sessions_embeddings v2 on v1.vector_value_id = v2.vector_value_id
+    group by
+        v2.id
+        
+    union all
+
+    select
+        ss.session_id,
+        s.cosine_similarity
+    from
+        web.sessions_speakers ss 
+    inner join
+        cteSimilarSpeakers s on s.speaker_id = ss.speaker_id
+),
+cteSimilar2 as (
+    select
+        *,
+        rn = row_number() over (partition by session_id order by cosine_similarity desc)
+    from
+        cteSimilar
+),
+cteSpeakers as
+(
+    select 
+        session_id, 
+        json_query('["' + string_agg(string_escape(full_name, 'json'), '","') + '"]') as speakers
+    from 
+        web.sessions_speakers ss 
+    inner join 
+        web.speakers sp on sp.id = ss.speaker_id 
+    group by 
+        session_id
+)
+select top(@top)
+    a.id,
+    a.title,
+    a.abstract,
+    a.external_id,
+    a.start_time_PST,
+    a.end_time_PST,
+    a.recording_url,
+    isnull((select top (1) speakers from cteSpeakers where session_id = a.id), '[]') as speakers,
+    r.cosine_similarity
+from 
+    cteSimilar2 r
+inner join 
+    web.sessions a on r.session_id = a.id
+where   
+    r.cosine_similarity > @min_similarity
+and
+    rn = 1
+order by    
+    r.cosine_similarity desc, a.title asc;
+
+declare @rc int = @@rowcount;
+
+declare @endTime2 as datetime2(7) = sysdatetime()
+update 
+    [web].[searched_text] 
+set 
+    ms_vector_search = datediff(ms, @endTime1, @endTime2),
+    found_sessions = @rc
+where 
+    id = @sid
+GO
+
diff --git a/database/SessionRecommender/StoredProcedures/get_sessions_count.sql b/database/SessionRecommender/StoredProcedures/get_sessions_count.sql
new file mode 100644
index 0000000..1590d12
--- /dev/null
+++ b/database/SessionRecommender/StoredProcedures/get_sessions_count.sql
@@ -0,0 +1,5 @@
+create procedure [web].[get_sessions_count]
+as
+select count(*) as total_sessions from [web].[sessions];
+GO
+
diff --git a/database/SessionRecommender/StoredProcedures/upsert_session_embeddings.sql b/database/SessionRecommender/StoredProcedures/upsert_session_embeddings.sql
new file mode 100644
index 0000000..8d83de5
--- /dev/null
+++ b/database/SessionRecommender/StoredProcedures/upsert_session_embeddings.sql
@@ -0,0 +1,23 @@
+
+create procedure [web].[upsert_session_embeddings]
+@id int,
+@embeddings nvarchar(max)
+as
+
+set xact_abort on
+set transaction isolation level serializable
+
+begin transaction
+
+    delete from web.sessions_embeddings 
+    where id = @id
+
+    insert into web.sessions_embeddings
+    select @id, cast([key] as int), cast([value] as float) 
+    from openjson(@embeddings)
+
+    update web.sessions set require_embeddings_update = 0 where id = @id
+
+commit
+GO
+
diff --git a/database/SessionRecommender/StoredProcedures/upsert_speaker_embeddings.sql b/database/SessionRecommender/StoredProcedures/upsert_speaker_embeddings.sql
new file mode 100644
index 0000000..a641df5
--- /dev/null
+++ b/database/SessionRecommender/StoredProcedures/upsert_speaker_embeddings.sql
@@ -0,0 +1,23 @@
+
+create procedure [web].[upsert_speaker_embeddings]
+@id int,
+@embeddings nvarchar(max)
+as
+
+set xact_abort on
+set transaction isolation level serializable
+
+begin transaction
+
+    delete from web.speakers_embeddings 
+    where id = @id
+
+    insert into web.speakers_embeddings
+    select @id, cast([key] as int), cast([value] as float) 
+    from openjson(@embeddings)
+
+    update web.speakers set require_embeddings_update = 0 where id = @id
+
+commit
+GO
+
diff --git a/database/SessionRecommender/Tables/searched_text.sql b/database/SessionRecommender/Tables/searched_text.sql
new file mode 100644
index 0000000..980ca8d
--- /dev/null
+++ b/database/SessionRecommender/Tables/searched_text.sql
@@ -0,0 +1,11 @@
+CREATE TABLE [web].[searched_text] (
+    [id]               INT            IDENTITY (1, 1) NOT NULL,
+    [searched_text]    NVARCHAR (MAX) NOT NULL,
+    [search_datetime]  DATETIME2 (7)  DEFAULT (sysdatetime()) NOT NULL,
+    [ms_rest_call]     INT            NULL,
+    [ms_vector_search] INT            NULL,
+    [found_sessions]   INT            NULL,
+    PRIMARY KEY CLUSTERED ([id] ASC)
+);
+GO
+
diff --git a/database/SessionRecommender/Tables/sessions.sql b/database/SessionRecommender/Tables/sessions.sql
new file mode 100644
index 0000000..991adac
--- /dev/null
+++ b/database/SessionRecommender/Tables/sessions.sql
@@ -0,0 +1,20 @@
+CREATE TABLE [web].[sessions] (
+    [id]                        INT            DEFAULT (NEXT VALUE FOR [web].[global_id]) NOT NULL,
+    [title]                     NVARCHAR (200) NOT NULL,
+    [abstract]                  NVARCHAR (MAX) NOT NULL,
+    [external_id]               VARCHAR (100)  COLLATE Latin1_General_100_BIN2 NULL,
+    [last_fetched]              DATETIME2 (7)  NULL,    
+    [start_time_PST]            DATETIME2 (0)  NULL,
+    [end_time_PST]              DATETIME2 (0)  NULL,
+    [tags]                      NVARCHAR (MAX) NULL,
+    [recording_url]             VARCHAR (1000) NULL,
+    [require_embeddings_update] BIT            DEFAULT ((0)) NOT NULL,
+    [embeddings]                NVARCHAR (MAX) NULL,
+    PRIMARY KEY CLUSTERED ([id] ASC),
+    CHECK (isjson([tags])=(1)),
+    UNIQUE NONCLUSTERED ([title] ASC)
+);
+GO
+
+
+
diff --git a/database/SessionRecommender/Tables/sessions_embeddings.sql b/database/SessionRecommender/Tables/sessions_embeddings.sql
new file mode 100644
index 0000000..4473505
--- /dev/null
+++ b/database/SessionRecommender/Tables/sessions_embeddings.sql
@@ -0,0 +1,12 @@
+CREATE TABLE [web].[sessions_embeddings] (
+    [id]                INT              NOT NULL,
+    [vector_value_id]   INT              NOT NULL,
+    [vector_value]      DECIMAL (19, 16) NOT NULL,
+    CONSTRAINT fk__sessions_embeddings__sessions FOREIGN KEY ([id]) REFERENCES [web].[sessions] ([id])
+);
+GO
+
+CREATE CLUSTERED COLUMNSTORE INDEX [IXCC]
+    ON [web].[sessions_embeddings];
+GO
+
diff --git a/database/SessionRecommender/Tables/sessions_speakers.sql b/database/SessionRecommender/Tables/sessions_speakers.sql
new file mode 100644
index 0000000..2fcbb66
--- /dev/null
+++ b/database/SessionRecommender/Tables/sessions_speakers.sql
@@ -0,0 +1,14 @@
+CREATE TABLE [web].[sessions_speakers] (
+    [session_id] INT NOT NULL,
+    [speaker_id] INT NOT NULL,
+    PRIMARY KEY CLUSTERED ([session_id] ASC, [speaker_id] ASC),
+    CONSTRAINT fk__sessions_speakers__sessions FOREIGN KEY ([session_id]) REFERENCES [web].[sessions] ([id]),
+    CONSTRAINT fk__sessions_speakers__speakers FOREIGN KEY ([speaker_id]) REFERENCES [web].[speakers] ([id])
+);
+GO
+
+
+CREATE NONCLUSTERED INDEX [ix2]
+    ON [web].[sessions_speakers]([speaker_id] ASC);
+GO
+
diff --git a/database/SessionRecommender/Tables/speakers.sql b/database/SessionRecommender/Tables/speakers.sql
new file mode 100644
index 0000000..de21003
--- /dev/null
+++ b/database/SessionRecommender/Tables/speakers.sql
@@ -0,0 +1,12 @@
+CREATE TABLE [web].[speakers] (
+    [id]                            INT            DEFAULT (NEXT VALUE FOR [web].[global_id]) NOT NULL,
+    [external_id]                   VARCHAR (100)  COLLATE Latin1_General_100_BIN2 NULL,
+    [full_name]                     NVARCHAR (100) NOT NULL,
+    [require_embeddings_update]     BIT            DEFAULT ((0)) NOT NULL,
+    [embeddings]                    NVARCHAR (MAX) NULL,
+
+    PRIMARY KEY CLUSTERED ([id] ASC),
+    UNIQUE NONCLUSTERED ([full_name] ASC),
+    CHECK (isjson([embeddings])=(1))
+);
+GO
diff --git a/database/SessionRecommender/Tables/speakers_embeddings.sql b/database/SessionRecommender/Tables/speakers_embeddings.sql
new file mode 100644
index 0000000..6818ccd
--- /dev/null
+++ b/database/SessionRecommender/Tables/speakers_embeddings.sql
@@ -0,0 +1,12 @@
+CREATE TABLE [web].[speakers_embeddings] (
+    [id]      INT              NOT NULL,
+    [vector_value_id] INT              NOT NULL,
+    [vector_value]    DECIMAL (19, 16) NOT NULL,
+    CONSTRAINT fk__speakers_embeddings__speakers FOREIGN KEY ([id]) REFERENCES [web].[speakers] ([id])
+);
+GO
+
+CREATE CLUSTERED COLUMNSTORE INDEX [IXCC]
+    ON [web].[speakers_embeddings];
+GO
+
diff --git a/database/SessionRecommender/Views/last_searches.sql b/database/SessionRecommender/Views/last_searches.sql
new file mode 100644
index 0000000..f5449bc
--- /dev/null
+++ b/database/SessionRecommender/Views/last_searches.sql
@@ -0,0 +1,15 @@
+create view [web].last_searches
+as
+select top (100)
+    id, 
+    searched_text, 
+    switchoffset(search_datetime, '-08:00') as search_datetime_pst, 
+    ms_rest_call, 
+    ms_vector_search, 
+    found_sessions
+from 
+    [web].searched_text 
+order by 
+    id desc
+GO
+
diff --git a/database/SessionRecommender/Views/search_stats.sql b/database/SessionRecommender/Views/search_stats.sql
new file mode 100644
index 0000000..33e5b16
--- /dev/null
+++ b/database/SessionRecommender/Views/search_stats.sql
@@ -0,0 +1,9 @@
+create view [web].search_stats
+as
+select 
+    count(*) as total_searches, 
+    avg(ms_vector_search) as avg_ms_vector_search 
+from 
+    [web].searched_text
+GO
+
diff --git a/database/SessionRecommender/session_recommender_v2.sqlproj b/database/SessionRecommender/session_recommender_v2.sqlproj
new file mode 100644
index 0000000..598afd5
--- /dev/null
+++ b/database/SessionRecommender/session_recommender_v2.sqlproj
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build">
+  <Sdk Name="Microsoft.Build.Sql" Version="0.1.12-preview" />
+  <PropertyGroup>
+    <Name>session_recommender_v2</Name>
+    <ProjectGuid>{A3BB1F3B-AAAF-4735-A73F-46B26F8B66C0}</ProjectGuid>
+    <DSP>Microsoft.Data.Tools.Schema.Sql.SqlAzureV12DatabaseSchemaProvider</DSP>
+    <ModelCollation>1033, CI</ModelCollation>
+    <IsChangeTrackingOn>True</IsChangeTrackingOn>
+  </PropertyGroup>
+  <ItemGroup>
+    <PackageReference Include="Microsoft.SqlServer.Dacpacs.Azure.Master">
+      <Version>160.0.0</Version>
+      <GeneratePathProperty>True</GeneratePathProperty>
+      <DatabaseVariableLiteralValue>master</DatabaseVariableLiteralValue>
+    </PackageReference>
+  </ItemGroup>
+  <ItemGroup>
+    <SqlCmdVariable Include="APP_USER_PASSWORD">
+      <Value>$(SqlCmdVar__4)</Value>
+      <DefaultValue>APP_USER_PASSWORD</DefaultValue>
+    </SqlCmdVariable>
+    <SqlCmdVariable Include="OPEN_AI_ENDPOINT">
+      <Value>$(SqlCmdVar__1)</Value>
+      <DefaultValue>https://dm-open-ai-3.openai.azure.com/</DefaultValue>
+    </SqlCmdVariable>
+    <SqlCmdVariable Include="OPEN_AI_DEPLOYMENT">
+      <Value>$(SqlCmdVar__2)</Value>
+      <DefaultValue>embeddings</DefaultValue>
+    </SqlCmdVariable>
+    <SqlCmdVariable Include="OPEN_AI_KEY">
+      <Value>$(SqlCmdVar__3)</Value>
+      <DefaultValue>
+      </DefaultValue>
+    </SqlCmdVariable>
+  </ItemGroup>
+  <ItemGroup>
+    <PreDeploy Include="Script.PreDeployment.sql" />
+  </ItemGroup>
+  <ItemGroup>
+    <PostDeploy Include="Script.PostDeployment.sql" />
+  </ItemGroup>
+  <Target Name="BeforeBuild">
+    <Delete Files="$(BaseIntermediateOutputPath)\project.assets.json" />
+  </Target>
+  <Target Name="AfterBuild">
+    <Message Text="Copying dacpacs..." Importance="high"/>
+    <Copy SourceFiles="$(OutputPath)\*.dacpac" DestinationFolder="$(OutputPath)\..\..\.."/>
+  </Target>
+</Project>
\ No newline at end of file
diff --git a/database/master.dacpac b/database/master.dacpac
new file mode 100644
index 0000000..bff7866
Binary files /dev/null and b/database/master.dacpac differ
diff --git a/database/session_recommender_v2.dacpac b/database/session_recommender_v2.dacpac
new file mode 100644
index 0000000..7edc6bc
Binary files /dev/null and b/database/session_recommender_v2.dacpac differ
diff --git a/database/setup-database.ps1 b/database/setup-database.ps1
new file mode 100644
index 0000000..466fa8f
--- /dev/null
+++ b/database/setup-database.ps1
@@ -0,0 +1,26 @@
+Invoke-WebRequest -Uri https://aka.ms/sqlpackage-linux -OutFile sqlpackage.zip
+
+Expand-Archive ./sqlpackage.zip sqlpackage/
+
+chmod a+x ./sqlpackage/sqlpackage
+
+./sqlpackage/sqlpackage /version
+
+Write-Host "Downloading dacpacs"
+
+Invoke-WebRequest -Uri https://github.com/azure-samples/azure-sql-db-session-recommender-v2/raw/main/database/session_recommender_v2.dacpac -OutFile session_recommender_v2.dacpac
+Invoke-WebRequest -Uri https://github.com/azure-samples/azure-sql-db-session-recommender-v2/raw/main/database/master.dacpac -OutFile master.dacpac
+
+Write-Host "Deploying database to $Env:DBSERVER with name $Env:DBNAME"
+
+./sqlpackage/sqlpackage `
+    /Action:Publish `
+    /SourceFile:"session_recommender_v2.dacpac" `
+    /TargetDatabaseName:"$Env:DBNAME" `
+    /TargetServerName:"$Env:DBSERVER" `
+    /TargetUser:"$Env:SQLADMIN" `
+    /TargetPassword:"$Env:SQLCMDPASSWORD" `
+    /v:OPEN_AI_ENDPOINT="$Env:OPEN_AI_ENDPOINT" `
+    /v:OPEN_AI_DEPLOYMENT="$Env:OPEN_AI_DEPLOYMENT" `
+    /v:OPEN_AI_KEY="$Env:OPEN_AI_KEY" `
+    /v:APP_USER_PASSWORD="$Env:APP_USER_PASSWORD"
diff --git a/func/.gitignore b/func/.gitignore
new file mode 100644
index 0000000..ff5b00c
--- /dev/null
+++ b/func/.gitignore
@@ -0,0 +1,264 @@
+## Ignore Visual Studio temporary files, build results, and
+## files generated by popular Visual Studio add-ons.
+
+# Azure Functions localsettings file
+local.settings.json
+
+# User-specific files
+*.suo
+*.user
+*.userosscache
+*.sln.docstates
+
+# User-specific files (MonoDevelop/Xamarin Studio)
+*.userprefs
+
+# Build results
+[Dd]ebug/
+[Dd]ebugPublic/
+[Rr]elease/
+[Rr]eleases/
+x64/
+x86/
+bld/
+[Bb]in/
+[Oo]bj/
+[Ll]og/
+
+# Visual Studio 2015 cache/options directory
+.vs/
+# Uncomment if you have tasks that create the project's static files in wwwroot
+#wwwroot/
+
+# MSTest test Results
+[Tt]est[Rr]esult*/
+[Bb]uild[Ll]og.*
+
+# NUNIT
+*.VisualState.xml
+TestResult.xml
+
+# Build Results of an ATL Project
+[Dd]ebugPS/
+[Rr]eleasePS/
+dlldata.c
+
+# DNX
+project.lock.json
+project.fragment.lock.json
+artifacts/
+
+*_i.c
+*_p.c
+*_i.h
+*.ilk
+*.meta
+*.obj
+*.pch
+*.pdb
+*.pgc
+*.pgd
+*.rsp
+*.sbr
+*.tlb
+*.tli
+*.tlh
+*.tmp
+*.tmp_proj
+*.log
+*.vspscc
+*.vssscc
+.builds
+*.pidb
+*.svclog
+*.scc
+
+# Chutzpah Test files
+_Chutzpah*
+
+# Visual C++ cache files
+ipch/
+*.aps
+*.ncb
+*.opendb
+*.opensdf
+*.sdf
+*.cachefile
+*.VC.db
+*.VC.VC.opendb
+
+# Visual Studio profiler
+*.psess
+*.vsp
+*.vspx
+*.sap
+
+# TFS 2012 Local Workspace
+$tf/
+
+# Guidance Automation Toolkit
+*.gpState
+
+# ReSharper is a .NET coding add-in
+_ReSharper*/
+*.[Rr]e[Ss]harper
+*.DotSettings.user
+
+# JustCode is a .NET coding add-in
+.JustCode
+
+# TeamCity is a build add-in
+_TeamCity*
+
+# DotCover is a Code Coverage Tool
+*.dotCover
+
+# NCrunch
+_NCrunch_*
+.*crunch*.local.xml
+nCrunchTemp_*
+
+# MightyMoose
+*.mm.*
+AutoTest.Net/
+
+# Web workbench (sass)
+.sass-cache/
+
+# Installshield output folder
+[Ee]xpress/
+
+# DocProject is a documentation generator add-in
+DocProject/buildhelp/
+DocProject/Help/*.HxT
+DocProject/Help/*.HxC
+DocProject/Help/*.hhc
+DocProject/Help/*.hhk
+DocProject/Help/*.hhp
+DocProject/Help/Html2
+DocProject/Help/html
+
+# Click-Once directory
+publish/
+
+# Publish Web Output
+*.[Pp]ublish.xml
+*.azurePubxml
+# TODO: Comment the next line if you want to checkin your web deploy settings
+# but database connection strings (with potential passwords) will be unencrypted
+#*.pubxml
+*.publishproj
+
+# Microsoft Azure Web App publish settings. Comment the next line if you want to
+# checkin your Azure Web App publish settings, but sensitive information contained
+# in these scripts will be unencrypted
+PublishScripts/
+
+# NuGet Packages
+*.nupkg
+# The packages folder can be ignored because of Package Restore
+**/packages/*
+# except build/, which is used as an MSBuild target.
+!**/packages/build/
+# Uncomment if necessary however generally it will be regenerated when needed
+#!**/packages/repositories.config
+# NuGet v3's project.json files produces more ignoreable files
+*.nuget.props
+*.nuget.targets
+
+# Microsoft Azure Build Output
+csx/
+*.build.csdef
+
+# Microsoft Azure Emulator
+ecf/
+rcf/
+
+# Windows Store app package directories and files
+AppPackages/
+BundleArtifacts/
+Package.StoreAssociation.xml
+_pkginfo.txt
+
+# Visual Studio cache files
+# files ending in .cache can be ignored
+*.[Cc]ache
+# but keep track of directories ending in .cache
+!*.[Cc]ache/
+
+# Others
+ClientBin/
+~$*
+*~
+*.dbmdl
+*.dbproj.schemaview
+*.jfm
+*.pfx
+*.publishsettings
+node_modules/
+orleans.codegen.cs
+
+# Since there are multiple workflows, uncomment next line to ignore bower_components
+# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
+#bower_components/
+
+# RIA/Silverlight projects
+Generated_Code/
+
+# Backup & report files from converting an old project file
+# to a newer Visual Studio version. Backup files are not needed,
+# because we have git ;-)
+_UpgradeReport_Files/
+Backup*/
+UpgradeLog*.XML
+UpgradeLog*.htm
+
+# SQL Server files
+*.mdf
+*.ldf
+
+# Business Intelligence projects
+*.rdl.data
+*.bim.layout
+*.bim_*.settings
+
+# Microsoft Fakes
+FakesAssemblies/
+
+# GhostDoc plugin setting file
+*.GhostDoc.xml
+
+# Node.js Tools for Visual Studio
+.ntvs_analysis.dat
+
+# Visual Studio 6 build log
+*.plg
+
+# Visual Studio 6 workspace options file
+*.opt
+
+# Visual Studio LightSwitch build output
+**/*.HTMLClient/GeneratedArtifacts
+**/*.DesktopClient/GeneratedArtifacts
+**/*.DesktopClient/ModelManifest.xml
+**/*.Server/GeneratedArtifacts
+**/*.Server/ModelManifest.xml
+_Pvt_Extensions
+
+# Paket dependency manager
+.paket/paket.exe
+paket-files/
+
+# FAKE - F# Make
+.fake/
+
+# JetBrains Rider
+.idea/
+*.sln.iml
+
+# CodeRush
+.cr/
+
+# Python Tools for Visual Studio (PTVS)
+__pycache__/
+*.pyc
\ No newline at end of file
diff --git a/func/.vscode/extensions.json b/func/.vscode/extensions.json
new file mode 100644
index 0000000..bb76300
--- /dev/null
+++ b/func/.vscode/extensions.json
@@ -0,0 +1,6 @@
+{
+  "recommendations": [
+    "ms-azuretools.vscode-azurefunctions",
+    "ms-dotnettools.csharp"
+  ]
+}
\ No newline at end of file
diff --git a/func/.vscode/launch.json b/func/.vscode/launch.json
new file mode 100644
index 0000000..894cbe6
--- /dev/null
+++ b/func/.vscode/launch.json
@@ -0,0 +1,11 @@
+{
+    "version": "0.2.0",
+    "configurations": [
+        {
+            "name": "Attach to .NET Functions",
+            "type": "coreclr",
+            "request": "attach",
+            "processId": "${command:azureFunctions.pickProcess}"
+        }
+    ]
+}
\ No newline at end of file
diff --git a/func/.vscode/settings.json b/func/.vscode/settings.json
new file mode 100644
index 0000000..eed4725
--- /dev/null
+++ b/func/.vscode/settings.json
@@ -0,0 +1,7 @@
+{
+    "azureFunctions.deploySubpath": "bin/Release/net8.0/publish",
+    "azureFunctions.projectLanguage": "C#",
+    "azureFunctions.projectRuntime": "~4",
+    "debug.internalConsoleOptions": "neverOpen",
+    "azureFunctions.preDeployTask": "publish (functions)"
+}
\ No newline at end of file
diff --git a/func/.vscode/tasks.json b/func/.vscode/tasks.json
new file mode 100644
index 0000000..5199259
--- /dev/null
+++ b/func/.vscode/tasks.json
@@ -0,0 +1,69 @@
+{
+	"version": "2.0.0",
+	"tasks": [
+		{
+			"label": "clean (functions)",
+			"command": "dotnet",
+			"args": [
+				"clean",
+				"/property:GenerateFullPaths=true",
+				"/consoleloggerparameters:NoSummary"
+			],
+			"type": "process",
+			"problemMatcher": "$msCompile"
+		},
+		{
+			"label": "build (functions)",
+			"command": "dotnet",
+			"args": [
+				"build",
+				"/property:GenerateFullPaths=true",
+				"/consoleloggerparameters:NoSummary"
+			],
+			"type": "process",
+			"dependsOn": "clean (functions)",
+			"group": {
+				"kind": "build",
+				"isDefault": true
+			},
+			"problemMatcher": "$msCompile"
+		},
+		{
+			"label": "clean release (functions)",
+			"command": "dotnet",
+			"args": [
+				"clean",
+				"--configuration",
+				"Release",
+				"/property:GenerateFullPaths=true",
+				"/consoleloggerparameters:NoSummary"
+			],
+			"type": "process",
+			"problemMatcher": "$msCompile"
+		},
+		{
+			"label": "publish (functions)",
+			"command": "dotnet",
+			"args": [
+				"publish",
+				"--configuration",
+				"Release",
+				"/property:GenerateFullPaths=true",
+				"/consoleloggerparameters:NoSummary"
+			],
+			"type": "process",
+			"dependsOn": "clean release (functions)",
+			"problemMatcher": "$msCompile"
+		},
+		{
+			"type": "func",
+			"dependsOn": "build (functions)",
+			"options": {
+				"cwd": "${workspaceFolder}/bin/Debug/net8.0"
+			},
+			"command": "host start",
+			"isBackground": true,
+			"problemMatcher": "$func-dotnet-watch"
+		}
+	]
+}
\ No newline at end of file
diff --git a/func/ChatHandler.cs b/func/ChatHandler.cs
new file mode 100644
index 0000000..6b868cb
--- /dev/null
+++ b/func/ChatHandler.cs
@@ -0,0 +1,123 @@
+using System;
+using System.Data;
+using System.Text.Json;
+using Azure;
+using Azure.AI.OpenAI;
+using Dapper;
+using Microsoft.AspNetCore.Http;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.Azure.Functions.Worker;
+using Microsoft.Data.SqlClient;
+using Microsoft.Extensions.Logging;
+using FromBodyAttribute = Microsoft.Azure.Functions.Worker.Http.FromBodyAttribute;
+
+namespace SessionRecommender.RequestHandler;
+
+public record ChatTurn(string userPrompt, string? responseMessage);
+
+public record FoundSession(
+    int Id, 
+    string Title, 
+    string Abstract,     
+    double Similarity, 
+    //string RecordingUrl, 
+    string Speakers,
+    string ExternalId,
+    DateTimeOffset Start, 
+    DateTimeOffset End
+);
+
+public class ChatHandler(OpenAIClient openAIClient, SqlConnection conn, ILogger<ChatHandler> logger)
+{
+    private readonly string _openAIDeploymentName = Environment.GetEnvironmentVariable("AZURE_OPENAI_GPT_DEPLOYMENT_NAME") ?? "gpt-4";
+
+    private const string SystemMessage = """
+You are a system assistant who helps users find the right session to watch from the conference, based off the sessions that are provided to you.
+
+Sessions will be provided in an assistant message in the format of `title|abstract|speakers|start-time|end-time`. You can use this information to help you answer the user's question.
+""";
+
+    [Function("ChatHandler")]
+    public async Task<IActionResult> AskAsync(
+        [HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = "ask")] HttpRequest req,
+        [FromBody] ChatTurn[] history)
+    {
+        logger.LogInformation("Retrieving similar sessions...");
+
+        DynamicParameters p = new();
+        p.Add("@text", history.Last().userPrompt);
+        p.Add("@top", 25);
+        p.Add("@min_similarity", 0.70);
+
+        using IDataReader foundSessions = await conn.ExecuteReaderAsync("[web].[find_sessions]", commandType: CommandType.StoredProcedure, param: p);
+
+        List<FoundSession> sessions = [];
+        while (foundSessions.Read())
+        {
+            sessions.Add(new(
+                Id: foundSessions.GetInt32(0),
+                Title: foundSessions.GetString(1),
+                Abstract: foundSessions.GetString(2),
+                ExternalId: foundSessions.GetString(3),
+                Start: foundSessions.GetDateTime(4),
+                End: foundSessions.GetDateTime(5),
+                //RecordingUrl: foundSessions.GetString(6),
+                Speakers: foundSessions.GetString(7),
+                Similarity: foundSessions.GetDouble(8)
+            ));
+        }
+
+        logger.LogInformation("Calling GPT...");
+
+        string sessionDescriptions = string.Join("\r", sessions.Select(s => $"{s.Title}|{s.Abstract}|{s.Speakers}|{s.Start}|{s.End}"));
+
+        List<ChatRequestMessage> messages = [new ChatRequestSystemMessage(SystemMessage)];
+
+        foreach (ChatTurn turn in history)
+        {
+            messages.Add(new ChatRequestUserMessage(turn.userPrompt));
+            if (turn.responseMessage is not null)
+            {
+                messages.Add(new ChatRequestAssistantMessage(turn.responseMessage));
+            }
+        }
+
+        messages.Add(new ChatRequestUserMessage($@"## Source ##
+{sessionDescriptions}
+## End ##
+
+You answer needs to divided in two sections: in the first section you'll add the answer to the question.
+In the second section, that must be named exactly '###thoughts###', and you must use the section name as typed, without any changes, you'll write brief thoughts on how you came up with the answer, e.g. what sources you used, what you thought about, etc.
+}}"));
+
+        ChatCompletionsOptions options = new(_openAIDeploymentName, messages);
+
+        try
+        {
+            var answerPayload = await openAIClient.GetChatCompletionsAsync(options);
+            var answerContent = answerPayload.Value.Choices[0].Message.Content;
+            
+            //logger.LogInformation(answerContent);            
+            
+            var answerPieces = answerContent
+                .Replace("###Thoughts###", "###thoughts###", StringComparison.InvariantCultureIgnoreCase)
+                .Replace("### Thoughts ###", "###thoughts###", StringComparison.InvariantCultureIgnoreCase)
+                .Split("###thoughts###", StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries);
+            var answer = answerPieces[0];
+            var thoughts = answerPieces.Length == 2 ? answerPieces[1] : "No thoughts provided.";
+            
+            logger.LogInformation("Done.");
+
+            return new OkObjectResult(new
+            {
+                answer,
+                thoughts                
+            });
+        }
+        catch (Exception e)
+        {
+            logger.LogError(e, "Failed to get answer from OpenAI.");
+            return new BadRequestObjectResult(e.Message);
+        }
+    }
+}
\ No newline at end of file
diff --git a/func/Program.cs b/func/Program.cs
new file mode 100644
index 0000000..f17786c
--- /dev/null
+++ b/func/Program.cs
@@ -0,0 +1,45 @@
+using Azure;
+using Azure.AI.OpenAI;
+using Azure.Identity;
+using Azure.Security.KeyVault.Secrets;
+using Microsoft.Data.SqlClient;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Hosting;
+
+var host = new HostBuilder()
+
+.ConfigureServices(services =>
+{
+    Uri openaiEndPoint = Environment.GetEnvironmentVariable("AZURE_OPENAI_ENDPOINT") is string value &&
+        Uri.TryCreate(value, UriKind.Absolute, out Uri? uri) &&
+        uri is not null
+        ? uri
+        : throw new ArgumentException(
+        $"Unable to parse endpoint URI");
+
+    string? apiKey;
+    var keyVaultEndpoint = Environment.GetEnvironmentVariable("AZURE_KEY_VAULT_ENDPOINT");
+    if (!string.IsNullOrEmpty(keyVaultEndpoint))
+    {
+        var openAIKeyName = Environment.GetEnvironmentVariable("AZURE_OPENAI_KEY");
+        var keyVaultClient = new SecretClient(vaultUri: new Uri(keyVaultEndpoint), credential: new DefaultAzureCredential());
+        apiKey = keyVaultClient.GetSecret(openAIKeyName).Value.Value;
+    }
+    else
+    {
+        apiKey = Environment.GetEnvironmentVariable("AZURE_OPENAI_KEY");
+    }
+
+    OpenAIClient openAIClient = apiKey != null ?
+        new(openaiEndPoint, new AzureKeyCredential(apiKey)) :
+        new(openaiEndPoint, new DefaultAzureCredential());
+
+    services.AddSingleton(openAIClient);
+
+    services.AddTransient((_) => new SqlConnection(Environment.GetEnvironmentVariable("AZURE_SQL_CONNECTION_STRING")));
+
+})
+.ConfigureFunctionsWebApplication()
+.Build();
+
+host.Run();
\ No newline at end of file
diff --git a/func/RequestHandler.csproj b/func/RequestHandler.csproj
new file mode 100644
index 0000000..2a08e4a
--- /dev/null
+++ b/func/RequestHandler.csproj
@@ -0,0 +1,29 @@
+<Project Sdk="Microsoft.NET.Sdk">
+  <PropertyGroup>
+    <TargetFramework>net8.0</TargetFramework>
+    <AzureFunctionsVersion>v4</AzureFunctionsVersion>
+    <OutputType>Exe</OutputType>
+    <ImplicitUsings>enable</ImplicitUsings>
+    <Nullable>enable</Nullable>
+    <LangVersion>preview</LangVersion>
+    <UserSecretsId>f9d76b6e-3000-45fa-8f99-dec6e7819a55</UserSecretsId>
+  </PropertyGroup>
+  <ItemGroup>    
+    <PackageReference Include="Azure.AI.OpenAI" Version="1.0.0-beta.13" />     
+    <PackageReference Include="Azure.Security.KeyVault.Secrets" Version="4.6.0" />    
+    <PackageReference Include="Microsoft.Azure.Functions.Worker.Extensions.Sql" Version="3.0.461" />    
+    <PackageReference Include="Microsoft.Azure.Functions.Worker.Sdk" Version="1.16.3" />
+    <PackageReference Include="Microsoft.Azure.Functions.Worker" Version="1.20.0" />
+    <PackageReference Include="Microsoft.Azure.Functions.Worker.Extensions.Http.AspNetCore" Version="1.1.1" />
+    <PackageReference Include="Dapper" Version="2.1.4" />    
+  </ItemGroup>
+  <ItemGroup>
+    <None Update="host.json">
+      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+    </None>
+    <None Update="local.settings.json">
+      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+      <CopyToPublishDirectory>Never</CopyToPublishDirectory>
+    </None>
+  </ItemGroup>
+</Project>
diff --git a/func/SessionProcessor.cs b/func/SessionProcessor.cs
new file mode 100644
index 0000000..fe69fad
--- /dev/null
+++ b/func/SessionProcessor.cs
@@ -0,0 +1,145 @@
+using Microsoft.Extensions.Logging;
+using Microsoft.Data.SqlClient;
+using System.Data;
+using Dapper;
+using Microsoft.Azure.Functions.Worker;
+using Microsoft.Azure.Functions.Worker.Extensions.Sql;
+using Azure.AI.OpenAI;
+using System.Text.Json;
+using System.Text.Json.Serialization;
+
+namespace SessionRecommender.RequestHandler;
+
+public class Item 
+{
+    public required int Id { get; set; }
+
+    [JsonPropertyName("require_embeddings_update")]
+    public bool RequireEmbeddingsUpdate { get; set; }
+
+    public override bool Equals(object obj)
+    {
+        if (obj is not Item that) return false;         
+        return Id == that.Id;
+    }
+
+    public override int GetHashCode()
+    {
+        return Id.GetHashCode();
+    }
+
+    public override string ToString()
+    {
+        return Id.ToString();
+    }
+}
+
+public class Session: Item
+{
+    public string? Title { get; set; }
+
+    public string? Abstract { get; set; }       
+}
+
+public class Speaker: Item
+{
+    [JsonPropertyName("full_name")]
+    public string? FullName { get; set; }
+}
+
+public class ChangedItem: Item 
+{
+    public SqlChangeOperation Operation { get; set; }        
+    public required string Payload { get; set; }
+}
+
+public class SessionProcessor(OpenAIClient openAIClient, SqlConnection conn, ILogger<SessionProcessor> logger)
+{
+    private readonly string _openAIDeploymentName = Environment.GetEnvironmentVariable("AZURE_OPENAI_EMBEDDINGS_DEPLOYMENT_NAME") ?? "embeddings";
+
+    [Function(nameof(SessionTrigger))]
+    public async Task SessionTrigger(
+        [SqlTrigger("[web].[sessions]", "AZURE_SQL_CONNECTION_STRING")]
+        IReadOnlyList<SqlChange<Session>> changes
+        )
+    {
+        var ci = from c in changes 
+                    where c.Operation != SqlChangeOperation.Delete 
+                    where c.Item.RequireEmbeddingsUpdate == true
+                    select new ChangedItem() { 
+                        Id = c.Item.Id, 
+                        Operation = c.Operation, 
+                        Payload = c.Item.Title + ':' + c.Item.Abstract                       
+                    };
+
+        await ProcessChanges(ci, "web.sessions", "web.upsert_session_embeddings", logger);
+    }
+
+    [Function(nameof(SpeakerTrigger))]
+    public async Task SpeakerTrigger(
+        [SqlTrigger("[web].[speakers]", "AZURE_SQL_CONNECTION_STRING")]
+        IReadOnlyList<SqlChange<Speaker>> changes        
+        )
+    {
+        var ci = from c in changes 
+                    where c.Operation != SqlChangeOperation.Delete 
+                    where c.Item.RequireEmbeddingsUpdate == true
+                    select new ChangedItem() { 
+                        Id = c.Item.Id, 
+                        Operation = c.Operation, 
+                        Payload = c.Item.FullName ?? "",
+                        RequireEmbeddingsUpdate = c.Item.RequireEmbeddingsUpdate
+                    };
+
+        await ProcessChanges(ci, "web.speakers", "web.upsert_speaker_embeddings", logger);          
+    }
+
+    private async Task ProcessChanges(IEnumerable<ChangedItem> changes, string referenceTable, string upsertStoredProcedure, ILogger logger)
+    {
+        var ct = changes.Count();
+        if (ct == 0) {
+            logger.LogInformation($"No useful changes detected on {referenceTable} table.");
+            return;
+        }
+
+        logger.LogInformation($"There are {ct} changes that requires processing on table {referenceTable}.");
+
+        foreach (var change in changes)
+        {
+            logger.LogInformation($"[{referenceTable}:{change.Id}] Processing change for operation: " + change.Operation.ToString());
+
+            var attempts = 0;
+            var embeddingsReceived = false;
+            while (attempts < 3)
+            {
+                attempts++;
+
+                logger.LogInformation($"[{referenceTable}:{change.Id}] Attempt {attempts}/3 to get embeddings.");
+
+                var response = await openAIClient.GetEmbeddingsAsync(
+                    new EmbeddingsOptions(_openAIDeploymentName, [change.Payload])
+                );
+
+                var e = response.Value.Data[0].Embedding;
+                await conn.ExecuteAsync(
+                    upsertStoredProcedure,
+                    commandType: CommandType.StoredProcedure,
+                    param: new
+                    {
+                        @id = change.Id,
+                        @embeddings = JsonSerializer.Serialize(e)
+                    });
+                embeddingsReceived = true;
+
+                logger.LogInformation($"[{referenceTable}:{change.Id}] Done.");                
+
+                break;
+            }
+            if (!embeddingsReceived)
+            {
+                logger.LogInformation($"[{referenceTable}:{change.Id}] Failed to get embeddings.");
+            }
+        }
+    }
+}
+
diff --git a/func/host.json b/func/host.json
new file mode 100644
index 0000000..f93b3ee
--- /dev/null
+++ b/func/host.json
@@ -0,0 +1,12 @@
+{
+    "version": "2.0",
+    "logging": {
+        "applicationInsights": {
+            "samplingSettings": {
+                "isEnabled": true,
+                "excludedTypes": "Request"
+            },
+            "enableLiveMetricsFilters": true
+        }
+    }   
+}
\ No newline at end of file
diff --git a/func/local.settings.json.sample b/func/local.settings.json.sample
new file mode 100644
index 0000000..adc93a0
--- /dev/null
+++ b/func/local.settings.json.sample
@@ -0,0 +1,12 @@
+{
+    "IsEncrypted": false,
+    "Values": {
+        "AzureWebJobsStorage": "UseDevelopmentStorage=true",
+        "FUNCTIONS_WORKER_RUNTIME": "dotnet-isolated",
+        "AZURE_SQL_CONNECTION_STRING": "Server=.database.windows.net;Initial Catalog=;Persist Security Info=False;User ID=session_recommender_app;Password=unEno!h5!&*KP420xds&@P901afb$^M;MultipleActiveResultSets=False;Encrypt=True;Connection Timeout=30;",
+        "AZURE_OPENAI_ENDPOINT": "https://.openai.azure.com/",
+        "AZURE_OPENAI_KEY": "",
+        "AZURE_OPENAI_EMBEDDINGS_DEPLOYMENT_NAME": "embeddings",
+        "AZURE_OPENAI_GPT_DEPLOYMENT_NAME": "gpt"        
+    }
+}
\ No newline at end of file
diff --git a/infra/abbreviations.json b/infra/abbreviations.json
new file mode 100644
index 0000000..0126e6d
--- /dev/null
+++ b/infra/abbreviations.json
@@ -0,0 +1,136 @@
+{
+    "analysisServicesServers": "as",
+    "apiManagementService": "apim-",
+    "appConfigurationConfigurationStores": "appcs-",
+    "appManagedEnvironments": "cae-",
+    "appContainerApps": "ca-",
+    "authorizationPolicyDefinitions": "policy-",
+    "automationAutomationAccounts": "aa-",
+    "blueprintBlueprints": "bp-",
+    "blueprintBlueprintsArtifacts": "bpa-",
+    "cacheRedis": "redis-",
+    "cdnProfiles": "cdnp-",
+    "cdnProfilesEndpoints": "cdne-",
+    "cognitiveServicesAccounts": "cog-",
+    "cognitiveServicesFormRecognizer": "cog-fr-",
+    "cognitiveServicesTextAnalytics": "cog-ta-",
+    "computeAvailabilitySets": "avail-",
+    "computeCloudServices": "cld-",
+    "computeDiskEncryptionSets": "des",
+    "computeDisks": "disk",
+    "computeDisksOs": "osdisk",
+    "computeGalleries": "gal",
+    "computeSnapshots": "snap-",
+    "computeVirtualMachines": "vm",
+    "computeVirtualMachineScaleSets": "vmss-",
+    "containerInstanceContainerGroups": "ci",
+    "containerRegistryRegistries": "cr",
+    "containerServiceManagedClusters": "aks-",
+    "databricksWorkspaces": "dbw-",
+    "dataFactoryFactories": "adf-",
+    "dataLakeAnalyticsAccounts": "dla",
+    "dataLakeStoreAccounts": "dls",
+    "dataMigrationServices": "dms-",
+    "dBforMySQLServers": "mysql-",
+    "dBforPostgreSQLServers": "psql-",
+    "devicesIotHubs": "iot-",
+    "devicesProvisioningServices": "provs-",
+    "devicesProvisioningServicesCertificates": "pcert-",
+    "documentDBDatabaseAccounts": "cosmos-",
+    "eventGridDomains": "evgd-",
+    "eventGridDomainsTopics": "evgt-",
+    "eventGridEventSubscriptions": "evgs-",
+    "eventHubNamespaces": "evhns-",
+    "eventHubNamespacesEventHubs": "evh-",
+    "hdInsightClustersHadoop": "hadoop-",
+    "hdInsightClustersHbase": "hbase-",
+    "hdInsightClustersKafka": "kafka-",
+    "hdInsightClustersMl": "mls-",
+    "hdInsightClustersSpark": "spark-",
+    "hdInsightClustersStorm": "storm-",
+    "hybridComputeMachines": "arcs-",
+    "insightsActionGroups": "ag-",
+    "insightsComponents": "appi-",
+    "keyVaultVaults": "kv-",
+    "kubernetesConnectedClusters": "arck",
+    "kustoClusters": "dec",
+    "kustoClustersDatabases": "dedb",
+    "logicIntegrationAccounts": "ia-",
+    "logicWorkflows": "logic-",
+    "machineLearningServicesWorkspaces": "mlw-",
+    "managedIdentityUserAssignedIdentities": "id-",
+    "managementManagementGroups": "mg-",
+    "migrateAssessmentProjects": "migr-",
+    "networkApplicationGateways": "agw-",
+    "networkApplicationSecurityGroups": "asg-",
+    "networkAzureFirewalls": "afw-",
+    "networkBastionHosts": "bas-",
+    "networkConnections": "con-",
+    "networkDnsZones": "dnsz-",
+    "networkExpressRouteCircuits": "erc-",
+    "networkFirewallPolicies": "afwp-",
+    "networkFirewallPoliciesWebApplication": "waf",
+    "networkFirewallPoliciesRuleGroups": "wafrg",
+    "networkFrontDoors": "fd-",
+    "networkFrontdoorWebApplicationFirewallPolicies": "fdfp-",
+    "networkLoadBalancersExternal": "lbe-",
+    "networkLoadBalancersInternal": "lbi-",
+    "networkLoadBalancersInboundNatRules": "rule-",
+    "networkLocalNetworkGateways": "lgw-",
+    "networkNatGateways": "ng-",
+    "networkNetworkInterfaces": "nic-",
+    "networkNetworkSecurityGroups": "nsg-",
+    "networkNetworkSecurityGroupsSecurityRules": "nsgsr-",
+    "networkNetworkWatchers": "nw-",
+    "networkPrivateDnsZones": "pdnsz-",
+    "networkPrivateLinkServices": "pl-",
+    "networkPublicIPAddresses": "pip-",
+    "networkPublicIPPrefixes": "ippre-",
+    "networkRouteFilters": "rf-",
+    "networkRouteTables": "rt-",
+    "networkRouteTablesRoutes": "udr-",
+    "networkTrafficManagerProfiles": "traf-",
+    "networkVirtualNetworkGateways": "vgw-",
+    "networkVirtualNetworks": "vnet-",
+    "networkVirtualNetworksSubnets": "snet-",
+    "networkVirtualNetworksVirtualNetworkPeerings": "peer-",
+    "networkVirtualWans": "vwan-",
+    "networkVpnGateways": "vpng-",
+    "networkVpnGatewaysVpnConnections": "vcn-",
+    "networkVpnGatewaysVpnSites": "vst-",
+    "notificationHubsNamespaces": "ntfns-",
+    "notificationHubsNamespacesNotificationHubs": "ntf-",
+    "operationalInsightsWorkspaces": "log-",
+    "portalDashboards": "dash-",
+    "powerBIDedicatedCapacities": "pbi-",
+    "purviewAccounts": "pview-",
+    "recoveryServicesVaults": "rsv-",
+    "resourcesResourceGroups": "rg-",
+    "searchSearchServices": "srch-",
+    "serviceBusNamespaces": "sb-",
+    "serviceBusNamespacesQueues": "sbq-",
+    "serviceBusNamespacesTopics": "sbt-",
+    "serviceEndPointPolicies": "se-",
+    "serviceFabricClusters": "sf-",
+    "signalRServiceSignalR": "sigr",
+    "sqlManagedInstances": "sqlmi-",
+    "sqlServers": "sql-",
+    "sqlServersDataWarehouse": "sqldw-",
+    "sqlServersDatabases": "sqldb-",
+    "sqlServersDatabasesStretch": "sqlstrdb-",
+    "storageStorageAccounts": "st",
+    "storageStorageAccountsVm": "stvm",
+    "storSimpleManagers": "ssimp",
+    "streamAnalyticsCluster": "asa-",
+    "synapseWorkspaces": "syn",
+    "synapseWorkspacesAnalyticsWorkspaces": "synw",
+    "synapseWorkspacesSqlPoolsDedicated": "syndp",
+    "synapseWorkspacesSqlPoolsSpark": "synsp",
+    "timeSeriesInsightsEnvironments": "tsi-",
+    "webServerFarms": "plan-",
+    "webSitesAppService": "app-",
+    "webSitesAppServiceEnvironment": "ase-",
+    "webSitesFunctions": "func-",
+    "webStaticSites": "stapp-"
+  }
+  
\ No newline at end of file
diff --git a/infra/app/functions.bicep b/infra/app/functions.bicep
new file mode 100644
index 0000000..5b603a0
--- /dev/null
+++ b/infra/app/functions.bicep
@@ -0,0 +1,49 @@
+param functionAppName string
+param location string = resourceGroup().location
+param hostingPlanId string
+param storageAccountName string
+@secure()
+param sqlConnectionString string
+param keyVaultName string
+param tags object = {}
+param applicationInsightsConnectionString string
+param useKeyVault bool
+param keyVaultEndpoint string = ''
+@secure()
+param openAIEndpoint string
+param openAIKeyName string
+param openAIName string
+param openAIEmebddingDeploymentName string = 'embeddings'
+param openAIGPTDeploymentName string = 'gpt'
+
+module functionApp '../core/host/functions.bicep' = {
+  name: 'function1'
+  params: {
+    location: location
+    alwaysOn: false
+    tags: union(tags, { 'azd-service-name': 'functionapp' })
+    kind: 'functionapp'
+    keyVaultName: keyVaultName
+    appServicePlanId: hostingPlanId
+    name: functionAppName
+    runtimeName: 'dotnet-isolated'
+    runtimeVersion: '8.0'
+    storageAccountName: storageAccountName
+    appSettings: {
+      WEBSITE_CONTENTSHARE: toLower(functionAppName)
+      WEBSITE_CONTENTAZUREFILECONNECTIONSTRING: 'DefaultEndpointsProtocol=https;AccountName=${storageAccountName};EndpointSuffix=${environment().suffixes.storage};AccountKey=${listKeys(resourceId(subscription().subscriptionId, resourceGroup().name, 'Microsoft.Storage/storageAccounts', storageAccountName), '2022-05-01').keys[0].value}'
+      APPLICATIONINSIGHTS_CONNECTION_STRING: applicationInsightsConnectionString
+      AZURE_SQL_CONNECTION_STRING: sqlConnectionString
+      AZURE_OPENAI_ENDPOINT: openAIEndpoint
+      AZURE_OPENAI_KEY: useKeyVault ? openAIKeyName : listKeys(resourceId(subscription().subscriptionId, resourceGroup().name, 'Microsoft.CognitiveServices/accounts', openAIName), '2023-05-01').key1
+      AZURE_OPENAI_EMBEDDINGS_DEPLOYMENT_NAME: openAIEmebddingDeploymentName
+      AZURE_OPENAI_GPT_DEPLOYMENT_NAME: openAIGPTDeploymentName      
+      AZURE_KEY_VAULT_ENDPOINT: useKeyVault ? keyVaultEndpoint : ''
+    }
+  }
+}
+
+output functionAppResourceId string = functionApp.outputs.functionAppResourceId
+output name string = functionApp.outputs.name
+output uri string = functionApp.outputs.uri
+output identityPrincipalId string = functionApp.outputs.identityPrincipalId
diff --git a/infra/app/openai.bicep b/infra/app/openai.bicep
new file mode 100644
index 0000000..f9af5d8
--- /dev/null
+++ b/infra/app/openai.bicep
@@ -0,0 +1,57 @@
+metadata description = 'Creates an Azure Cognitive Services instance.'
+param name string
+param location string = resourceGroup().location
+param tags object = {}
+@description('The custom subdomain name used to access the API. Defaults to the value of the name parameter.')
+param customSubDomainName string = name
+param deployments array = []
+param kind string = 'OpenAI'
+param publicNetworkAccess string = 'Enabled'
+param sku object = {
+  name: 'S0'
+}
+param keyVaultName string
+param useKeyVault bool
+
+resource account 'Microsoft.CognitiveServices/accounts@2023-05-01' = {
+  name: name
+  location: location
+  tags: tags
+  kind: kind
+  properties: {
+    customSubDomainName: customSubDomainName
+    publicNetworkAccess: publicNetworkAccess
+  }
+  sku: sku
+}
+
+@batchSize(1)
+resource deployment 'Microsoft.CognitiveServices/accounts/deployments@2023-05-01' = [for deployment in deployments: {
+  parent: account
+  name: deployment.name
+  properties: {
+    model: deployment.model
+    raiPolicyName: contains(deployment, 'raiPolicyName') ? deployment.raiPolicyName : null
+  }
+  sku: contains(deployment, 'sku') ? deployment.sku : {
+    name: 'Standard'
+    capacity: 20
+  }
+}]
+
+resource keyVault 'Microsoft.KeyVault/vaults@2022-07-01' existing = if (useKeyVault) {
+  name: keyVaultName
+}
+
+resource openAIKey 'Microsoft.KeyVault/vaults/secrets@2022-07-01' = if (useKeyVault) {
+  parent: keyVault
+  name: 'openAIKey'
+  properties: {
+    value: account.listKeys().key1
+  }
+}
+
+output endpoint string = account.properties.endpoint
+output id string = account.id
+output name string = account.name
+output openAIKeyName string = openAIKey.name
diff --git a/infra/app/sqlserver.bicep b/infra/app/sqlserver.bicep
new file mode 100644
index 0000000..82d662f
--- /dev/null
+++ b/infra/app/sqlserver.bicep
@@ -0,0 +1,114 @@
+metadata description = 'Creates an Azure SQL Server instance.'
+param name string
+param location string = resourceGroup().location
+param tags object = {}
+param databaseName string
+param principalId string
+param connectionStringKey string = 'AZURE-SQL-CONNECTION-STRING'
+
+param sqlAdmin string = 'sqlAdmin'
+@secure()
+param sqlAdminPassword string
+
+param appUser string = 'session_recommender_app'
+@secure()
+param appUserPassword string
+
+@secure()
+param openAIEndpoint string
+param openAIDeploymentName string
+param openAIServiceName string
+
+
+resource sqlServer 'Microsoft.Sql/servers@2022-05-01-preview' = {
+  name: name
+  location: location
+  tags: tags
+  properties: {
+    version: '12.0'
+    minimalTlsVersion: '1.2'
+    publicNetworkAccess: 'Enabled'
+    administratorLogin: sqlAdmin
+    administratorLoginPassword: sqlAdminPassword
+  }
+
+  resource database 'databases' = {
+    name: databaseName
+    location: location
+  }
+
+  resource firewall 'firewallRules' = {
+    name: 'Azure Services'
+    properties: {
+      // Allow all clients
+      // Note: range [0.0.0.0-0.0.0.0] means "allow all Azure-hosted clients only".
+      // This is not sufficient, because we also want to allow direct access from developer machine, for debugging purposes.
+      startIpAddress: '0.0.0.0'
+      endIpAddress: '0.0.0.0'
+    }
+  }
+
+  resource symbolicname 'administrators@2022-05-01-preview' = {
+    name: 'ActiveDirectory'
+    properties: {
+      administratorType: 'ActiveDirectory'
+      login: 'EntraAdmin'
+      sid: principalId
+      tenantId: tenant().tenantId
+    }
+  }
+}
+
+resource createDBScript2 'Microsoft.Resources/deploymentScripts@2023-08-01' = {
+  name: '${name}-createDB-script'
+  location: location
+  kind: 'AzurePowerShell'
+  properties: {
+    azPowerShellVersion: '10.0'
+    retentionInterval: 'PT1H' // Retain the script resource for 1 hour after it ends running
+    timeout: 'PT5M' // Five minutes
+    cleanupPreference: 'OnSuccess'
+    environmentVariables: [           
+      {
+        name: 'DBNAME'
+        value: databaseName
+      }
+      {
+        name: 'DBSERVER'
+        value: sqlServer.properties.fullyQualifiedDomainName
+      }
+      {
+        name: 'SQLCMDPASSWORD'
+        secureValue: sqlAdminPassword
+      }
+      {
+        name: 'SQLADMIN'
+        value: sqlAdmin
+      }
+      {
+        name: 'OPEN_AI_ENDPOINT'
+        value: openAIEndpoint
+      }
+      {
+        name: 'OPEN_AI_DEPLOYMENT'
+        value: openAIDeploymentName
+      }
+      {
+        name: 'OPEN_AI_KEY'
+        secureValue: listKeys(resourceId(subscription().subscriptionId, resourceGroup().name, 'Microsoft.CognitiveServices/accounts', openAIServiceName), '2023-05-01').key1
+      }
+      {
+        name: 'APP_USER_PASSWORD'
+        secureValue: appUserPassword
+      }
+    ]
+    scriptContent: loadTextContent('../../database/setup-database.ps1')  
+  }
+}
+
+var connectionString = 'Server=${sqlServer.properties.fullyQualifiedDomainName}; Database=${sqlServer::database.name}; User=${appUser}'
+output connectionStringKey string = connectionStringKey
+output connectionString string = connectionString
+output databaseName string = sqlServer::database.name
+output name string = sqlServer.name
+output id string = sqlServer.id
diff --git a/infra/app/staticwebapp.bicep b/infra/app/staticwebapp.bicep
new file mode 100644
index 0000000..c84003e
--- /dev/null
+++ b/infra/app/staticwebapp.bicep
@@ -0,0 +1,39 @@
+metadata description = 'Creates an Azure Static Web Apps instance.'
+param name string
+param location string = resourceGroup().location
+param tags object = {}
+param sku object = {
+  name: 'Standard'
+  tier: 'Standard'
+}
+param sqlServerLocation string
+param sqlServerId string
+@secure()
+param sqlConnectionString string
+param apiResourceId string
+
+resource web 'Microsoft.Web/staticSites@2022-09-01' = {
+  name: name
+  location: location
+  tags: tags
+  properties: {}
+  sku: sku
+  resource apifunc 'linkedBackends@2022-09-01' = {
+    name: 'default'
+    properties: {
+      backendResourceId: apiResourceId
+      region: location
+    }
+  }
+  resource dbconn 'databaseConnections@2022-09-01' = {
+    name: 'default'
+    properties: {
+      connectionString: sqlConnectionString
+      region: sqlServerLocation
+      resourceId: sqlServerId      
+    }
+  }
+}
+
+output name string = web.name
+output uri string = 'https://${web.properties.defaultHostname}'
diff --git a/infra/core/host/appservice-appsettings.bicep b/infra/core/host/appservice-appsettings.bicep
new file mode 100644
index 0000000..f4b22f8
--- /dev/null
+++ b/infra/core/host/appservice-appsettings.bicep
@@ -0,0 +1,17 @@
+metadata description = 'Updates app settings for an Azure App Service.'
+@description('The name of the app service resource within the current resource group scope')
+param name string
+
+@description('The app settings to be applied to the app service')
+@secure()
+param appSettings object
+
+resource appService 'Microsoft.Web/sites@2022-03-01' existing = {
+  name: name
+}
+
+resource settings 'Microsoft.Web/sites/config@2022-03-01' = {
+  name: 'appsettings'
+  parent: appService
+  properties: appSettings
+}
diff --git a/infra/core/host/appservice.bicep b/infra/core/host/appservice.bicep
new file mode 100644
index 0000000..6580cd2
--- /dev/null
+++ b/infra/core/host/appservice.bicep
@@ -0,0 +1,124 @@
+metadata description = 'Creates an Azure App Service in an existing Azure App Service plan.'
+param name string
+param location string = resourceGroup().location
+param tags object = {}
+
+// Reference Properties
+param applicationInsightsName string = ''
+param appServicePlanId string
+param keyVaultName string = ''
+param managedIdentity bool = !empty(keyVaultName)
+
+// Runtime Properties
+@allowed([
+  'dotnet', 'dotnetcore', 'dotnet-isolated', 'node', 'python', 'java', 'powershell', 'custom'
+])
+param runtimeName string
+param runtimeNameAndVersion string = '${runtimeName}|${runtimeVersion}'
+param runtimeVersion string
+
+// Microsoft.Web/sites Properties
+param kind string = 'app,linux'
+
+// Microsoft.Web/sites/config
+param allowedOrigins array = []
+param alwaysOn bool = true
+param appCommandLine string = ''
+@secure()
+param appSettings object = {}
+param clientAffinityEnabled bool = false
+param enableOryxBuild bool = contains(kind, 'linux')
+param functionAppScaleLimit int = -1
+param linuxFxVersion string = runtimeNameAndVersion
+param minimumElasticInstanceCount int = -1
+param numberOfWorkers int = -1
+param scmDoBuildDuringDeployment bool = false
+param use32BitWorkerProcess bool = false
+param ftpsState string = 'FtpsOnly'
+param healthCheckPath string = ''
+
+resource appService 'Microsoft.Web/sites@2022-03-01' = {
+  name: name
+  location: location
+  tags: tags
+  kind: kind
+  properties: {
+    serverFarmId: appServicePlanId
+    siteConfig: {
+      linuxFxVersion: linuxFxVersion
+      alwaysOn: alwaysOn
+      ftpsState: ftpsState
+      minTlsVersion: '1.2'
+      appCommandLine: appCommandLine
+      numberOfWorkers: numberOfWorkers != -1 ? numberOfWorkers : null
+      minimumElasticInstanceCount: minimumElasticInstanceCount != -1 ? minimumElasticInstanceCount : null
+      use32BitWorkerProcess: use32BitWorkerProcess
+      functionAppScaleLimit: functionAppScaleLimit != -1 ? functionAppScaleLimit : null
+      healthCheckPath: healthCheckPath
+      cors: {
+        allowedOrigins: union([ 'https://portal.azure.com', 'https://ms.portal.azure.com' ], allowedOrigins)
+      }
+    }
+    clientAffinityEnabled: clientAffinityEnabled
+    httpsOnly: true
+  }
+
+  identity: { type: managedIdentity ? 'SystemAssigned' : 'None' }
+
+  resource basicPublishingCredentialsPoliciesFtp 'basicPublishingCredentialsPolicies' = {
+    name: 'ftp'
+    properties: {
+      allow: false
+    }
+  }
+
+  resource basicPublishingCredentialsPoliciesScm 'basicPublishingCredentialsPolicies' = {
+    name: 'scm'
+    properties: {
+      allow: false
+    }
+  }
+}
+
+// Updates to the single Microsoft.sites/web/config resources that need to be performed sequentially
+// sites/web/config 'appsettings'
+module configAppSettings 'appservice-appsettings.bicep' = {
+  name: '${name}-appSettings'
+  params: {
+    name: appService.name
+    appSettings: union(appSettings,
+      {
+        SCM_DO_BUILD_DURING_DEPLOYMENT: string(scmDoBuildDuringDeployment)
+        ENABLE_ORYX_BUILD: string(enableOryxBuild)
+      },
+      runtimeName == 'python' && appCommandLine == '' ? { PYTHON_ENABLE_GUNICORN_MULTIWORKERS: 'true'} : {},
+      !empty(applicationInsightsName) ? { APPLICATIONINSIGHTS_CONNECTION_STRING: applicationInsights.properties.ConnectionString } : {},
+      !empty(keyVaultName) ? { AZURE_KEY_VAULT_ENDPOINT: keyVault.properties.vaultUri } : {})
+  }
+}
+
+// sites/web/config 'logs'
+resource configLogs 'Microsoft.Web/sites/config@2022-03-01' = {
+  name: 'logs'
+  parent: appService
+  properties: {
+    applicationLogs: { fileSystem: { level: 'Verbose' } }
+    detailedErrorMessages: { enabled: true }
+    failedRequestsTracing: { enabled: true }
+    httpLogs: { fileSystem: { enabled: true, retentionInDays: 1, retentionInMb: 35 } }
+  }
+  dependsOn: [configAppSettings]
+}
+
+resource keyVault 'Microsoft.KeyVault/vaults@2022-07-01' existing = if (!(empty(keyVaultName))) {
+  name: keyVaultName
+}
+
+resource applicationInsights 'Microsoft.Insights/components@2020-02-02' existing = if (!empty(applicationInsightsName)) {
+  name: applicationInsightsName
+}
+
+output identityPrincipalId string = managedIdentity ? appService.identity.principalId : ''
+output name string = appService.name
+output uri string = 'https://${appService.properties.defaultHostName}'
+output functionAppResourceId  string = appService.id
diff --git a/infra/core/host/appserviceplan.bicep b/infra/core/host/appserviceplan.bicep
new file mode 100644
index 0000000..2e37e04
--- /dev/null
+++ b/infra/core/host/appserviceplan.bicep
@@ -0,0 +1,22 @@
+metadata description = 'Creates an Azure App Service plan.'
+param name string
+param location string = resourceGroup().location
+param tags object = {}
+
+param kind string = ''
+param reserved bool = true
+param sku object
+
+resource appServicePlan 'Microsoft.Web/serverfarms@2022-03-01' = {
+  name: name
+  location: location
+  tags: tags
+  sku: sku
+  kind: kind
+  properties: {
+    reserved: reserved
+  }
+}
+
+output id string = appServicePlan.id
+output name string = appServicePlan.name
diff --git a/infra/core/host/functions.bicep b/infra/core/host/functions.bicep
new file mode 100644
index 0000000..e57fff7
--- /dev/null
+++ b/infra/core/host/functions.bicep
@@ -0,0 +1,87 @@
+metadata description = 'Creates an Azure Function in an existing Azure App Service plan.'
+param name string
+param location string = resourceGroup().location
+param tags object = {}
+
+// Reference Properties
+param applicationInsightsName string = ''
+param appServicePlanId string
+param keyVaultName string = ''
+param managedIdentity bool = !empty(keyVaultName)
+param storageAccountName string
+
+// Runtime Properties
+@allowed([
+  'dotnet', 'dotnetcore', 'dotnet-isolated', 'node', 'python', 'java', 'powershell', 'custom'
+])
+param runtimeName string
+param runtimeNameAndVersion string = '${runtimeName}|${runtimeVersion}'
+param runtimeVersion string
+
+// Function Settings
+@allowed([
+  '~4', '~3', '~2', '~1'
+])
+param extensionVersion string = '~4'
+
+// Microsoft.Web/sites Properties
+param kind string = 'functionapp,linux'
+
+// Microsoft.Web/sites/config
+param allowedOrigins array = []
+param alwaysOn bool = true
+param appCommandLine string = ''
+@secure()
+param appSettings object = {}
+param clientAffinityEnabled bool = false
+param enableOryxBuild bool = contains(kind, 'linux')
+param functionAppScaleLimit int = -1
+param linuxFxVersion string = runtimeNameAndVersion
+param minimumElasticInstanceCount int = -1
+param numberOfWorkers int = -1
+param scmDoBuildDuringDeployment bool = true
+param use32BitWorkerProcess bool = false
+param healthCheckPath string = ''
+
+module functions 'appservice.bicep' = {
+  name: '${name}-functions'
+  params: {
+    name: name
+    location: location
+    tags: tags
+    allowedOrigins: allowedOrigins
+    alwaysOn: alwaysOn
+    appCommandLine: appCommandLine
+    applicationInsightsName: applicationInsightsName
+    appServicePlanId: appServicePlanId
+    appSettings: union(appSettings, {
+        AzureWebJobsStorage: 'DefaultEndpointsProtocol=https;AccountName=${storage.name};AccountKey=${storage.listKeys().keys[0].value};EndpointSuffix=${environment().suffixes.storage}'
+        FUNCTIONS_EXTENSION_VERSION: extensionVersion
+        FUNCTIONS_WORKER_RUNTIME: runtimeName
+      })
+    clientAffinityEnabled: clientAffinityEnabled
+    enableOryxBuild: enableOryxBuild
+    functionAppScaleLimit: functionAppScaleLimit
+    healthCheckPath: healthCheckPath
+    keyVaultName: keyVaultName
+    kind: kind
+    linuxFxVersion: linuxFxVersion
+    managedIdentity: managedIdentity
+    minimumElasticInstanceCount: minimumElasticInstanceCount
+    numberOfWorkers: numberOfWorkers
+    runtimeName: runtimeName
+    runtimeVersion: runtimeVersion
+    runtimeNameAndVersion: runtimeNameAndVersion
+    scmDoBuildDuringDeployment: scmDoBuildDuringDeployment
+    use32BitWorkerProcess: use32BitWorkerProcess
+  }
+}
+
+resource storage 'Microsoft.Storage/storageAccounts@2021-09-01' existing = {
+  name: storageAccountName
+}
+
+output identityPrincipalId string = managedIdentity ? functions.outputs.identityPrincipalId : ''
+output name string = functions.outputs.name
+output uri string = functions.outputs.uri
+output functionAppResourceId string = functions.outputs.functionAppResourceId
diff --git a/infra/core/monitor/applicationinsights-dashboard.bicep b/infra/core/monitor/applicationinsights-dashboard.bicep
new file mode 100644
index 0000000..d082e66
--- /dev/null
+++ b/infra/core/monitor/applicationinsights-dashboard.bicep
@@ -0,0 +1,1236 @@
+metadata description = 'Creates a dashboard for an Application Insights instance.'
+param name string
+param applicationInsightsName string
+param location string = resourceGroup().location
+param tags object = {}
+
+// 2020-09-01-preview because that is the latest valid version
+resource applicationInsightsDashboard 'Microsoft.Portal/dashboards@2020-09-01-preview' = {
+  name: name
+  location: location
+  tags: tags
+  properties: {
+    lenses: [
+      {
+        order: 0
+        parts: [
+          {
+            position: {
+              x: 0
+              y: 0
+              colSpan: 2
+              rowSpan: 1
+            }
+            metadata: {
+              inputs: [
+                {
+                  name: 'id'
+                  value: '/subscriptions/${subscription().subscriptionId}/resourceGroups/${resourceGroup().name}/providers/Microsoft.Insights/components/${applicationInsights.name}'
+                }
+                {
+                  name: 'Version'
+                  value: '1.0'
+                }
+              ]
+              #disable-next-line BCP036
+              type: 'Extension/AppInsightsExtension/PartType/AspNetOverviewPinnedPart'
+              asset: {
+                idInputName: 'id'
+                type: 'ApplicationInsights'
+              }
+              defaultMenuItemId: 'overview'
+            }
+          }
+          {
+            position: {
+              x: 2
+              y: 0
+              colSpan: 1
+              rowSpan: 1
+            }
+            metadata: {
+              inputs: [
+                {
+                  name: 'ComponentId'
+                  value: {
+                    Name: applicationInsights.name
+                    SubscriptionId: subscription().subscriptionId
+                    ResourceGroup: resourceGroup().name
+                  }
+                }
+                {
+                  name: 'Version'
+                  value: '1.0'
+                }
+              ]
+              #disable-next-line BCP036
+              type: 'Extension/AppInsightsExtension/PartType/ProactiveDetectionAsyncPart'
+              asset: {
+                idInputName: 'ComponentId'
+                type: 'ApplicationInsights'
+              }
+              defaultMenuItemId: 'ProactiveDetection'
+            }
+          }
+          {
+            position: {
+              x: 3
+              y: 0
+              colSpan: 1
+              rowSpan: 1
+            }
+            metadata: {
+              inputs: [
+                {
+                  name: 'ComponentId'
+                  value: {
+                    Name: applicationInsights.name
+                    SubscriptionId: subscription().subscriptionId
+                    ResourceGroup: resourceGroup().name
+                  }
+                }
+                {
+                  name: 'ResourceId'
+                  value: '/subscriptions/${subscription().subscriptionId}/resourceGroups/${resourceGroup().name}/providers/Microsoft.Insights/components/${applicationInsights.name}'
+                }
+              ]
+              #disable-next-line BCP036
+              type: 'Extension/AppInsightsExtension/PartType/QuickPulseButtonSmallPart'
+              asset: {
+                idInputName: 'ComponentId'
+                type: 'ApplicationInsights'
+              }
+            }
+          }
+          {
+            position: {
+              x: 4
+              y: 0
+              colSpan: 1
+              rowSpan: 1
+            }
+            metadata: {
+              inputs: [
+                {
+                  name: 'ComponentId'
+                  value: {
+                    Name: applicationInsights.name
+                    SubscriptionId: subscription().subscriptionId
+                    ResourceGroup: resourceGroup().name
+                  }
+                }
+                {
+                  name: 'TimeContext'
+                  value: {
+                    durationMs: 86400000
+                    endTime: null
+                    createdTime: '2018-05-04T01:20:33.345Z'
+                    isInitialTime: true
+                    grain: 1
+                    useDashboardTimeRange: false
+                  }
+                }
+                {
+                  name: 'Version'
+                  value: '1.0'
+                }
+              ]
+              #disable-next-line BCP036
+              type: 'Extension/AppInsightsExtension/PartType/AvailabilityNavButtonPart'
+              asset: {
+                idInputName: 'ComponentId'
+                type: 'ApplicationInsights'
+              }
+            }
+          }
+          {
+            position: {
+              x: 5
+              y: 0
+              colSpan: 1
+              rowSpan: 1
+            }
+            metadata: {
+              inputs: [
+                {
+                  name: 'ComponentId'
+                  value: {
+                    Name: applicationInsights.name
+                    SubscriptionId: subscription().subscriptionId
+                    ResourceGroup: resourceGroup().name
+                  }
+                }
+                {
+                  name: 'TimeContext'
+                  value: {
+                    durationMs: 86400000
+                    endTime: null
+                    createdTime: '2018-05-08T18:47:35.237Z'
+                    isInitialTime: true
+                    grain: 1
+                    useDashboardTimeRange: false
+                  }
+                }
+                {
+                  name: 'ConfigurationId'
+                  value: '78ce933e-e864-4b05-a27b-71fd55a6afad'
+                }
+              ]
+              #disable-next-line BCP036
+              type: 'Extension/AppInsightsExtension/PartType/AppMapButtonPart'
+              asset: {
+                idInputName: 'ComponentId'
+                type: 'ApplicationInsights'
+              }
+            }
+          }
+          {
+            position: {
+              x: 0
+              y: 1
+              colSpan: 3
+              rowSpan: 1
+            }
+            metadata: {
+              inputs: []
+              type: 'Extension/HubsExtension/PartType/MarkdownPart'
+              settings: {
+                content: {
+                  settings: {
+                    content: '# Usage'
+                    title: ''
+                    subtitle: ''
+                  }
+                }
+              }
+            }
+          }
+          {
+            position: {
+              x: 3
+              y: 1
+              colSpan: 1
+              rowSpan: 1
+            }
+            metadata: {
+              inputs: [
+                {
+                  name: 'ComponentId'
+                  value: {
+                    Name: applicationInsights.name
+                    SubscriptionId: subscription().subscriptionId
+                    ResourceGroup: resourceGroup().name
+                  }
+                }
+                {
+                  name: 'TimeContext'
+                  value: {
+                    durationMs: 86400000
+                    endTime: null
+                    createdTime: '2018-05-04T01:22:35.782Z'
+                    isInitialTime: true
+                    grain: 1
+                    useDashboardTimeRange: false
+                  }
+                }
+              ]
+              #disable-next-line BCP036
+              type: 'Extension/AppInsightsExtension/PartType/UsageUsersOverviewPart'
+              asset: {
+                idInputName: 'ComponentId'
+                type: 'ApplicationInsights'
+              }
+            }
+          }
+          {
+            position: {
+              x: 4
+              y: 1
+              colSpan: 3
+              rowSpan: 1
+            }
+            metadata: {
+              inputs: []
+              type: 'Extension/HubsExtension/PartType/MarkdownPart'
+              settings: {
+                content: {
+                  settings: {
+                    content: '# Reliability'
+                    title: ''
+                    subtitle: ''
+                  }
+                }
+              }
+            }
+          }
+          {
+            position: {
+              x: 7
+              y: 1
+              colSpan: 1
+              rowSpan: 1
+            }
+            metadata: {
+              inputs: [
+                {
+                  name: 'ResourceId'
+                  value: '/subscriptions/${subscription().subscriptionId}/resourceGroups/${resourceGroup().name}/providers/Microsoft.Insights/components/${applicationInsights.name}'
+                }
+                {
+                  name: 'DataModel'
+                  value: {
+                    version: '1.0.0'
+                    timeContext: {
+                      durationMs: 86400000
+                      createdTime: '2018-05-04T23:42:40.072Z'
+                      isInitialTime: false
+                      grain: 1
+                      useDashboardTimeRange: false
+                    }
+                  }
+                  isOptional: true
+                }
+                {
+                  name: 'ConfigurationId'
+                  value: '8a02f7bf-ac0f-40e1-afe9-f0e72cfee77f'
+                  isOptional: true
+                }
+              ]
+              #disable-next-line BCP036
+              type: 'Extension/AppInsightsExtension/PartType/CuratedBladeFailuresPinnedPart'
+              isAdapter: true
+              asset: {
+                idInputName: 'ResourceId'
+                type: 'ApplicationInsights'
+              }
+              defaultMenuItemId: 'failures'
+            }
+          }
+          {
+            position: {
+              x: 8
+              y: 1
+              colSpan: 3
+              rowSpan: 1
+            }
+            metadata: {
+              inputs: []
+              type: 'Extension/HubsExtension/PartType/MarkdownPart'
+              settings: {
+                content: {
+                  settings: {
+                    content: '# Responsiveness\r\n'
+                    title: ''
+                    subtitle: ''
+                  }
+                }
+              }
+            }
+          }
+          {
+            position: {
+              x: 11
+              y: 1
+              colSpan: 1
+              rowSpan: 1
+            }
+            metadata: {
+              inputs: [
+                {
+                  name: 'ResourceId'
+                  value: '/subscriptions/${subscription().subscriptionId}/resourceGroups/${resourceGroup().name}/providers/Microsoft.Insights/components/${applicationInsights.name}'
+                }
+                {
+                  name: 'DataModel'
+                  value: {
+                    version: '1.0.0'
+                    timeContext: {
+                      durationMs: 86400000
+                      createdTime: '2018-05-04T23:43:37.804Z'
+                      isInitialTime: false
+                      grain: 1
+                      useDashboardTimeRange: false
+                    }
+                  }
+                  isOptional: true
+                }
+                {
+                  name: 'ConfigurationId'
+                  value: '2a8ede4f-2bee-4b9c-aed9-2db0e8a01865'
+                  isOptional: true
+                }
+              ]
+              #disable-next-line BCP036
+              type: 'Extension/AppInsightsExtension/PartType/CuratedBladePerformancePinnedPart'
+              isAdapter: true
+              asset: {
+                idInputName: 'ResourceId'
+                type: 'ApplicationInsights'
+              }
+              defaultMenuItemId: 'performance'
+            }
+          }
+          {
+            position: {
+              x: 12
+              y: 1
+              colSpan: 3
+              rowSpan: 1
+            }
+            metadata: {
+              inputs: []
+              type: 'Extension/HubsExtension/PartType/MarkdownPart'
+              settings: {
+                content: {
+                  settings: {
+                    content: '# Browser'
+                    title: ''
+                    subtitle: ''
+                  }
+                }
+              }
+            }
+          }
+          {
+            position: {
+              x: 15
+              y: 1
+              colSpan: 1
+              rowSpan: 1
+            }
+            metadata: {
+              inputs: [
+                {
+                  name: 'ComponentId'
+                  value: {
+                    Name: applicationInsights.name
+                    SubscriptionId: subscription().subscriptionId
+                    ResourceGroup: resourceGroup().name
+                  }
+                }
+                {
+                  name: 'MetricsExplorerJsonDefinitionId'
+                  value: 'BrowserPerformanceTimelineMetrics'
+                }
+                {
+                  name: 'TimeContext'
+                  value: {
+                    durationMs: 86400000
+                    createdTime: '2018-05-08T12:16:27.534Z'
+                    isInitialTime: false
+                    grain: 1
+                    useDashboardTimeRange: false
+                  }
+                }
+                {
+                  name: 'CurrentFilter'
+                  value: {
+                    eventTypes: [
+                      4
+                      1
+                      3
+                      5
+                      2
+                      6
+                      13
+                    ]
+                    typeFacets: {}
+                    isPermissive: false
+                  }
+                }
+                {
+                  name: 'id'
+                  value: {
+                    Name: applicationInsights.name
+                    SubscriptionId: subscription().subscriptionId
+                    ResourceGroup: resourceGroup().name
+                  }
+                }
+                {
+                  name: 'Version'
+                  value: '1.0'
+                }
+              ]
+              #disable-next-line BCP036
+              type: 'Extension/AppInsightsExtension/PartType/MetricsExplorerBladePinnedPart'
+              asset: {
+                idInputName: 'ComponentId'
+                type: 'ApplicationInsights'
+              }
+              defaultMenuItemId: 'browser'
+            }
+          }
+          {
+            position: {
+              x: 0
+              y: 2
+              colSpan: 4
+              rowSpan: 3
+            }
+            metadata: {
+              inputs: [
+                {
+                  name: 'options'
+                  value: {
+                    chart: {
+                      metrics: [
+                        {
+                          resourceMetadata: {
+                            id: '/subscriptions/${subscription().subscriptionId}/resourceGroups/${resourceGroup().name}/providers/Microsoft.Insights/components/${applicationInsights.name}'
+                          }
+                          name: 'sessions/count'
+                          aggregationType: 5
+                          namespace: 'microsoft.insights/components/kusto'
+                          metricVisualization: {
+                            displayName: 'Sessions'
+                            color: '#47BDF5'
+                          }
+                        }
+                        {
+                          resourceMetadata: {
+                            id: '/subscriptions/${subscription().subscriptionId}/resourceGroups/${resourceGroup().name}/providers/Microsoft.Insights/components/${applicationInsights.name}'
+                          }
+                          name: 'users/count'
+                          aggregationType: 5
+                          namespace: 'microsoft.insights/components/kusto'
+                          metricVisualization: {
+                            displayName: 'Users'
+                            color: '#7E58FF'
+                          }
+                        }
+                      ]
+                      title: 'Unique sessions and users'
+                      visualization: {
+                        chartType: 2
+                        legendVisualization: {
+                          isVisible: true
+                          position: 2
+                          hideSubtitle: false
+                        }
+                        axisVisualization: {
+                          x: {
+                            isVisible: true
+                            axisType: 2
+                          }
+                          y: {
+                            isVisible: true
+                            axisType: 1
+                          }
+                        }
+                      }
+                      openBladeOnClick: {
+                        openBlade: true
+                        destinationBlade: {
+                          extensionName: 'HubsExtension'
+                          bladeName: 'ResourceMenuBlade'
+                          parameters: {
+                            id: '/subscriptions/${subscription().subscriptionId}/resourceGroups/${resourceGroup().name}/providers/Microsoft.Insights/components/${applicationInsights.name}'
+                            menuid: 'segmentationUsers'
+                          }
+                        }
+                      }
+                    }
+                  }
+                }
+                {
+                  name: 'sharedTimeRange'
+                  isOptional: true
+                }
+              ]
+              #disable-next-line BCP036
+              type: 'Extension/HubsExtension/PartType/MonitorChartPart'
+              settings: {}
+            }
+          }
+          {
+            position: {
+              x: 4
+              y: 2
+              colSpan: 4
+              rowSpan: 3
+            }
+            metadata: {
+              inputs: [
+                {
+                  name: 'options'
+                  value: {
+                    chart: {
+                      metrics: [
+                        {
+                          resourceMetadata: {
+                            id: '/subscriptions/${subscription().subscriptionId}/resourceGroups/${resourceGroup().name}/providers/Microsoft.Insights/components/${applicationInsights.name}'
+                          }
+                          name: 'requests/failed'
+                          aggregationType: 7
+                          namespace: 'microsoft.insights/components'
+                          metricVisualization: {
+                            displayName: 'Failed requests'
+                            color: '#EC008C'
+                          }
+                        }
+                      ]
+                      title: 'Failed requests'
+                      visualization: {
+                        chartType: 3
+                        legendVisualization: {
+                          isVisible: true
+                          position: 2
+                          hideSubtitle: false
+                        }
+                        axisVisualization: {
+                          x: {
+                            isVisible: true
+                            axisType: 2
+                          }
+                          y: {
+                            isVisible: true
+                            axisType: 1
+                          }
+                        }
+                      }
+                      openBladeOnClick: {
+                        openBlade: true
+                        destinationBlade: {
+                          extensionName: 'HubsExtension'
+                          bladeName: 'ResourceMenuBlade'
+                          parameters: {
+                            id: '/subscriptions/${subscription().subscriptionId}/resourceGroups/${resourceGroup().name}/providers/Microsoft.Insights/components/${applicationInsights.name}'
+                            menuid: 'failures'
+                          }
+                        }
+                      }
+                    }
+                  }
+                }
+                {
+                  name: 'sharedTimeRange'
+                  isOptional: true
+                }
+              ]
+              #disable-next-line BCP036
+              type: 'Extension/HubsExtension/PartType/MonitorChartPart'
+              settings: {}
+            }
+          }
+          {
+            position: {
+              x: 8
+              y: 2
+              colSpan: 4
+              rowSpan: 3
+            }
+            metadata: {
+              inputs: [
+                {
+                  name: 'options'
+                  value: {
+                    chart: {
+                      metrics: [
+                        {
+                          resourceMetadata: {
+                            id: '/subscriptions/${subscription().subscriptionId}/resourceGroups/${resourceGroup().name}/providers/Microsoft.Insights/components/${applicationInsights.name}'
+                          }
+                          name: 'requests/duration'
+                          aggregationType: 4
+                          namespace: 'microsoft.insights/components'
+                          metricVisualization: {
+                            displayName: 'Server response time'
+                            color: '#00BCF2'
+                          }
+                        }
+                      ]
+                      title: 'Server response time'
+                      visualization: {
+                        chartType: 2
+                        legendVisualization: {
+                          isVisible: true
+                          position: 2
+                          hideSubtitle: false
+                        }
+                        axisVisualization: {
+                          x: {
+                            isVisible: true
+                            axisType: 2
+                          }
+                          y: {
+                            isVisible: true
+                            axisType: 1
+                          }
+                        }
+                      }
+                      openBladeOnClick: {
+                        openBlade: true
+                        destinationBlade: {
+                          extensionName: 'HubsExtension'
+                          bladeName: 'ResourceMenuBlade'
+                          parameters: {
+                            id: '/subscriptions/${subscription().subscriptionId}/resourceGroups/${resourceGroup().name}/providers/Microsoft.Insights/components/${applicationInsights.name}'
+                            menuid: 'performance'
+                          }
+                        }
+                      }
+                    }
+                  }
+                }
+                {
+                  name: 'sharedTimeRange'
+                  isOptional: true
+                }
+              ]
+              #disable-next-line BCP036
+              type: 'Extension/HubsExtension/PartType/MonitorChartPart'
+              settings: {}
+            }
+          }
+          {
+            position: {
+              x: 12
+              y: 2
+              colSpan: 4
+              rowSpan: 3
+            }
+            metadata: {
+              inputs: [
+                {
+                  name: 'options'
+                  value: {
+                    chart: {
+                      metrics: [
+                        {
+                          resourceMetadata: {
+                            id: '/subscriptions/${subscription().subscriptionId}/resourceGroups/${resourceGroup().name}/providers/Microsoft.Insights/components/${applicationInsights.name}'
+                          }
+                          name: 'browserTimings/networkDuration'
+                          aggregationType: 4
+                          namespace: 'microsoft.insights/components'
+                          metricVisualization: {
+                            displayName: 'Page load network connect time'
+                            color: '#7E58FF'
+                          }
+                        }
+                        {
+                          resourceMetadata: {
+                            id: '/subscriptions/${subscription().subscriptionId}/resourceGroups/${resourceGroup().name}/providers/Microsoft.Insights/components/${applicationInsights.name}'
+                          }
+                          name: 'browserTimings/processingDuration'
+                          aggregationType: 4
+                          namespace: 'microsoft.insights/components'
+                          metricVisualization: {
+                            displayName: 'Client processing time'
+                            color: '#44F1C8'
+                          }
+                        }
+                        {
+                          resourceMetadata: {
+                            id: '/subscriptions/${subscription().subscriptionId}/resourceGroups/${resourceGroup().name}/providers/Microsoft.Insights/components/${applicationInsights.name}'
+                          }
+                          name: 'browserTimings/sendDuration'
+                          aggregationType: 4
+                          namespace: 'microsoft.insights/components'
+                          metricVisualization: {
+                            displayName: 'Send request time'
+                            color: '#EB9371'
+                          }
+                        }
+                        {
+                          resourceMetadata: {
+                            id: '/subscriptions/${subscription().subscriptionId}/resourceGroups/${resourceGroup().name}/providers/Microsoft.Insights/components/${applicationInsights.name}'
+                          }
+                          name: 'browserTimings/receiveDuration'
+                          aggregationType: 4
+                          namespace: 'microsoft.insights/components'
+                          metricVisualization: {
+                            displayName: 'Receiving response time'
+                            color: '#0672F1'
+                          }
+                        }
+                      ]
+                      title: 'Average page load time breakdown'
+                      visualization: {
+                        chartType: 3
+                        legendVisualization: {
+                          isVisible: true
+                          position: 2
+                          hideSubtitle: false
+                        }
+                        axisVisualization: {
+                          x: {
+                            isVisible: true
+                            axisType: 2
+                          }
+                          y: {
+                            isVisible: true
+                            axisType: 1
+                          }
+                        }
+                      }
+                    }
+                  }
+                }
+                {
+                  name: 'sharedTimeRange'
+                  isOptional: true
+                }
+              ]
+              #disable-next-line BCP036
+              type: 'Extension/HubsExtension/PartType/MonitorChartPart'
+              settings: {}
+            }
+          }
+          {
+            position: {
+              x: 0
+              y: 5
+              colSpan: 4
+              rowSpan: 3
+            }
+            metadata: {
+              inputs: [
+                {
+                  name: 'options'
+                  value: {
+                    chart: {
+                      metrics: [
+                        {
+                          resourceMetadata: {
+                            id: '/subscriptions/${subscription().subscriptionId}/resourceGroups/${resourceGroup().name}/providers/Microsoft.Insights/components/${applicationInsights.name}'
+                          }
+                          name: 'availabilityResults/availabilityPercentage'
+                          aggregationType: 4
+                          namespace: 'microsoft.insights/components'
+                          metricVisualization: {
+                            displayName: 'Availability'
+                            color: '#47BDF5'
+                          }
+                        }
+                      ]
+                      title: 'Average availability'
+                      visualization: {
+                        chartType: 3
+                        legendVisualization: {
+                          isVisible: true
+                          position: 2
+                          hideSubtitle: false
+                        }
+                        axisVisualization: {
+                          x: {
+                            isVisible: true
+                            axisType: 2
+                          }
+                          y: {
+                            isVisible: true
+                            axisType: 1
+                          }
+                        }
+                      }
+                      openBladeOnClick: {
+                        openBlade: true
+                        destinationBlade: {
+                          extensionName: 'HubsExtension'
+                          bladeName: 'ResourceMenuBlade'
+                          parameters: {
+                            id: '/subscriptions/${subscription().subscriptionId}/resourceGroups/${resourceGroup().name}/providers/Microsoft.Insights/components/${applicationInsights.name}'
+                            menuid: 'availability'
+                          }
+                        }
+                      }
+                    }
+                  }
+                }
+                {
+                  name: 'sharedTimeRange'
+                  isOptional: true
+                }
+              ]
+              #disable-next-line BCP036
+              type: 'Extension/HubsExtension/PartType/MonitorChartPart'
+              settings: {}
+            }
+          }
+          {
+            position: {
+              x: 4
+              y: 5
+              colSpan: 4
+              rowSpan: 3
+            }
+            metadata: {
+              inputs: [
+                {
+                  name: 'options'
+                  value: {
+                    chart: {
+                      metrics: [
+                        {
+                          resourceMetadata: {
+                            id: '/subscriptions/${subscription().subscriptionId}/resourceGroups/${resourceGroup().name}/providers/Microsoft.Insights/components/${applicationInsights.name}'
+                          }
+                          name: 'exceptions/server'
+                          aggregationType: 7
+                          namespace: 'microsoft.insights/components'
+                          metricVisualization: {
+                            displayName: 'Server exceptions'
+                            color: '#47BDF5'
+                          }
+                        }
+                        {
+                          resourceMetadata: {
+                            id: '/subscriptions/${subscription().subscriptionId}/resourceGroups/${resourceGroup().name}/providers/Microsoft.Insights/components/${applicationInsights.name}'
+                          }
+                          name: 'dependencies/failed'
+                          aggregationType: 7
+                          namespace: 'microsoft.insights/components'
+                          metricVisualization: {
+                            displayName: 'Dependency failures'
+                            color: '#7E58FF'
+                          }
+                        }
+                      ]
+                      title: 'Server exceptions and Dependency failures'
+                      visualization: {
+                        chartType: 2
+                        legendVisualization: {
+                          isVisible: true
+                          position: 2
+                          hideSubtitle: false
+                        }
+                        axisVisualization: {
+                          x: {
+                            isVisible: true
+                            axisType: 2
+                          }
+                          y: {
+                            isVisible: true
+                            axisType: 1
+                          }
+                        }
+                      }
+                    }
+                  }
+                }
+                {
+                  name: 'sharedTimeRange'
+                  isOptional: true
+                }
+              ]
+              #disable-next-line BCP036
+              type: 'Extension/HubsExtension/PartType/MonitorChartPart'
+              settings: {}
+            }
+          }
+          {
+            position: {
+              x: 8
+              y: 5
+              colSpan: 4
+              rowSpan: 3
+            }
+            metadata: {
+              inputs: [
+                {
+                  name: 'options'
+                  value: {
+                    chart: {
+                      metrics: [
+                        {
+                          resourceMetadata: {
+                            id: '/subscriptions/${subscription().subscriptionId}/resourceGroups/${resourceGroup().name}/providers/Microsoft.Insights/components/${applicationInsights.name}'
+                          }
+                          name: 'performanceCounters/processorCpuPercentage'
+                          aggregationType: 4
+                          namespace: 'microsoft.insights/components'
+                          metricVisualization: {
+                            displayName: 'Processor time'
+                            color: '#47BDF5'
+                          }
+                        }
+                        {
+                          resourceMetadata: {
+                            id: '/subscriptions/${subscription().subscriptionId}/resourceGroups/${resourceGroup().name}/providers/Microsoft.Insights/components/${applicationInsights.name}'
+                          }
+                          name: 'performanceCounters/processCpuPercentage'
+                          aggregationType: 4
+                          namespace: 'microsoft.insights/components'
+                          metricVisualization: {
+                            displayName: 'Process CPU'
+                            color: '#7E58FF'
+                          }
+                        }
+                      ]
+                      title: 'Average processor and process CPU utilization'
+                      visualization: {
+                        chartType: 2
+                        legendVisualization: {
+                          isVisible: true
+                          position: 2
+                          hideSubtitle: false
+                        }
+                        axisVisualization: {
+                          x: {
+                            isVisible: true
+                            axisType: 2
+                          }
+                          y: {
+                            isVisible: true
+                            axisType: 1
+                          }
+                        }
+                      }
+                    }
+                  }
+                }
+                {
+                  name: 'sharedTimeRange'
+                  isOptional: true
+                }
+              ]
+              #disable-next-line BCP036
+              type: 'Extension/HubsExtension/PartType/MonitorChartPart'
+              settings: {}
+            }
+          }
+          {
+            position: {
+              x: 12
+              y: 5
+              colSpan: 4
+              rowSpan: 3
+            }
+            metadata: {
+              inputs: [
+                {
+                  name: 'options'
+                  value: {
+                    chart: {
+                      metrics: [
+                        {
+                          resourceMetadata: {
+                            id: '/subscriptions/${subscription().subscriptionId}/resourceGroups/${resourceGroup().name}/providers/Microsoft.Insights/components/${applicationInsights.name}'
+                          }
+                          name: 'exceptions/browser'
+                          aggregationType: 7
+                          namespace: 'microsoft.insights/components'
+                          metricVisualization: {
+                            displayName: 'Browser exceptions'
+                            color: '#47BDF5'
+                          }
+                        }
+                      ]
+                      title: 'Browser exceptions'
+                      visualization: {
+                        chartType: 2
+                        legendVisualization: {
+                          isVisible: true
+                          position: 2
+                          hideSubtitle: false
+                        }
+                        axisVisualization: {
+                          x: {
+                            isVisible: true
+                            axisType: 2
+                          }
+                          y: {
+                            isVisible: true
+                            axisType: 1
+                          }
+                        }
+                      }
+                    }
+                  }
+                }
+                {
+                  name: 'sharedTimeRange'
+                  isOptional: true
+                }
+              ]
+              #disable-next-line BCP036
+              type: 'Extension/HubsExtension/PartType/MonitorChartPart'
+              settings: {}
+            }
+          }
+          {
+            position: {
+              x: 0
+              y: 8
+              colSpan: 4
+              rowSpan: 3
+            }
+            metadata: {
+              inputs: [
+                {
+                  name: 'options'
+                  value: {
+                    chart: {
+                      metrics: [
+                        {
+                          resourceMetadata: {
+                            id: '/subscriptions/${subscription().subscriptionId}/resourceGroups/${resourceGroup().name}/providers/Microsoft.Insights/components/${applicationInsights.name}'
+                          }
+                          name: 'availabilityResults/count'
+                          aggregationType: 7
+                          namespace: 'microsoft.insights/components'
+                          metricVisualization: {
+                            displayName: 'Availability test results count'
+                            color: '#47BDF5'
+                          }
+                        }
+                      ]
+                      title: 'Availability test results count'
+                      visualization: {
+                        chartType: 2
+                        legendVisualization: {
+                          isVisible: true
+                          position: 2
+                          hideSubtitle: false
+                        }
+                        axisVisualization: {
+                          x: {
+                            isVisible: true
+                            axisType: 2
+                          }
+                          y: {
+                            isVisible: true
+                            axisType: 1
+                          }
+                        }
+                      }
+                    }
+                  }
+                }
+                {
+                  name: 'sharedTimeRange'
+                  isOptional: true
+                }
+              ]
+              #disable-next-line BCP036
+              type: 'Extension/HubsExtension/PartType/MonitorChartPart'
+              settings: {}
+            }
+          }
+          {
+            position: {
+              x: 4
+              y: 8
+              colSpan: 4
+              rowSpan: 3
+            }
+            metadata: {
+              inputs: [
+                {
+                  name: 'options'
+                  value: {
+                    chart: {
+                      metrics: [
+                        {
+                          resourceMetadata: {
+                            id: '/subscriptions/${subscription().subscriptionId}/resourceGroups/${resourceGroup().name}/providers/Microsoft.Insights/components/${applicationInsights.name}'
+                          }
+                          name: 'performanceCounters/processIOBytesPerSecond'
+                          aggregationType: 4
+                          namespace: 'microsoft.insights/components'
+                          metricVisualization: {
+                            displayName: 'Process IO rate'
+                            color: '#47BDF5'
+                          }
+                        }
+                      ]
+                      title: 'Average process I/O rate'
+                      visualization: {
+                        chartType: 2
+                        legendVisualization: {
+                          isVisible: true
+                          position: 2
+                          hideSubtitle: false
+                        }
+                        axisVisualization: {
+                          x: {
+                            isVisible: true
+                            axisType: 2
+                          }
+                          y: {
+                            isVisible: true
+                            axisType: 1
+                          }
+                        }
+                      }
+                    }
+                  }
+                }
+                {
+                  name: 'sharedTimeRange'
+                  isOptional: true
+                }
+              ]
+              #disable-next-line BCP036
+              type: 'Extension/HubsExtension/PartType/MonitorChartPart'
+              settings: {}
+            }
+          }
+          {
+            position: {
+              x: 8
+              y: 8
+              colSpan: 4
+              rowSpan: 3
+            }
+            metadata: {
+              inputs: [
+                {
+                  name: 'options'
+                  value: {
+                    chart: {
+                      metrics: [
+                        {
+                          resourceMetadata: {
+                            id: '/subscriptions/${subscription().subscriptionId}/resourceGroups/${resourceGroup().name}/providers/Microsoft.Insights/components/${applicationInsights.name}'
+                          }
+                          name: 'performanceCounters/memoryAvailableBytes'
+                          aggregationType: 4
+                          namespace: 'microsoft.insights/components'
+                          metricVisualization: {
+                            displayName: 'Available memory'
+                            color: '#47BDF5'
+                          }
+                        }
+                      ]
+                      title: 'Average available memory'
+                      visualization: {
+                        chartType: 2
+                        legendVisualization: {
+                          isVisible: true
+                          position: 2
+                          hideSubtitle: false
+                        }
+                        axisVisualization: {
+                          x: {
+                            isVisible: true
+                            axisType: 2
+                          }
+                          y: {
+                            isVisible: true
+                            axisType: 1
+                          }
+                        }
+                      }
+                    }
+                  }
+                }
+                {
+                  name: 'sharedTimeRange'
+                  isOptional: true
+                }
+              ]
+              #disable-next-line BCP036
+              type: 'Extension/HubsExtension/PartType/MonitorChartPart'
+              settings: {}
+            }
+          }
+        ]
+      }
+    ]
+  }
+}
+
+resource applicationInsights 'Microsoft.Insights/components@2020-02-02' existing = {
+  name: applicationInsightsName
+}
diff --git a/infra/core/monitor/applicationinsights.bicep b/infra/core/monitor/applicationinsights.bicep
new file mode 100644
index 0000000..4b4d01e
--- /dev/null
+++ b/infra/core/monitor/applicationinsights.bicep
@@ -0,0 +1,30 @@
+metadata description = 'Creates an Application Insights instance based on an existing Log Analytics workspace.'
+param name string
+param dashboardName string = ''
+param location string = resourceGroup().location
+param tags object = {}
+param logAnalyticsWorkspaceId string
+
+resource applicationInsights 'Microsoft.Insights/components@2020-02-02' = {
+  name: name
+  location: location
+  tags: tags
+  kind: 'web'
+  properties: {
+    Application_Type: 'web'
+    WorkspaceResourceId: logAnalyticsWorkspaceId
+  }
+}
+
+module applicationInsightsDashboard 'applicationinsights-dashboard.bicep' = if (!empty(dashboardName)) {
+  name: 'application-insights-dashboard'
+  params: {
+    name: dashboardName
+    location: location
+    applicationInsightsName: applicationInsights.name
+  }
+}
+
+output connectionString string = applicationInsights.properties.ConnectionString
+output instrumentationKey string = applicationInsights.properties.InstrumentationKey
+output name string = applicationInsights.name
diff --git a/infra/core/monitor/loganalytics.bicep b/infra/core/monitor/loganalytics.bicep
new file mode 100644
index 0000000..33f9dc2
--- /dev/null
+++ b/infra/core/monitor/loganalytics.bicep
@@ -0,0 +1,22 @@
+metadata description = 'Creates a Log Analytics workspace.'
+param name string
+param location string = resourceGroup().location
+param tags object = {}
+
+resource logAnalytics 'Microsoft.OperationalInsights/workspaces@2021-12-01-preview' = {
+  name: name
+  location: location
+  tags: tags
+  properties: any({
+    retentionInDays: 30
+    features: {
+      searchVersion: 1
+    }
+    sku: {
+      name: 'PerGB2018'
+    }
+  })
+}
+
+output id string = logAnalytics.id
+output name string = logAnalytics.name
diff --git a/infra/core/security/keyvault-access.bicep b/infra/core/security/keyvault-access.bicep
new file mode 100644
index 0000000..316775f
--- /dev/null
+++ b/infra/core/security/keyvault-access.bicep
@@ -0,0 +1,22 @@
+metadata description = 'Assigns an Azure Key Vault access policy.'
+param name string = 'add'
+
+param keyVaultName string
+param permissions object = { secrets: [ 'get', 'list' ] }
+param principalId string
+
+resource keyVaultAccessPolicies 'Microsoft.KeyVault/vaults/accessPolicies@2022-07-01' = {
+  parent: keyVault
+  name: name
+  properties: {
+    accessPolicies: [ {
+        objectId: principalId
+        tenantId: subscription().tenantId
+        permissions: permissions
+      } ]
+  }
+}
+
+resource keyVault 'Microsoft.KeyVault/vaults@2022-07-01' existing = {
+  name: keyVaultName
+}
diff --git a/infra/core/security/keyvault.bicep b/infra/core/security/keyvault.bicep
new file mode 100644
index 0000000..314a1db
--- /dev/null
+++ b/infra/core/security/keyvault.bicep
@@ -0,0 +1,26 @@
+metadata description = 'Creates an Azure Key Vault.'
+param name string
+param location string = resourceGroup().location
+param tags object = {}
+
+param principalId string = ''
+
+resource keyVault 'Microsoft.KeyVault/vaults@2022-07-01' = {
+  name: name
+  location: location
+  tags: tags
+  properties: {
+    tenantId: subscription().tenantId
+    sku: { family: 'A', name: 'standard' }
+    accessPolicies: !empty(principalId) ? [
+      {
+        objectId: principalId
+        permissions: { secrets: [ 'get', 'list' ] }
+        tenantId: subscription().tenantId
+      }
+    ] : []
+  }
+}
+
+output endpoint string = keyVault.properties.vaultUri
+output name string = keyVault.name
diff --git a/infra/core/security/role.bicep b/infra/core/security/role.bicep
new file mode 100644
index 0000000..0b30cfd
--- /dev/null
+++ b/infra/core/security/role.bicep
@@ -0,0 +1,21 @@
+metadata description = 'Creates a role assignment for a service principal.'
+param principalId string
+
+@allowed([
+  'Device'
+  'ForeignGroup'
+  'Group'
+  'ServicePrincipal'
+  'User'
+])
+param principalType string = 'ServicePrincipal'
+param roleDefinitionId string
+
+resource role 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
+  name: guid(subscription().id, resourceGroup().id, principalId, roleDefinitionId)
+  properties: {
+    principalId: principalId
+    principalType: principalType
+    roleDefinitionId: resourceId('Microsoft.Authorization/roleDefinitions', roleDefinitionId)
+  }
+}
diff --git a/infra/core/storage/storage-account.bicep b/infra/core/storage/storage-account.bicep
new file mode 100644
index 0000000..4b6febb
--- /dev/null
+++ b/infra/core/storage/storage-account.bicep
@@ -0,0 +1,64 @@
+metadata description = 'Creates an Azure storage account.'
+param name string
+param location string = resourceGroup().location
+param tags object = {}
+
+@allowed([
+  'Cool'
+  'Hot'
+  'Premium' ])
+param accessTier string = 'Hot'
+param allowBlobPublicAccess bool = true
+param allowCrossTenantReplication bool = true
+param allowSharedKeyAccess bool = true
+param containers array = []
+param defaultToOAuthAuthentication bool = false
+param deleteRetentionPolicy object = {}
+@allowed([ 'AzureDnsZone', 'Standard' ])
+param dnsEndpointType string = 'Standard'
+param kind string = 'StorageV2'
+param minimumTlsVersion string = 'TLS1_2'
+param supportsHttpsTrafficOnly bool = true
+param networkAcls object = {
+  bypass: 'AzureServices'
+  defaultAction: 'Allow'
+}
+@allowed([ 'Enabled', 'Disabled' ])
+param publicNetworkAccess string = 'Enabled'
+param sku object = { name: 'Standard_LRS' }
+
+resource storage 'Microsoft.Storage/storageAccounts@2022-05-01' = {
+  name: name
+  location: location
+  tags: tags
+  kind: kind
+  sku: sku
+  properties: {
+    accessTier: accessTier
+    allowBlobPublicAccess: allowBlobPublicAccess
+    allowCrossTenantReplication: allowCrossTenantReplication
+    allowSharedKeyAccess: allowSharedKeyAccess
+    defaultToOAuthAuthentication: defaultToOAuthAuthentication
+    dnsEndpointType: dnsEndpointType
+    minimumTlsVersion: minimumTlsVersion
+    networkAcls: networkAcls
+    publicNetworkAccess: publicNetworkAccess
+    supportsHttpsTrafficOnly: supportsHttpsTrafficOnly
+  }
+
+  resource blobServices 'blobServices' = if (!empty(containers)) {
+    name: 'default'
+    properties: {
+      deleteRetentionPolicy: deleteRetentionPolicy
+    }
+    resource container 'containers' = [for container in containers: {
+      name: container.name
+      properties: {
+        publicAccess: contains(container, 'publicAccess') ? container.publicAccess : 'None'
+      }
+    }]
+  }
+}
+
+output name string = storage.name
+output primaryEndpoints object = storage.properties.primaryEndpoints
diff --git a/infra/main.bicep b/infra/main.bicep
new file mode 100644
index 0000000..6284d35
--- /dev/null
+++ b/infra/main.bicep
@@ -0,0 +1,224 @@
+targetScope = 'subscription'
+
+@minLength(1)
+@maxLength(64)
+@description('Name of the the environment which is used to generate a short unique hash used in all resources.')
+param environmentName string
+
+@minLength(1)
+@description('Primary location for all resources')
+param location string
+
+// Identity
+@description('Id of the user or app to assign application roles')
+param principalId string
+
+// OpenAI
+param openAIServiceName string = ''
+param openAISkuName string = 'S0'
+param embeddingDeploymentName string = 'embeddings'
+param gptDeploymentName string = 'gpt'
+
+// Azure SQL
+@secure()
+@description('SQL Server administrator password')
+param sqlAdminPassword string
+@secure()
+@description('Application user password')
+param appUserPassword string
+param dbServiceName string = ''
+param dbName string = 'session_recommender_v2'
+
+param keyVaultName string = ''
+
+param storageAccountName string = ''
+
+param functionAppName string = ''
+
+param hostingPlanName string = ''
+param staticWebAppName string = ''
+
+param applicationInsightsName string = ''
+
+param logAnalyticsName string = ''
+
+@description('Flag to Use keyvault to store and use keys')
+param useKeyVault bool = true
+
+var abbrs = loadJsonContent('./abbreviations.json')
+var resourceToken = toLower(uniqueString(subscription().id, environmentName, location))
+var tags = { 'azd-env-name': environmentName }
+var rgName = 'rg-${environmentName}'
+
+// Organize resources in a resource group
+resource rg 'Microsoft.Resources/resourceGroups@2021-04-01' = {
+  name: rgName
+  location: location
+  tags: tags
+}
+
+module openAI 'app/openai.bicep' = {
+  name: 'openai'
+  scope: rg
+  params: {
+    name: !empty(openAIServiceName) ? openAIServiceName : '${abbrs.cognitiveServicesAccounts}${resourceToken}'
+    location: location
+    tags: tags
+    sku: {
+      name: openAISkuName
+    }
+    deployments: [
+      {
+        name: embeddingDeploymentName
+        model: {
+          format: 'OpenAI'
+          name: 'text-embedding-ada-002'
+          version: '2'
+        }
+        capacity: 30
+      }
+      {
+        name: gptDeploymentName
+        model: {
+          format: 'OpenAI'
+          name: 'gpt-35-turbo'          
+          version: '0613'
+        }
+        capacity: 120
+      }
+    ]
+    keyVaultName: keyVault.outputs.name
+    useKeyVault: useKeyVault
+  }
+}
+
+module database 'app/sqlserver.bicep' = {
+  name: 'database'
+  scope: rg
+  params: {
+    tags: tags
+    location: location
+    appUserPassword: appUserPassword
+    sqlAdminPassword: sqlAdminPassword
+    databaseName: dbName
+    name: !empty(dbServiceName) ? dbServiceName : '${abbrs.sqlServers}catalog-${resourceToken}'
+    openAIEndpoint: openAI.outputs.endpoint
+    openAIServiceName: openAI.outputs.name
+    openAIDeploymentName: embeddingDeploymentName
+    principalId: principalId
+  }
+}
+
+module keyVault 'core/security/keyvault.bicep' = {
+  name: 'keyvault'
+  scope: rg
+  params: {
+    name: !empty(keyVaultName) ? keyVaultName : '${abbrs.keyVaultVaults}${resourceToken}'
+    location: location
+    tags: tags
+    principalId: principalId
+  }
+}
+
+module hostingPlan 'core/host/appserviceplan.bicep' = {
+  name: 'hostingPlan'
+  scope: rg
+  params: {
+    tags: tags
+    location: location
+    name: !empty(hostingPlanName) ? hostingPlanName : '${abbrs.webServerFarms}${resourceToken}'
+    sku: {
+      name: 'Y1'
+      tier: 'Dynamic'
+    }
+    kind: 'linux'
+  }
+}
+
+module logAnalytics 'core/monitor/loganalytics.bicep' ={
+  name: 'logAnalytics'
+  scope: rg
+  params: {
+    name: !empty(logAnalyticsName) ? logAnalyticsName : '${abbrs.insightsComponents}${resourceToken}'
+    location: location
+  }
+}
+
+module applicationInsights 'core/monitor/applicationinsights.bicep' = {
+  name: 'monitoring'
+  scope: rg
+  params: {
+    location: location
+    tags: tags
+    name: !empty(applicationInsightsName) ? applicationInsightsName : '${abbrs.insightsComponents}${resourceToken}'
+    logAnalyticsWorkspaceId: logAnalytics.outputs.id
+  }
+}
+
+module functionApp 'app/functions.bicep' = {
+  name: 'function'
+  scope: rg
+  params: {
+    tags: union(tags, { 'azd-service-name': 'functionapp' })
+    location: location
+    storageAccountName: storageAccount.outputs.name
+    openAIKeyName: useKeyVault ? openAI.outputs.openAIKeyName : ''
+    functionAppName: !empty(functionAppName) ? functionAppName : '${abbrs.webSitesFunctions}${resourceToken}'
+    hostingPlanId: hostingPlan.outputs.id
+    sqlConnectionString: '${database.outputs.connectionString}; Password=${appUserPassword}'
+    openAIEmebddingDeploymentName: embeddingDeploymentName
+    openAIGPTDeploymentName: gptDeploymentName
+    openAIEndpoint: openAI.outputs.endpoint
+    keyVaultName: keyVault.outputs.name
+    applicationInsightsConnectionString: applicationInsights.outputs.connectionString
+    useKeyVault: useKeyVault
+    openAIName: openAI.outputs.name
+    keyVaultEndpoint: keyVault.outputs.endpoint
+  }
+}
+
+module storageAccount 'core/storage/storage-account.bicep' = {
+  name: 'storage'
+  scope: rg
+  params: {
+    tags: tags
+    name: !empty(storageAccountName) ? storageAccountName : '${abbrs.storageStorageAccounts}${resourceToken}'
+    location: location
+  }
+}
+
+module funcaccess './core/security/keyvault-access.bicep' = if (useKeyVault) {
+  name: 'web-keyvault-access'
+  scope: rg
+  params: {
+    keyVaultName: keyVault.outputs.name
+    principalId: functionApp.outputs.identityPrincipalId
+  }
+}
+
+module web 'app/staticwebapp.bicep' = {
+  name: 'web'
+  scope: rg
+  params: {
+    name: !empty(staticWebAppName) ? staticWebAppName : '${abbrs.webStaticSites}${resourceToken}'
+    location: location
+    tags: union(tags, { 'azd-service-name': 'web' })
+    sqlConnectionString: '${database.outputs.connectionString}; Password=${appUserPassword}'
+    sqlServerId: database.outputs.id
+    sqlServerLocation: location
+    apiResourceId: functionApp.outputs.functionAppResourceId
+  }
+}
+
+output AZURE_SQL_SQLSERVICE_CONNECTION_STRING_KEY string = database.outputs.connectionStringKey
+output AZURE_FUNCTIONAPP_NAME string = functionApp.outputs.name
+output AZURE_FUNCTIONAPP_ID string = functionApp.outputs.functionAppResourceId
+output AZURE_KEY_VAULT_ENDPOINT string = keyVault.outputs.endpoint
+output AZURE_KEY_VALUT_NAME string = keyVault.outputs.name
+output AZURE_LOCATION string = location
+output AZURE_TENANT_ID string = tenant().tenantId
+output APPLICATIONINSIGHTS_CONNECTION_STRING string = applicationInsights.outputs.connectionString
+output AZURE_STORAGE_NAME string = storageAccount.outputs.name
+output AZURE_STATIC_WEB_URL string = web.outputs.uri
+output LOG_ANALYTICS_ID string = logAnalytics.outputs.id
+output USE_KEY_VAULT bool = useKeyVault
diff --git a/infra/main.parameters.json b/infra/main.parameters.json
new file mode 100644
index 0000000..f82b5e1
--- /dev/null
+++ b/infra/main.parameters.json
@@ -0,0 +1,24 @@
+{
+  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#",
+  "contentVersion": "1.0.0.0",
+  "parameters": {
+    "location": {
+      "value": "${AZURE_LOCATION}"
+    },
+    "environmentName": {
+      "value": "${AZURE_ENV_NAME}"
+    },
+    "principalId": {
+      "value": "${AZURE_PRINCIPAL_ID}"
+    },
+    "sqlAdminPassword": {
+      "value": "$(secretOrRandomPassword ${AZURE_KEY_VAULT_NAME} sqlAdminPassword)"
+    },
+    "appUserPassword": {
+      "value": "$(secretOrRandomPassword ${AZURE_KEY_VAULT_NAME} appUserPassword)"
+    },
+    "useKeyVault": {
+      "value": "${USE_KEY_VAULT=true}"
+    }
+  }
+}
\ No newline at end of file
diff --git a/swa-cli.config.json b/swa-cli.config.json
new file mode 100644
index 0000000..aafbc9f
--- /dev/null
+++ b/swa-cli.config.json
@@ -0,0 +1,11 @@
+{
+  "$schema": "https://aka.ms/azure/static-web-apps-cli/schema",
+  "configurations": {
+    "client": {
+      "appLocation": "client",
+      "outputLocation": "dist",
+      "appBuildCommand": "npm run build",
+      "run": "npm run dev"
+    }
+  }
+}
diff --git a/swa-db-connections/staticwebapp.database.config.json b/swa-db-connections/staticwebapp.database.config.json
new file mode 100644
index 0000000..2389f09
--- /dev/null
+++ b/swa-db-connections/staticwebapp.database.config.json
@@ -0,0 +1,131 @@
+{
+  "$schema": "https://github.com/Azure/data-api-builder/releases/download/v0.9.7/dab.draft.schema.json",
+  "data-source": {
+    "database-type": "mssql",
+    "connection-string": "@env('MSSQL')",
+    "options": {
+      "set-session-context": false
+    }
+  },
+  "runtime": {
+    "rest": {
+      "enabled": true,
+      "path": "/rest",
+      "request-body-strict": true
+    },
+    "graphql": {
+      "enabled": true,
+      "path": "/graphql",
+      "allow-introspection": true
+    },
+    "host": {
+      "cors": {
+        "origins": [
+          "*"
+        ],
+        "allow-credentials": false
+      },
+      "authentication": {
+        "provider": "StaticWebApps"
+      },
+      "mode": "development"
+    }
+  },
+  "entities": {
+    "FindRelatedSessions": {
+      "source": {
+        "object": "web.find_sessions",
+        "type": "stored-procedure",
+        "parameters": {
+          "text": "",
+          "top": 10,
+          "min_similarity": 0.75
+        }
+      },
+      "graphql": {
+        "enabled": false,
+        "operation": "query"
+      },
+      "rest": {
+        "enabled": true,
+        "path": "/find",
+        "methods": [
+          "post"
+        ]
+      },
+      "permissions": [
+        {
+          "role": "anonymous",
+          "actions": [
+            {
+              "action": "execute"
+            }
+          ]
+        }
+      ]
+    },
+    "GetSessionsCount": {
+      "source": {
+        "object": "web.get_sessions_count",
+        "type": "stored-procedure"
+      },
+      "graphql": {
+        "enabled": false,
+        "operation": "query"
+      },
+      "rest": {
+        "enabled": true,
+        "path": "/sessions-count",
+        "methods": [
+          "get"
+        ]
+      },
+      "permissions": [
+        {
+          "role": "anonymous",
+          "actions": [
+            {
+              "action": "execute"
+            }
+          ]
+        }
+      ]
+    },
+    "Session": {
+      "source": {
+        "object": "web.sessions",
+        "type": "table"
+      },
+      "graphql": {
+        "enabled": true,
+        "type": {
+          "singular": "Session",
+          "plural": "Sessions"
+        }
+      },
+      "rest": {
+        "enabled": true,
+        "path": "/sessions"
+      },
+      "permissions": [
+        {
+          "role": "anonymous",
+          "actions": [
+            {
+              "action": "read"
+            }
+          ]
+        },
+        {
+          "role": "authenticated",
+          "actions": [
+            {
+              "action": "*"
+            }
+          ]
+        }
+
+      ]
+    }
+  }
+}
\ No newline at end of file