getlastTransactions() {
+ return lastTransactions;
+ }
+
+}
diff --git a/app/backend/src/main/java/com/microsoft/openai/samples/assistant/proxy/BlobStorageProxy.java b/app/backend/src/main/java/com/microsoft/openai/samples/assistant/proxy/BlobStorageProxy.java
new file mode 100644
index 0000000..dbf601e
--- /dev/null
+++ b/app/backend/src/main/java/com/microsoft/openai/samples/assistant/proxy/BlobStorageProxy.java
@@ -0,0 +1,48 @@
+// Copyright (c) Microsoft. All rights reserved.
+package com.microsoft.openai.samples.assistant.proxy;
+
+import com.azure.core.credential.TokenCredential;
+import com.azure.storage.blob.BlobContainerClient;
+import com.azure.storage.blob.BlobContainerClientBuilder;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Component;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+
+/**
+ * This class is a proxy to the Blob storage API. It is responsible for: - calling the API -
+ * handling errors and retry strategy - add monitoring points - add circuit breaker with exponential
+ * backoff
+ */
+@Component
+public class BlobStorageProxy {
+
+ private final BlobContainerClient client;
+
+ public BlobStorageProxy(
+ @Value("${storage-account.service}") String storageAccountServiceName,
+ @Value("${blob.container.name}") String containerName,
+ TokenCredential tokenCredential) {
+
+ String endpoint = "https://%s.blob.core.windows.net".formatted(storageAccountServiceName);
+ this.client =
+ new BlobContainerClientBuilder()
+ .endpoint(endpoint)
+ .credential(tokenCredential)
+ .containerName(containerName)
+ .buildClient();
+ }
+
+ public byte[] getFileAsBytes(String fileName) throws IOException {
+ var blobClient = client.getBlobClient(fileName);
+ int dataSize = (int) blobClient.getProperties().getBlobSize();
+
+ // There is no need to close ByteArrayOutputStream.
+ // https://docs.oracle.com/javase/8/docs/api/java/io/ByteArrayOutputStream.html
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream(dataSize);
+ blobClient.downloadStream(outputStream);
+
+ return outputStream.toByteArray();
+ }
+}
diff --git a/app/backend/src/main/java/com/microsoft/openai/samples/assistant/proxy/OpenAIProxy.java b/app/backend/src/main/java/com/microsoft/openai/samples/assistant/proxy/OpenAIProxy.java
new file mode 100644
index 0000000..182cd9d
--- /dev/null
+++ b/app/backend/src/main/java/com/microsoft/openai/samples/assistant/proxy/OpenAIProxy.java
@@ -0,0 +1,106 @@
+// Copyright (c) Microsoft. All rights reserved.
+package com.microsoft.openai.samples.assistant.proxy;
+
+import com.azure.ai.openai.OpenAIClient;
+import com.azure.ai.openai.models.*;
+import com.azure.core.exception.HttpResponseException;
+import com.azure.core.util.IterableStream;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Component;
+import org.springframework.web.server.ResponseStatusException;
+
+import java.util.List;
+
+/**
+ * This class is a proxy to the OpenAI API to simplify cross-cutting concerns management (security,
+ * load balancing, monitoring, resiliency). It is responsible for: - calling the OpenAI API -
+ * handling errors and retry strategy - load balance requests across open AI instances - add
+ * monitoring points - add circuit breaker with exponential backoff
+ *
+ * It also makes unit testing easy using mockito to provide mock implementation for this bean.
+ */
+@Component
+public class OpenAIProxy {
+
+ private final OpenAIClient client;
+
+ @Value("${openai.chatgpt.deployment}")
+ private String gptChatDeploymentModelId;
+
+ @Value("${openai.embedding.deployment}")
+ private String embeddingDeploymentModelId;
+
+ public OpenAIProxy(OpenAIClient client) {
+ this.client = client;
+ }
+
+ public Completions getCompletions(CompletionsOptions completionsOptions) {
+ Completions completions;
+ try {
+ completions = client.getCompletions(this.gptChatDeploymentModelId, completionsOptions);
+ } catch (HttpResponseException e) {
+ throw new ResponseStatusException(
+ e.getResponse().getStatusCode(), "Error calling OpenAI API:" + e.getValue(), e);
+ }
+ return completions;
+ }
+
+ public Completions getCompletions(String prompt) {
+
+ Completions completions;
+ try {
+ completions = client.getCompletions(this.gptChatDeploymentModelId, prompt);
+ } catch (HttpResponseException e) {
+ throw new ResponseStatusException(
+ e.getResponse().getStatusCode(),
+ "Error calling OpenAI API:" + e.getMessage(),
+ e);
+ }
+ return completions;
+ }
+
+ public ChatCompletions getChatCompletions(ChatCompletionsOptions chatCompletionsOptions) {
+ ChatCompletions chatCompletions;
+ try {
+ chatCompletions =
+ client.getChatCompletions(
+ this.gptChatDeploymentModelId, chatCompletionsOptions);
+ } catch (HttpResponseException e) {
+ throw new ResponseStatusException(
+ e.getResponse().getStatusCode(),
+ "Error calling OpenAI API:" + e.getMessage(),
+ e);
+ }
+ return chatCompletions;
+ }
+
+ public IterableStream getChatCompletionsStream(
+ ChatCompletionsOptions chatCompletionsOptions) {
+ try {
+ return client.getChatCompletionsStream(
+ this.gptChatDeploymentModelId, chatCompletionsOptions);
+ } catch (HttpResponseException e) {
+ throw new ResponseStatusException(
+ e.getResponse().getStatusCode(),
+ "Error calling OpenAI API:" + e.getMessage(),
+ e);
+ }
+ }
+
+ public Embeddings getEmbeddings(List texts) {
+ Embeddings embeddings;
+ try {
+ EmbeddingsOptions embeddingsOptions = new EmbeddingsOptions(texts);
+ embeddingsOptions.setUser("search-openai-demo-java");
+ embeddingsOptions.setModel(this.embeddingDeploymentModelId);
+ embeddingsOptions.setInputType("query");
+ embeddings = client.getEmbeddings(this.embeddingDeploymentModelId, embeddingsOptions);
+ } catch (HttpResponseException e) {
+ throw new ResponseStatusException(
+ e.getResponse().getStatusCode(),
+ "Error calling OpenAI API:" + e.getMessage(),
+ e);
+ }
+ return embeddings;
+ }
+}
diff --git a/app/backend/src/main/resources/application.properties b/app/backend/src/main/resources/application.properties
new file mode 100644
index 0000000..2133743
--- /dev/null
+++ b/app/backend/src/main/resources/application.properties
@@ -0,0 +1,18 @@
+#Used to enable mocked class to take precedence over real class in unit tests
+spring.main.lazy-initialization=true
+
+openai.service=${AZURE_OPENAI_SERVICE}
+openai.chatgpt.deployment=${AZURE_OPENAI_CHATGPT_DEPLOYMENT:chat}
+openai.tracing.enabled=${AZURE_OPENAI_TRACING_ENABLED:true}
+
+documentintelligence.service=${AZURE_DOCUMENT_INTELLIGENCE_SERVICE:example}
+
+
+storage-account.service=${AZURE_STORAGE_ACCOUNT}
+blob.container.name=${AZURE_STORAGE_CONTAINER:content}
+
+logging.level.com.microsoft.openai.samples.rag.ask.approaches.semantickernel=DEBUG
+server.error.include-message=always
+
+# Support for User Assigned Managed identity
+azure.identity.client-id=${AZURE_CLIENT_ID:system-managed-identity}
\ No newline at end of file
diff --git a/app/frontend/.dockerignore b/app/frontend/.dockerignore
new file mode 100644
index 0000000..a1ee4db
--- /dev/null
+++ b/app/frontend/.dockerignore
@@ -0,0 +1,2 @@
+manifests
+node_modules
\ No newline at end of file
diff --git a/app/frontend/.env.dev b/app/frontend/.env.dev
new file mode 100644
index 0000000..e34f261
--- /dev/null
+++ b/app/frontend/.env.dev
@@ -0,0 +1 @@
+VITE_BACKEND_URI=http://127.0.0.1:8081/api
diff --git a/app/frontend/.env.local b/app/frontend/.env.local
new file mode 100644
index 0000000..e34f261
--- /dev/null
+++ b/app/frontend/.env.local
@@ -0,0 +1 @@
+VITE_BACKEND_URI=http://127.0.0.1:8081/api
diff --git a/app/frontend/.env.production b/app/frontend/.env.production
new file mode 100644
index 0000000..c00db2d
--- /dev/null
+++ b/app/frontend/.env.production
@@ -0,0 +1,2 @@
+VITE_BACKEND_URI=/api
+
diff --git a/app/frontend/.npmrc b/app/frontend/.npmrc
new file mode 100644
index 0000000..b6f27f1
--- /dev/null
+++ b/app/frontend/.npmrc
@@ -0,0 +1 @@
+engine-strict=true
diff --git a/app/frontend/.prettierignore b/app/frontend/.prettierignore
new file mode 100644
index 0000000..fc355bc
--- /dev/null
+++ b/app/frontend/.prettierignore
@@ -0,0 +1,2 @@
+# Ignore JSON
+**/*.json
diff --git a/app/frontend/.prettierrc.json b/app/frontend/.prettierrc.json
new file mode 100644
index 0000000..b7d6774
--- /dev/null
+++ b/app/frontend/.prettierrc.json
@@ -0,0 +1,6 @@
+{
+ "tabWidth": 4,
+ "printWidth": 160,
+ "arrowParens": "avoid",
+ "trailingComma": "none"
+}
diff --git a/app/frontend/Dockerfile b/app/frontend/Dockerfile
new file mode 100644
index 0000000..670144c
--- /dev/null
+++ b/app/frontend/Dockerfile
@@ -0,0 +1,21 @@
+FROM node:18-alpine AS build
+
+# make the 'app' folder the current working directory
+WORKDIR /app
+
+COPY . .
+
+
+# install project dependencies
+RUN npm install
+RUN npm run build
+
+FROM nginx:alpine
+
+WORKDIR /usr/share/nginx/html
+COPY --from=build /app/build .
+COPY --from=build /app/nginx/nginx.conf.template /etc/nginx/conf.d
+
+EXPOSE 80
+
+CMD ["/bin/sh", "-c", "envsubst < /etc/nginx/conf.d/nginx.conf.template > /etc/nginx/conf.d/default.conf && nginx -g \"daemon off;\""]
diff --git a/app/frontend/Dockerfile-aks b/app/frontend/Dockerfile-aks
new file mode 100644
index 0000000..3041dbf
--- /dev/null
+++ b/app/frontend/Dockerfile-aks
@@ -0,0 +1,20 @@
+FROM node:18-alpine AS build
+
+# make the 'app' folder the current working directory
+WORKDIR /app
+
+COPY . .
+
+
+# install project dependencies
+RUN npm install
+RUN npm run build
+
+FROM nginx:alpine
+
+WORKDIR /usr/share/nginx/html
+COPY --from=build /app/build .
+
+EXPOSE 80
+
+CMD ["/bin/sh", "-c", "nginx -g \"daemon off;\""]
\ No newline at end of file
diff --git a/app/frontend/index.html b/app/frontend/index.html
new file mode 100644
index 0000000..e4081a0
--- /dev/null
+++ b/app/frontend/index.html
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+ GPT + Enterprise data | Java Sample
+
+
+
+
+
+
diff --git a/app/frontend/manifests/frontend-deployment.tmpl.yml b/app/frontend/manifests/frontend-deployment.tmpl.yml
new file mode 100644
index 0000000..1eac564
--- /dev/null
+++ b/app/frontend/manifests/frontend-deployment.tmpl.yml
@@ -0,0 +1,26 @@
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+ name: frontend-deployment
+ namespace: azure-open-ai
+ labels:
+ app: frontend
+spec:
+ replicas: 1
+ selector:
+ matchLabels:
+ app: frontend
+ template:
+ metadata:
+ labels:
+ app: frontend
+ spec:
+ containers:
+ - name: frontend
+ image: {{.Env.SERVICE_FRONTEND_IMAGE_NAME}}
+ imagePullPolicy: IfNotPresent
+ ports:
+ - containerPort: 80
+ envFrom:
+ - configMapRef:
+ name: azd-env-configmap
diff --git a/app/frontend/manifests/frontend-service.yml b/app/frontend/manifests/frontend-service.yml
new file mode 100644
index 0000000..2fabe3f
--- /dev/null
+++ b/app/frontend/manifests/frontend-service.yml
@@ -0,0 +1,13 @@
+apiVersion: v1
+kind: Service
+metadata:
+ name: frontend-service
+ namespace: azure-open-ai
+spec:
+ type: ClusterIP
+ ports:
+ - protocol: TCP
+ port: 80
+ targetPort: 80
+ selector:
+ app: frontend
diff --git a/app/frontend/nginx/nginx.conf.template b/app/frontend/nginx/nginx.conf.template
new file mode 100644
index 0000000..cafa824
--- /dev/null
+++ b/app/frontend/nginx/nginx.conf.template
@@ -0,0 +1,13 @@
+server {
+ listen 80;
+ location / {
+ root /usr/share/nginx/html;
+ index index.html index.htm;
+ }
+
+ location /api {
+ proxy_ssl_server_name on;
+ proxy_http_version 1.1;
+ proxy_pass $REACT_APP_API_BASE_URL;
+ }
+}
\ No newline at end of file
diff --git a/app/frontend/package-lock.json b/app/frontend/package-lock.json
new file mode 100644
index 0000000..f7a19b7
--- /dev/null
+++ b/app/frontend/package-lock.json
@@ -0,0 +1,5592 @@
+{
+ "name": "frontend",
+ "version": "1.0.0-alpha",
+ "lockfileVersion": 2,
+ "requires": true,
+ "packages": {
+ "": {
+ "name": "frontend",
+ "version": "1.0.0-alpha",
+ "dependencies": {
+ "@azure/msal-browser": "^3.1.0",
+ "@azure/msal-react": "^2.0.4",
+ "@fluentui/react": "^8.112.5",
+ "@fluentui/react-components": "^9.37.3",
+ "@fluentui/react-icons": "^2.0.221",
+ "@react-spring/web": "^9.7.3",
+ "dompurify": "^3.0.6",
+ "ndjson-readablestream": "^1.0.7",
+ "react": "^18.2.0",
+ "react-dom": "^18.2.0",
+ "react-router-dom": "^6.18.0",
+ "scheduler": "^0.20.2"
+ },
+ "devDependencies": {
+ "@types/dompurify": "^3.0.3",
+ "@types/react": "^18.2.34",
+ "@types/react-dom": "^18.2.14",
+ "@vitejs/plugin-react": "^4.1.1",
+ "prettier": "^3.0.3",
+ "typescript": "^5.2.2",
+ "vite": "^4.5.3"
+ },
+ "engines": {
+ "node": ">=14.0.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/@azure/msal-browser": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/@azure/msal-browser/-/msal-browser-3.2.0.tgz",
+ "integrity": "sha512-le2qutddMiq0i3ErQaLKuwP1DpNgdd9iXPs3fSCsLuBrdGg9B4/j4ArCAHCwgxA82Ydj9BcqtMIL5BSWwU+P5A==",
+ "dependencies": {
+ "@azure/msal-common": "14.1.0"
+ },
+ "engines": {
+ "node": ">=0.8.0"
+ }
+ },
+ "node_modules/@azure/msal-common": {
+ "version": "14.1.0",
+ "resolved": "https://registry.npmjs.org/@azure/msal-common/-/msal-common-14.1.0.tgz",
+ "integrity": "sha512-xphmhcfl5VL+uq5//VKMwQn+wfEZLMKNpFCcMi8Ur8ej5UT166g6chBsxgMzc9xo9Y24R9FB3m/tjDiV03xMIA==",
+ "engines": {
+ "node": ">=0.8.0"
+ }
+ },
+ "node_modules/@azure/msal-react": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/@azure/msal-react/-/msal-react-2.0.4.tgz",
+ "integrity": "sha512-BujRm5FBDWYXyr3pnmubS4dIqZMlurYVtV2AyztoeAFUd+nh3XQZD9knHBqTyu53IDjhCCvUPUke/jSkv5WGlg==",
+ "dependencies": {
+ "@rollup/plugin-typescript": "^11.1.0",
+ "rollup": "^3.20.2"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "peerDependencies": {
+ "@azure/msal-browser": "^3.2.0",
+ "react": "^16.8.0 || ^17 || ^18"
+ }
+ },
+ "node_modules/@babel/code-frame": {
+ "version": "7.23.5",
+ "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.23.5.tgz",
+ "integrity": "sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA==",
+ "dev": true,
+ "dependencies": {
+ "@babel/highlight": "^7.23.4",
+ "chalk": "^2.4.2"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/compat-data": {
+ "version": "7.23.5",
+ "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.23.5.tgz",
+ "integrity": "sha512-uU27kfDRlhfKl+w1U6vp16IuvSLtjAxdArVXPa9BvLkrr7CYIsxH5adpHObeAGY/41+syctUWOZ140a2Rvkgjw==",
+ "dev": true,
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/core": {
+ "version": "7.23.7",
+ "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.23.7.tgz",
+ "integrity": "sha512-+UpDgowcmqe36d4NwqvKsyPMlOLNGMsfMmQ5WGCu+siCe3t3dfe9njrzGfdN4qq+bcNUt0+Vw6haRxBOycs4dw==",
+ "dev": true,
+ "dependencies": {
+ "@ampproject/remapping": "^2.2.0",
+ "@babel/code-frame": "^7.23.5",
+ "@babel/generator": "^7.23.6",
+ "@babel/helper-compilation-targets": "^7.23.6",
+ "@babel/helper-module-transforms": "^7.23.3",
+ "@babel/helpers": "^7.23.7",
+ "@babel/parser": "^7.23.6",
+ "@babel/template": "^7.22.15",
+ "@babel/traverse": "^7.23.7",
+ "@babel/types": "^7.23.6",
+ "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.6",
+ "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.6.tgz",
+ "integrity": "sha512-qrSfCYxYQB5owCmGLbl8XRpX1ytXlpueOb0N0UmQwA073KZxejgQTzAmJezxvpwQD9uGtK2shHdi55QT+MbjIw==",
+ "dev": true,
+ "dependencies": {
+ "@babel/types": "^7.23.6",
+ "@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.23.6",
+ "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.23.6.tgz",
+ "integrity": "sha512-9JB548GZoQVmzrFgp8o7KxdgkTGm6xs9DW0o/Pim72UDjzr5ObUQ6ZzYPqA+g9OTS2bBQoctLJrky0RDCAWRgQ==",
+ "dev": true,
+ "dependencies": {
+ "@babel/compat-data": "^7.23.5",
+ "@babel/helper-validator-option": "^7.23.5",
+ "browserslist": "^4.22.2",
+ "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.3",
+ "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.23.3.tgz",
+ "integrity": "sha512-7bBs4ED9OmswdfDzpz4MpWgSrV7FXlc3zIagvLFjS5H+Mk7Snr21vQ6QwrsoCGMfNC4e4LQPdoULEt4ykz0SRQ==",
+ "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.23.4",
+ "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.23.4.tgz",
+ "integrity": "sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ==",
+ "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.23.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.23.5.tgz",
+ "integrity": "sha512-85ttAOMLsr53VgXkTbkx8oA6YTfT4q7/HzXSLEYmjcSTJPMPQtvq1BD79Byep5xMUYbGRzEpDsjUf3dyp54IKw==",
+ "dev": true,
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helpers": {
+ "version": "7.23.8",
+ "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.23.8.tgz",
+ "integrity": "sha512-KDqYz4PiOWvDFrdHLPhKtCThtIcKVy6avWD2oG4GEvyQ+XDZwHD4YQd+H2vNMnq2rkdxsDkU82T+Vk8U/WXHRQ==",
+ "dev": true,
+ "dependencies": {
+ "@babel/template": "^7.22.15",
+ "@babel/traverse": "^7.23.7",
+ "@babel/types": "^7.23.6"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/highlight": {
+ "version": "7.23.4",
+ "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.23.4.tgz",
+ "integrity": "sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==",
+ "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.6",
+ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.6.tgz",
+ "integrity": "sha512-Z2uID7YJ7oNvAI20O9X0bblw7Qqs8Q2hFy0R9tAfnfLkp5MW0UH9eUvnDSnFwKZ0AvgS1ucqR4KzvVHgnke1VQ==",
+ "dev": true,
+ "bin": {
+ "parser": "bin/babel-parser.js"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-react-jsx-self": {
+ "version": "7.23.3",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.23.3.tgz",
+ "integrity": "sha512-qXRvbeKDSfwnlJnanVRp0SfuWE5DQhwQr5xtLBzp56Wabyo+4CMosF6Kfp+eOD/4FYpql64XVJ2W0pVLlJZxOQ==",
+ "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.23.3",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.23.3.tgz",
+ "integrity": "sha512-91RS0MDnAWDNvGC6Wio5XYkyWI39FMFO+JK9+4AlgaTH+yWwVTsw7/sn6LK0lH7c5F+TFkpv/3LfCJ1Ydwof/g==",
+ "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.8",
+ "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.23.8.tgz",
+ "integrity": "sha512-Y7KbAP984rn1VGMbGqKmBLio9V7y5Je9GvU4rQPCPinCyNfUcToxIXl06d59URp/F3LwinvODxab5N/G6qggkw==",
+ "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.7",
+ "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.7.tgz",
+ "integrity": "sha512-tY3mM8rH9jM0YHFGyfC0/xf+SB5eKUu7HPj7/k3fpi9dAlsMc5YbQvDi0Sh2QTPXqMhyaAtzAr807TIyfQrmyg==",
+ "dev": true,
+ "dependencies": {
+ "@babel/code-frame": "^7.23.5",
+ "@babel/generator": "^7.23.6",
+ "@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.6",
+ "@babel/types": "^7.23.6",
+ "debug": "^4.3.1",
+ "globals": "^11.1.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/types": {
+ "version": "7.23.6",
+ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.6.tgz",
+ "integrity": "sha512-+uarb83brBzPKN38NX1MkB6vb6+mwvR6amUulqAE7ccQw1pEl+bCia9TbdG1lsnFP7lZySvUn37CHyXQdfTwzg==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-string-parser": "^7.23.4",
+ "@babel/helper-validator-identifier": "^7.22.20",
+ "to-fast-properties": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@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.11",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.11.tgz",
+ "integrity": "sha512-q4qlUf5ucwbUJZXF5tEQ8LF7y0Nk4P58hOsGk3ucY0oCwgQqAnqXVbUuahCddVHfrxmpyewRpiTHwVHIETYu7Q==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/android-arm64": {
+ "version": "0.18.11",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.18.11.tgz",
+ "integrity": "sha512-snieiq75Z1z5LJX9cduSAjUr7vEI1OdlzFPMw0HH5YI7qQHDd3qs+WZoMrWYDsfRJSq36lIA6mfZBkvL46KoIw==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/android-x64": {
+ "version": "0.18.11",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.18.11.tgz",
+ "integrity": "sha512-iPuoxQEV34+hTF6FT7om+Qwziv1U519lEOvekXO9zaMMlT9+XneAhKL32DW3H7okrCOBQ44BMihE8dclbZtTuw==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/darwin-arm64": {
+ "version": "0.18.11",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.18.11.tgz",
+ "integrity": "sha512-Gm0QkI3k402OpfMKyQEEMG0RuW2LQsSmI6OeO4El2ojJMoF5NLYb3qMIjvbG/lbMeLOGiW6ooU8xqc+S0fgz2w==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/darwin-x64": {
+ "version": "0.18.11",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.18.11.tgz",
+ "integrity": "sha512-N15Vzy0YNHu6cfyDOjiyfJlRJCB/ngKOAvoBf1qybG3eOq0SL2Lutzz9N7DYUbb7Q23XtHPn6lMDF6uWbGv9Fw==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/freebsd-arm64": {
+ "version": "0.18.11",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.11.tgz",
+ "integrity": "sha512-atEyuq6a3omEY5qAh5jIORWk8MzFnCpSTUruBgeyN9jZq1K/QI9uke0ATi3MHu4L8c59CnIi4+1jDKMuqmR71A==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/freebsd-x64": {
+ "version": "0.18.11",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.18.11.tgz",
+ "integrity": "sha512-XtuPrEfBj/YYYnAAB7KcorzzpGTvOr/dTtXPGesRfmflqhA4LMF0Gh/n5+a9JBzPuJ+CGk17CA++Hmr1F/gI0Q==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-arm": {
+ "version": "0.18.11",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.18.11.tgz",
+ "integrity": "sha512-Idipz+Taso/toi2ETugShXjQ3S59b6m62KmLHkJlSq/cBejixmIydqrtM2XTvNCywFl3VC7SreSf6NV0i6sRyg==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-arm64": {
+ "version": "0.18.11",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.18.11.tgz",
+ "integrity": "sha512-c6Vh2WS9VFKxKZ2TvJdA7gdy0n6eSy+yunBvv4aqNCEhSWVor1TU43wNRp2YLO9Vng2G+W94aRz+ILDSwAiYog==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-ia32": {
+ "version": "0.18.11",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.18.11.tgz",
+ "integrity": "sha512-S3hkIF6KUqRh9n1Q0dSyYcWmcVa9Cg+mSoZEfFuzoYXXsk6196qndrM+ZiHNwpZKi3XOXpShZZ+9dfN5ykqjjw==",
+ "cpu": [
+ "ia32"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-loong64": {
+ "version": "0.18.11",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.18.11.tgz",
+ "integrity": "sha512-MRESANOoObQINBA+RMZW+Z0TJWpibtE7cPFnahzyQHDCA9X9LOmGh68MVimZlM9J8n5Ia8lU773te6O3ILW8kw==",
+ "cpu": [
+ "loong64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-mips64el": {
+ "version": "0.18.11",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.18.11.tgz",
+ "integrity": "sha512-qVyPIZrXNMOLYegtD1u8EBccCrBVshxMrn5MkuFc3mEVsw7CCQHaqZ4jm9hbn4gWY95XFnb7i4SsT3eflxZsUg==",
+ "cpu": [
+ "mips64el"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-ppc64": {
+ "version": "0.18.11",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.18.11.tgz",
+ "integrity": "sha512-T3yd8vJXfPirZaUOoA9D2ZjxZX4Gr3QuC3GztBJA6PklLotc/7sXTOuuRkhE9W/5JvJP/K9b99ayPNAD+R+4qQ==",
+ "cpu": [
+ "ppc64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-riscv64": {
+ "version": "0.18.11",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.18.11.tgz",
+ "integrity": "sha512-evUoRPWiwuFk++snjH9e2cAjF5VVSTj+Dnf+rkO/Q20tRqv+644279TZlPK8nUGunjPAtQRCj1jQkDAvL6rm2w==",
+ "cpu": [
+ "riscv64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-s390x": {
+ "version": "0.18.11",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.18.11.tgz",
+ "integrity": "sha512-/SlRJ15XR6i93gRWquRxYCfhTeC5PdqEapKoLbX63PLCmAkXZHY2uQm2l9bN0oPHBsOw2IswRZctMYS0MijFcg==",
+ "cpu": [
+ "s390x"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-x64": {
+ "version": "0.18.11",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.18.11.tgz",
+ "integrity": "sha512-xcncej+wF16WEmIwPtCHi0qmx1FweBqgsRtEL1mSHLFR6/mb3GEZfLQnx+pUDfRDEM4DQF8dpXIW7eDOZl1IbA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/netbsd-x64": {
+ "version": "0.18.11",
+ "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.18.11.tgz",
+ "integrity": "sha512-aSjMHj/F7BuS1CptSXNg6S3M4F3bLp5wfFPIJM+Km2NfIVfFKhdmfHF9frhiCLIGVzDziggqWll0B+9AUbud/Q==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "netbsd"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/openbsd-x64": {
+ "version": "0.18.11",
+ "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.18.11.tgz",
+ "integrity": "sha512-tNBq+6XIBZtht0xJGv7IBB5XaSyvYPCm1PxJ33zLQONdZoLVM0bgGqUrXnJyiEguD9LU4AHiu+GCXy/Hm9LsdQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "openbsd"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/sunos-x64": {
+ "version": "0.18.11",
+ "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.18.11.tgz",
+ "integrity": "sha512-kxfbDOrH4dHuAAOhr7D7EqaYf+W45LsAOOhAet99EyuxxQmjbk8M9N4ezHcEiCYPaiW8Dj3K26Z2V17Gt6p3ng==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "sunos"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/win32-arm64": {
+ "version": "0.18.11",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.18.11.tgz",
+ "integrity": "sha512-Sh0dDRyk1Xi348idbal7lZyfSkjhJsdFeuC13zqdipsvMetlGiFQNdO+Yfp6f6B4FbyQm7qsk16yaZk25LChzg==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/win32-ia32": {
+ "version": "0.18.11",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.18.11.tgz",
+ "integrity": "sha512-o9JUIKF1j0rqJTFbIoF4bXj6rvrTZYOrfRcGyL0Vm5uJ/j5CkBD/51tpdxe9lXEDouhRgdr/BYzUrDOvrWwJpg==",
+ "cpu": [
+ "ia32"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/win32-x64": {
+ "version": "0.18.11",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.18.11.tgz",
+ "integrity": "sha512-rQI4cjLHd2hGsM1LqgDI7oOCYbQ6IBOVsX9ejuRMSze0GqXUG2ekwiKkiBU1pRGSeCqFFHxTrcEydB2Hyoz9CA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@floating-ui/core": {
+ "version": "1.5.3",
+ "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.5.3.tgz",
+ "integrity": "sha512-O0WKDOo0yhJuugCx6trZQj5jVJ9yR0ystG2JaNAemYUWce+pmM6WUEFIibnWyEJKdrDxhm75NoSRME35FNaM/Q==",
+ "dependencies": {
+ "@floating-ui/utils": "^0.2.0"
+ }
+ },
+ "node_modules/@floating-ui/devtools": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/@floating-ui/devtools/-/devtools-0.2.1.tgz",
+ "integrity": "sha512-8PHJLbD6VhBh+LJ1uty/Bz30qs02NXCE5u8WpOhSewlYXUWl03GNXknr9AS2yaAWJEQaY27x7eByJs44gODBcw==",
+ "peerDependencies": {
+ "@floating-ui/dom": ">=1.5.4"
+ }
+ },
+ "node_modules/@floating-ui/dom": {
+ "version": "1.5.4",
+ "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.5.4.tgz",
+ "integrity": "sha512-jByEsHIY+eEdCjnTVu+E3ephzTOzkQ8hgUfGwos+bg7NlH33Zc5uO+QHz1mrQUOgIKKDD1RtS201P9NvAfq3XQ==",
+ "dependencies": {
+ "@floating-ui/core": "^1.5.3",
+ "@floating-ui/utils": "^0.2.0"
+ }
+ },
+ "node_modules/@floating-ui/utils": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.1.tgz",
+ "integrity": "sha512-9TANp6GPoMtYzQdt54kfAyMmz1+osLlXdg2ENroU7zzrtflTLrrC/lgrIfaSe+Wu0b89GKccT7vxXA0MoAIO+Q=="
+ },
+ "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.31",
+ "resolved": "https://registry.npmjs.org/@fluentui/font-icons-mdl2/-/font-icons-mdl2-8.5.31.tgz",
+ "integrity": "sha512-jioHZ9XUfR9vUT5XnxdCrJ+hoC9TpYim+4YdtlUE/euI8kdW1tDZ5zqlSNk1GLDR34n03R09yWj5gVDCcMJbyQ==",
+ "dependencies": {
+ "@fluentui/set-version": "^8.2.14",
+ "@fluentui/style-utilities": "^8.10.2",
+ "@fluentui/utilities": "^8.13.24",
+ "tslib": "^2.1.0"
+ }
+ },
+ "node_modules/@fluentui/foundation-legacy": {
+ "version": "8.2.51",
+ "resolved": "https://registry.npmjs.org/@fluentui/foundation-legacy/-/foundation-legacy-8.2.51.tgz",
+ "integrity": "sha512-z/jrp1imV66/D2MGpN/55LGk/Istymk5tN+XUFHDENDi+9zyb2MgSxFshp774DJIrg3vVlyuS8oo+dBuTM3UbQ==",
+ "dependencies": {
+ "@fluentui/merge-styles": "^8.5.15",
+ "@fluentui/set-version": "^8.2.14",
+ "@fluentui/style-utilities": "^8.10.2",
+ "@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.11",
+ "resolved": "https://registry.npmjs.org/@fluentui/priority-overflow/-/priority-overflow-9.1.11.tgz",
+ "integrity": "sha512-sdrpavvKX2kepQ1d6IaI3ObLq5SAQBPRHPGx2+wiMWL7cEx9vGGM0fmeicl3soqqmM5uwCmWnZk9QZv9XOY98w==",
+ "dependencies": {
+ "@swc/helpers": "^0.5.1"
+ }
+ },
+ "node_modules/@fluentui/react": {
+ "version": "8.114.4",
+ "resolved": "https://registry.npmjs.org/@fluentui/react/-/react-8.114.4.tgz",
+ "integrity": "sha512-dVpfFSpWUxdyqWlCVSXX5d34S760h4MaQjGR2/TPavtcJRRpJDHbBN2Hn7s4riA6YX5N7bTdN372UvIVbBbzuw==",
+ "dependencies": {
+ "@fluentui/date-time-utilities": "^8.5.16",
+ "@fluentui/font-icons-mdl2": "^8.5.31",
+ "@fluentui/foundation-legacy": "^8.2.51",
+ "@fluentui/merge-styles": "^8.5.15",
+ "@fluentui/react-focus": "^8.8.38",
+ "@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.2",
+ "@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.38",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-accordion/-/react-accordion-9.3.38.tgz",
+ "integrity": "sha512-BB8d9+Jr0v4SW58OJTIyvsxhA/iOBbvIkQZlVHKqt4tL8dHOIFPrApw5WqQqaSYJsEwt4HxmlNU4Dv8qRughbg==",
+ "dependencies": {
+ "@fluentui/react-aria": "^9.7.3",
+ "@fluentui/react-context-selector": "^9.1.49",
+ "@fluentui/react-icons": "^2.0.224",
+ "@fluentui/react-jsx-runtime": "^9.0.27",
+ "@fluentui/react-shared-contexts": "^9.14.0",
+ "@fluentui/react-tabster": "^9.17.3",
+ "@fluentui/react-theme": "^9.1.16",
+ "@fluentui/react-utilities": "^9.16.1",
+ "@griffel/react": "^1.5.14",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.9.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.104",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-alert/-/react-alert-9.0.0-beta.104.tgz",
+ "integrity": "sha512-Z8BGSyzEKok5wlJF2cUc8GUj2q+c1D+119YF0WtHLiieh7pwOHjBcDJOHqnaVnQNbhetIA3NUht2z0e1wgOK5w==",
+ "dependencies": {
+ "@fluentui/react-avatar": "^9.6.9",
+ "@fluentui/react-button": "^9.3.65",
+ "@fluentui/react-icons": "^2.0.224",
+ "@fluentui/react-jsx-runtime": "^9.0.27",
+ "@fluentui/react-tabster": "^9.17.3",
+ "@fluentui/react-theme": "^9.1.16",
+ "@fluentui/react-utilities": "^9.16.1",
+ "@griffel/react": "^1.5.14",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.9.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.7.3",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-aria/-/react-aria-9.7.3.tgz",
+ "integrity": "sha512-YwyPNEcBDCdY6YzhrIrtlSrLs2Le7X1jLq9em8OnqHeiO22dBmg5xlBJoAMwJ8awCpI9xhu1PhU/2VJY4YqNuA==",
+ "dependencies": {
+ "@fluentui/keyboard-keys": "^9.0.7",
+ "@fluentui/react-shared-contexts": "^9.14.0",
+ "@fluentui/react-tabster": "^9.17.3",
+ "@fluentui/react-utilities": "^9.16.1",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.9.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.6.9",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-avatar/-/react-avatar-9.6.9.tgz",
+ "integrity": "sha512-3aZeUhGOg+UlHsp2x//G4VKRWKclcsZvX6L9UVnHsA/nQqRw7C5Bfo9iFNsEeJ3R5W5mFA6LyEFWedJ7QdAmdQ==",
+ "dependencies": {
+ "@fluentui/react-badge": "^9.2.22",
+ "@fluentui/react-context-selector": "^9.1.49",
+ "@fluentui/react-icons": "^2.0.224",
+ "@fluentui/react-jsx-runtime": "^9.0.27",
+ "@fluentui/react-popover": "^9.8.33",
+ "@fluentui/react-shared-contexts": "^9.14.0",
+ "@fluentui/react-tabster": "^9.17.3",
+ "@fluentui/react-theme": "^9.1.16",
+ "@fluentui/react-tooltip": "^9.4.11",
+ "@fluentui/react-utilities": "^9.16.1",
+ "@griffel/react": "^1.5.14",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.9.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.22",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-badge/-/react-badge-9.2.22.tgz",
+ "integrity": "sha512-zzimP5mZiiCOm8expUTzD6yvvKbnKq22PK/L6+oNpifrvQnDwJF/0nwXQVjA3+icNoYTaHe/q0fFivpXV+Js6g==",
+ "dependencies": {
+ "@fluentui/react-icons": "^2.0.224",
+ "@fluentui/react-jsx-runtime": "^9.0.27",
+ "@fluentui/react-shared-contexts": "^9.14.0",
+ "@fluentui/react-theme": "^9.1.16",
+ "@fluentui/react-utilities": "^9.16.1",
+ "@griffel/react": "^1.5.14",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.9.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.14.0 <19.0.0"
+ }
+ },
+ "node_modules/@fluentui/react-breadcrumb": {
+ "version": "9.0.11",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-breadcrumb/-/react-breadcrumb-9.0.11.tgz",
+ "integrity": "sha512-L+AQqZz1gqkScD8IW1CjZWGNrDaHDc/gSv+PrvgSZeGDPibGj6TnLygJ7BKM+rQ+Hc2SbCogKbERpQZCbrSFvA==",
+ "dependencies": {
+ "@fluentui/react-aria": "^9.7.3",
+ "@fluentui/react-button": "^9.3.65",
+ "@fluentui/react-icons": "^2.0.224",
+ "@fluentui/react-jsx-runtime": "^9.0.27",
+ "@fluentui/react-link": "^9.2.7",
+ "@fluentui/react-shared-contexts": "^9.14.0",
+ "@fluentui/react-tabster": "^9.17.3",
+ "@fluentui/react-theme": "^9.1.16",
+ "@fluentui/react-utilities": "^9.16.1",
+ "@griffel/react": "^1.5.14",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.9.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.65",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-button/-/react-button-9.3.65.tgz",
+ "integrity": "sha512-3VOt29AugkfR7VMnkKON449E7Sn/nvc6BBT4kJDGKQY+Nm5d2p9e4HmHp1UaM9zRPt47lagTY2WFJNrKKSe/BA==",
+ "dependencies": {
+ "@fluentui/keyboard-keys": "^9.0.7",
+ "@fluentui/react-aria": "^9.7.3",
+ "@fluentui/react-icons": "^2.0.224",
+ "@fluentui/react-jsx-runtime": "^9.0.27",
+ "@fluentui/react-shared-contexts": "^9.14.0",
+ "@fluentui/react-tabster": "^9.17.3",
+ "@fluentui/react-theme": "^9.1.16",
+ "@fluentui/react-utilities": "^9.16.1",
+ "@griffel/react": "^1.5.14",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.9.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.64",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-card/-/react-card-9.0.64.tgz",
+ "integrity": "sha512-TB/Zk+tLDUPNyAd2y8BvN0T2nroimtBOpB5GTK72E5sWPk0kaKIHwBEfXxNFGdGXcw0TAmVNqYi4ks37vh0Rgg==",
+ "dependencies": {
+ "@fluentui/keyboard-keys": "^9.0.7",
+ "@fluentui/react-jsx-runtime": "^9.0.27",
+ "@fluentui/react-tabster": "^9.17.3",
+ "@fluentui/react-theme": "^9.1.16",
+ "@fluentui/react-utilities": "^9.16.1",
+ "@griffel/react": "^1.5.14",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.9.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.2.8",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-checkbox/-/react-checkbox-9.2.8.tgz",
+ "integrity": "sha512-L4aWzeZdi98d0ZhgNPtxghfhasQv1qlxIRMaPxtwvk5TN6i9YmRF8vf5Pmf0PESjT+zp3VPcisHcIfcqG26SmQ==",
+ "dependencies": {
+ "@fluentui/react-field": "^9.1.50",
+ "@fluentui/react-icons": "^2.0.224",
+ "@fluentui/react-jsx-runtime": "^9.0.27",
+ "@fluentui/react-label": "^9.1.58",
+ "@fluentui/react-shared-contexts": "^9.14.0",
+ "@fluentui/react-tabster": "^9.17.3",
+ "@fluentui/react-theme": "^9.1.16",
+ "@fluentui/react-utilities": "^9.16.1",
+ "@griffel/react": "^1.5.14",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.9.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.7.0",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-combobox/-/react-combobox-9.7.0.tgz",
+ "integrity": "sha512-YmTdg04rvsg2+Dkw3ob+YLnS9rm3TLVMMNYTH0T64/FM3qirHntIXGbhMZXP5Cdo14gzQwr/e78NjBRKfYO4Wg==",
+ "dependencies": {
+ "@fluentui/keyboard-keys": "^9.0.7",
+ "@fluentui/react-context-selector": "^9.1.49",
+ "@fluentui/react-field": "^9.1.50",
+ "@fluentui/react-icons": "^2.0.224",
+ "@fluentui/react-jsx-runtime": "^9.0.27",
+ "@fluentui/react-portal": "^9.4.10",
+ "@fluentui/react-positioning": "^9.12.4",
+ "@fluentui/react-shared-contexts": "^9.14.0",
+ "@fluentui/react-tabster": "^9.17.3",
+ "@fluentui/react-theme": "^9.1.16",
+ "@fluentui/react-utilities": "^9.16.1",
+ "@griffel/react": "^1.5.14",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.9.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.45.0",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-components/-/react-components-9.45.0.tgz",
+ "integrity": "sha512-Y+Laj1dvRcCp/nWT0DExRXoh7oKTX458g6oltrGjhIHikq4D6/kssK5tfhCyknPLwIlVSYi5J+G6L3NfvI8a8w==",
+ "dependencies": {
+ "@fluentui/react-accordion": "^9.3.38",
+ "@fluentui/react-alert": "9.0.0-beta.104",
+ "@fluentui/react-avatar": "^9.6.9",
+ "@fluentui/react-badge": "^9.2.22",
+ "@fluentui/react-breadcrumb": "^9.0.11",
+ "@fluentui/react-button": "^9.3.65",
+ "@fluentui/react-card": "^9.0.64",
+ "@fluentui/react-checkbox": "^9.2.8",
+ "@fluentui/react-combobox": "^9.7.0",
+ "@fluentui/react-dialog": "^9.9.7",
+ "@fluentui/react-divider": "^9.2.58",
+ "@fluentui/react-drawer": "^9.1.1",
+ "@fluentui/react-field": "^9.1.50",
+ "@fluentui/react-image": "^9.1.55",
+ "@fluentui/react-infobutton": "9.0.0-beta.88",
+ "@fluentui/react-infolabel": "^9.0.16",
+ "@fluentui/react-input": "^9.4.60",
+ "@fluentui/react-label": "^9.1.58",
+ "@fluentui/react-link": "^9.2.7",
+ "@fluentui/react-menu": "^9.12.45",
+ "@fluentui/react-message-bar": "^9.0.16",
+ "@fluentui/react-overflow": "^9.1.8",
+ "@fluentui/react-persona": "^9.2.68",
+ "@fluentui/react-popover": "^9.8.33",
+ "@fluentui/react-portal": "^9.4.10",
+ "@fluentui/react-positioning": "^9.12.4",
+ "@fluentui/react-progress": "^9.1.60",
+ "@fluentui/react-provider": "^9.13.8",
+ "@fluentui/react-radio": "^9.2.3",
+ "@fluentui/react-select": "^9.1.60",
+ "@fluentui/react-shared-contexts": "^9.14.0",
+ "@fluentui/react-skeleton": "^9.0.48",
+ "@fluentui/react-slider": "^9.1.65",
+ "@fluentui/react-spinbutton": "^9.2.60",
+ "@fluentui/react-spinner": "^9.3.38",
+ "@fluentui/react-switch": "^9.1.65",
+ "@fluentui/react-table": "^9.11.5",
+ "@fluentui/react-tabs": "^9.4.6",
+ "@fluentui/react-tabster": "^9.17.3",
+ "@fluentui/react-tags": "^9.0.22",
+ "@fluentui/react-text": "^9.4.7",
+ "@fluentui/react-textarea": "^9.3.60",
+ "@fluentui/react-theme": "^9.1.16",
+ "@fluentui/react-toast": "^9.3.27",
+ "@fluentui/react-toolbar": "^9.1.66",
+ "@fluentui/react-tooltip": "^9.4.11",
+ "@fluentui/react-tree": "^9.4.25",
+ "@fluentui/react-utilities": "^9.16.1",
+ "@fluentui/react-virtualizer": "9.0.0-alpha.66",
+ "@griffel/react": "^1.5.14",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.9.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.49",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-context-selector/-/react-context-selector-9.1.49.tgz",
+ "integrity": "sha512-u4wRNfnyfuZDalVEESBPFQ0Ue4yYu+ozkPQvuEV6kriQGnAQQyyVbIidOCuP7Sja0nBwgM8eAzK0uX/slmmj3Q==",
+ "dependencies": {
+ "@fluentui/react-utilities": "^9.16.1",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.9.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.9.7",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-dialog/-/react-dialog-9.9.7.tgz",
+ "integrity": "sha512-5/6MeaHOYpx8Vt0auMJGLCjn6O1IYtl6IhwdwRNXL6AS1o4F24IKXdWZPtiHWuvzbuZAQd3+5nRDUE5KC9We6A==",
+ "dependencies": {
+ "@fluentui/keyboard-keys": "^9.0.7",
+ "@fluentui/react-aria": "^9.7.3",
+ "@fluentui/react-context-selector": "^9.1.49",
+ "@fluentui/react-icons": "^2.0.224",
+ "@fluentui/react-jsx-runtime": "^9.0.27",
+ "@fluentui/react-portal": "^9.4.10",
+ "@fluentui/react-shared-contexts": "^9.14.0",
+ "@fluentui/react-tabster": "^9.17.3",
+ "@fluentui/react-theme": "^9.1.16",
+ "@fluentui/react-utilities": "^9.16.1",
+ "@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.9.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.58",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-divider/-/react-divider-9.2.58.tgz",
+ "integrity": "sha512-y1ECy1zM4imKhpyOyUGugB+J30tfySO5hhrsIcpaiUQxRjE4IhZf2ZG6EqAQYLinJ+hV06yLZoazekljlvk6yw==",
+ "dependencies": {
+ "@fluentui/react-jsx-runtime": "^9.0.27",
+ "@fluentui/react-shared-contexts": "^9.14.0",
+ "@fluentui/react-theme": "^9.1.16",
+ "@fluentui/react-utilities": "^9.16.1",
+ "@griffel/react": "^1.5.14",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.9.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.1.1",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-drawer/-/react-drawer-9.1.1.tgz",
+ "integrity": "sha512-3zvbbeaLLJZa4MXRpW8Ta4DFZ5457Tq9/4a0CqsIW/+8EuwtJwO+FB5a0DS6j0q6kN4mjkWF19OvzMkJsSTRVw==",
+ "dependencies": {
+ "@fluentui/react-dialog": "^9.9.7",
+ "@fluentui/react-jsx-runtime": "^9.0.27",
+ "@fluentui/react-motion-preview": "^0.5.10",
+ "@fluentui/react-shared-contexts": "^9.14.0",
+ "@fluentui/react-tabster": "^9.17.3",
+ "@fluentui/react-theme": "^9.1.16",
+ "@fluentui/react-utilities": "^9.16.1",
+ "@griffel/react": "^1.5.14",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.9.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.50",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-field/-/react-field-9.1.50.tgz",
+ "integrity": "sha512-2mbx7YReMWvrgi3set9KepLLgMyNJ7StLu/HiHMM3jkcgPt3mGfwoJEsEKt+xd8eUAo4b82F7t+tHI4f9yzJaQ==",
+ "dependencies": {
+ "@fluentui/react-context-selector": "^9.1.49",
+ "@fluentui/react-icons": "^2.0.224",
+ "@fluentui/react-jsx-runtime": "^9.0.27",
+ "@fluentui/react-label": "^9.1.58",
+ "@fluentui/react-theme": "^9.1.16",
+ "@fluentui/react-utilities": "^9.16.1",
+ "@griffel/react": "^1.5.14",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.9.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.38",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-focus/-/react-focus-8.8.38.tgz",
+ "integrity": "sha512-vnsaY7hJSPIJBxm5Pj0FrcFDumV6kKgFVpsKsEKJzb1D88rDDLcmvz9jWUx68a3ru6idEbZYmyePGT1IiRsAug==",
+ "dependencies": {
+ "@fluentui/keyboard-key": "^0.4.14",
+ "@fluentui/merge-styles": "^8.5.15",
+ "@fluentui/set-version": "^8.2.14",
+ "@fluentui/style-utilities": "^8.10.2",
+ "@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.225",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-icons/-/react-icons-2.0.225.tgz",
+ "integrity": "sha512-L9phN3bAMlZCa5+/ObGjIO+5GI8M50ym766sraSq92jaJwgAXrCJDLWuDGWZRGrC63DcagtR2culptj3q7gMMg==",
+ "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.55",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-image/-/react-image-9.1.55.tgz",
+ "integrity": "sha512-hYP61OWLuGSJNPOGJXtphbiDESfLB+/vsODKQsJhrDRJ2CSNMAfNznPHucqGRRN6AWQOI/BynJDS5F22Y//7CQ==",
+ "dependencies": {
+ "@fluentui/react-jsx-runtime": "^9.0.27",
+ "@fluentui/react-shared-contexts": "^9.14.0",
+ "@fluentui/react-theme": "^9.1.16",
+ "@fluentui/react-utilities": "^9.16.1",
+ "@griffel/react": "^1.5.14",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.9.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.88",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-infobutton/-/react-infobutton-9.0.0-beta.88.tgz",
+ "integrity": "sha512-NVZyfrLtoFNu7cGkp2ORWsxJiCk1JgN4CVBDj03QSIh14EsPMwphYgDwfQ8TZOF2Nub0DGtC7/tF8IUlb/aP6g==",
+ "dependencies": {
+ "@fluentui/react-icons": "^2.0.224",
+ "@fluentui/react-jsx-runtime": "^9.0.27",
+ "@fluentui/react-label": "^9.1.58",
+ "@fluentui/react-popover": "^9.8.33",
+ "@fluentui/react-tabster": "^9.17.3",
+ "@fluentui/react-theme": "^9.1.16",
+ "@fluentui/react-utilities": "^9.16.1",
+ "@griffel/react": "^1.5.14",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.9.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.16",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-infolabel/-/react-infolabel-9.0.16.tgz",
+ "integrity": "sha512-UCY+2vB4vOn0LfVhbgkyNG0EiuKIe0PdxEAtLU2PqosHLkaLKnYDKJdiIS/oaFmyNtGHmMxRkigvZpZ7h74f9g==",
+ "dependencies": {
+ "@fluentui/react-icons": "^2.0.224",
+ "@fluentui/react-jsx-runtime": "^9.0.27",
+ "@fluentui/react-label": "^9.1.58",
+ "@fluentui/react-popover": "^9.8.33",
+ "@fluentui/react-tabster": "^9.17.3",
+ "@fluentui/react-theme": "^9.1.16",
+ "@fluentui/react-utilities": "^9.16.1",
+ "@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.60",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-input/-/react-input-9.4.60.tgz",
+ "integrity": "sha512-kuk24K0X0gckTCssXoiWvZsTFVpZJv+WPl2fkjxeffzmFfBZtJUFQkXeC4/hcAg+aScjZnEtqjHjwDEbjZqkeA==",
+ "dependencies": {
+ "@fluentui/react-field": "^9.1.50",
+ "@fluentui/react-jsx-runtime": "^9.0.27",
+ "@fluentui/react-shared-contexts": "^9.14.0",
+ "@fluentui/react-theme": "^9.1.16",
+ "@fluentui/react-utilities": "^9.16.1",
+ "@griffel/react": "^1.5.14",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.9.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.27",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-jsx-runtime/-/react-jsx-runtime-9.0.27.tgz",
+ "integrity": "sha512-9wxsWxVI7RLXsdK+7lzp7TK0FJKnrrj+Igxn0prqAvXdBRiFcuycoCJaHzC4Ka+Hsiol8NQg6xaIR59a28lmyQ==",
+ "dependencies": {
+ "@fluentui/react-utilities": "^9.16.1",
+ "@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-label": {
+ "version": "9.1.58",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-label/-/react-label-9.1.58.tgz",
+ "integrity": "sha512-0ouSMop4vpXJzMvAyfmIr3TgDM/W1k+GFm8ZPD5fDQCopSJ+h3kvUZg5pqaXpBwamvZ16+qRARfTNITp2U7Rjw==",
+ "dependencies": {
+ "@fluentui/react-jsx-runtime": "^9.0.27",
+ "@fluentui/react-shared-contexts": "^9.14.0",
+ "@fluentui/react-theme": "^9.1.16",
+ "@fluentui/react-utilities": "^9.16.1",
+ "@griffel/react": "^1.5.14",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.9.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.2.7",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-link/-/react-link-9.2.7.tgz",
+ "integrity": "sha512-z4X9dcUc/7FlqDxbGKbOfWubru+QimtzgMtlVxZ30pkC959hfIbFpbBY6Me76UOuFiOZxUPdfyY/73ekhhhVxw==",
+ "dependencies": {
+ "@fluentui/keyboard-keys": "^9.0.7",
+ "@fluentui/react-jsx-runtime": "^9.0.27",
+ "@fluentui/react-shared-contexts": "^9.14.0",
+ "@fluentui/react-tabster": "^9.17.3",
+ "@fluentui/react-theme": "^9.1.16",
+ "@fluentui/react-utilities": "^9.16.1",
+ "@griffel/react": "^1.5.14",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.9.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.45",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-menu/-/react-menu-9.12.45.tgz",
+ "integrity": "sha512-qhpmuvAB4DUmmC5lNMakVvZjTdj/GZnH6WctNGZp94iCZLhcnIQcM9l0PvRpUpU1v3irXRyE5QV+x+wXC0awTw==",
+ "dependencies": {
+ "@fluentui/keyboard-keys": "^9.0.7",
+ "@fluentui/react-aria": "^9.7.3",
+ "@fluentui/react-context-selector": "^9.1.49",
+ "@fluentui/react-icons": "^2.0.224",
+ "@fluentui/react-jsx-runtime": "^9.0.27",
+ "@fluentui/react-portal": "^9.4.10",
+ "@fluentui/react-positioning": "^9.12.4",
+ "@fluentui/react-shared-contexts": "^9.14.0",
+ "@fluentui/react-tabster": "^9.17.3",
+ "@fluentui/react-theme": "^9.1.16",
+ "@fluentui/react-utilities": "^9.16.1",
+ "@griffel/react": "^1.5.14",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.9.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.16",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-message-bar/-/react-message-bar-9.0.16.tgz",
+ "integrity": "sha512-R1VnqcFwu0pM2Yk8rjkN48Lx/n44UFD13BuY8/JeEuU8XQ8hLnEBVtdHjzRPJk+iM5in2ScMMQj4Z0nWyCRM1Q==",
+ "dependencies": {
+ "@fluentui/react-button": "^9.3.65",
+ "@fluentui/react-icons": "^2.0.224",
+ "@fluentui/react-jsx-runtime": "^9.0.27",
+ "@fluentui/react-shared-contexts": "^9.14.0",
+ "@fluentui/react-theme": "^9.1.16",
+ "@fluentui/react-utilities": "^9.16.1",
+ "@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.10",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-motion-preview/-/react-motion-preview-0.5.10.tgz",
+ "integrity": "sha512-6iwF3N4hB6IxCoFVusgA2mp6mrTknwcsVGNYEQw1YF5WgGOMF3M0N1xNpN61/SYziT6HSUaI38NaA7LI3Dp3Sw==",
+ "dependencies": {
+ "@fluentui/react-jsx-runtime": "^9.0.27",
+ "@fluentui/react-shared-contexts": "^9.14.0",
+ "@fluentui/react-theme": "^9.1.16",
+ "@fluentui/react-utilities": "^9.16.1",
+ "@griffel/react": "^1.5.14",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.9.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.1.8",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-overflow/-/react-overflow-9.1.8.tgz",
+ "integrity": "sha512-W8L68+0bUtfGr72LRx+U05EZLO0E8VMfscDiNKiEjDrOqdBnqNAIDN86825wrN77HH2wvILN07EhPOauqzz8YQ==",
+ "dependencies": {
+ "@fluentui/priority-overflow": "^9.1.11",
+ "@fluentui/react-context-selector": "^9.1.49",
+ "@fluentui/react-theme": "^9.1.16",
+ "@fluentui/react-utilities": "^9.16.1",
+ "@griffel/react": "^1.5.14",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.9.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.68",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-persona/-/react-persona-9.2.68.tgz",
+ "integrity": "sha512-CYtDiZ34GGaw7lZ85uHZOuYXzkY21VHN6cUlGY1TJn98+Xz+y7JoVLIG7KZHHp2JzmmjtwjvgnqAdOun5LrWig==",
+ "dependencies": {
+ "@fluentui/react-avatar": "^9.6.9",
+ "@fluentui/react-badge": "^9.2.22",
+ "@fluentui/react-jsx-runtime": "^9.0.27",
+ "@fluentui/react-shared-contexts": "^9.14.0",
+ "@fluentui/react-theme": "^9.1.16",
+ "@fluentui/react-utilities": "^9.16.1",
+ "@griffel/react": "^1.5.14",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.9.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.33",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-popover/-/react-popover-9.8.33.tgz",
+ "integrity": "sha512-0yPX6KCdMEGmrvJnQles5iTKN0OZ2vNSPVdkbyEKIUKj5DrNK1cMZEV/7Tgrtn922fx3/74FLMqEpEDTdrvQ/Q==",
+ "dependencies": {
+ "@fluentui/keyboard-keys": "^9.0.7",
+ "@fluentui/react-aria": "^9.7.3",
+ "@fluentui/react-context-selector": "^9.1.49",
+ "@fluentui/react-jsx-runtime": "^9.0.27",
+ "@fluentui/react-portal": "^9.4.10",
+ "@fluentui/react-positioning": "^9.12.4",
+ "@fluentui/react-shared-contexts": "^9.14.0",
+ "@fluentui/react-tabster": "^9.17.3",
+ "@fluentui/react-theme": "^9.1.16",
+ "@fluentui/react-utilities": "^9.16.1",
+ "@griffel/react": "^1.5.14",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.9.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.10",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-portal/-/react-portal-9.4.10.tgz",
+ "integrity": "sha512-k8fTRv9wTPSPCuNBFE2HxIhXsVYoG6Azb6Ib2xaDK+nczoW2WbsmNmwBJGEGi8UKjIoQzV+95KsYQ9me+uqKPA==",
+ "dependencies": {
+ "@fluentui/react-shared-contexts": "^9.14.0",
+ "@fluentui/react-tabster": "^9.17.3",
+ "@fluentui/react-utilities": "^9.16.1",
+ "@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.9.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.12.4",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-positioning/-/react-positioning-9.12.4.tgz",
+ "integrity": "sha512-qQAjHF/FJFs2TyK0x08t0iFtDQlGNGH0OFC3jrG1xIFEe3nFPoeYeNT3zxOmj+D7bvlcJTIITcoe++YQTnCf4w==",
+ "dependencies": {
+ "@floating-ui/devtools": "0.2.1",
+ "@floating-ui/dom": "^1.2.0",
+ "@fluentui/react-shared-contexts": "^9.14.0",
+ "@fluentui/react-theme": "^9.1.16",
+ "@fluentui/react-utilities": "^9.16.1",
+ "@griffel/react": "^1.5.14",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.9.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.60",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-progress/-/react-progress-9.1.60.tgz",
+ "integrity": "sha512-9wC7lWdo3S8rhxKWlIhcYAzsZNw+rL2HvNJTvEvFxXcOG7nJxP/3mGclV/jCCwDoPDnt9BT+40pGK84eD0BNIA==",
+ "dependencies": {
+ "@fluentui/react-field": "^9.1.50",
+ "@fluentui/react-jsx-runtime": "^9.0.27",
+ "@fluentui/react-shared-contexts": "^9.14.0",
+ "@fluentui/react-theme": "^9.1.16",
+ "@fluentui/react-utilities": "^9.16.1",
+ "@griffel/react": "^1.5.14",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.9.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.13.8",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-provider/-/react-provider-9.13.8.tgz",
+ "integrity": "sha512-FCvDMjs/BNAcqJuHU+kN/lqLB2RDQ/LQo29ltfLKFlTR1nTUNJvPMOVhjj6eEt+t81628LOYhbbaXOj9rYtfGg==",
+ "dependencies": {
+ "@fluentui/react-icons": "^2.0.224",
+ "@fluentui/react-jsx-runtime": "^9.0.27",
+ "@fluentui/react-shared-contexts": "^9.14.0",
+ "@fluentui/react-tabster": "^9.17.3",
+ "@fluentui/react-theme": "^9.1.16",
+ "@fluentui/react-utilities": "^9.16.1",
+ "@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.9.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.2.3",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-radio/-/react-radio-9.2.3.tgz",
+ "integrity": "sha512-8eKeUL0ZNr792Q6NGWPp7dpOV2IFcjAQ2oWR2/bruQVu8LMzYYKe2o6pQWdCag6UGPZuszkms9Xl7zPdDQBUdA==",
+ "dependencies": {
+ "@fluentui/react-field": "^9.1.50",
+ "@fluentui/react-jsx-runtime": "^9.0.27",
+ "@fluentui/react-label": "^9.1.58",
+ "@fluentui/react-shared-contexts": "^9.14.0",
+ "@fluentui/react-tabster": "^9.17.3",
+ "@fluentui/react-theme": "^9.1.16",
+ "@fluentui/react-utilities": "^9.16.1",
+ "@griffel/react": "^1.5.14",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.9.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.60",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-select/-/react-select-9.1.60.tgz",
+ "integrity": "sha512-4HfRRTlGStOgtO00RY6jmOwz6MXnoa9gtjkV7StLmJZ2U5NTjVUrnp2dP1Vjb6hO13xaihWGEYyYKnsQ3R7kIw==",
+ "dependencies": {
+ "@fluentui/react-field": "^9.1.50",
+ "@fluentui/react-icons": "^2.0.224",
+ "@fluentui/react-jsx-runtime": "^9.0.27",
+ "@fluentui/react-shared-contexts": "^9.14.0",
+ "@fluentui/react-theme": "^9.1.16",
+ "@fluentui/react-utilities": "^9.16.1",
+ "@griffel/react": "^1.5.14",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.9.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.14.0",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-shared-contexts/-/react-shared-contexts-9.14.0.tgz",
+ "integrity": "sha512-P9yhg31WYfB1W66/gD3+qVCLBsyIEcOzQvKVaIQvd9UhF67lNW4kMXUB6YVOk5PV0Og4hXnkH/vuHl7YMD9RHw==",
+ "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.48",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-skeleton/-/react-skeleton-9.0.48.tgz",
+ "integrity": "sha512-P0Rw5hIOn5CrZIWg7nVoK3gamxFhZI80KcRVaWap4O3gLo5C8nKHJWOtyBQZ5WKH+S6hoEGZ2USL6CoyXslxeQ==",
+ "dependencies": {
+ "@fluentui/react-field": "^9.1.50",
+ "@fluentui/react-jsx-runtime": "^9.0.27",
+ "@fluentui/react-shared-contexts": "^9.14.0",
+ "@fluentui/react-theme": "^9.1.16",
+ "@fluentui/react-utilities": "^9.16.1",
+ "@griffel/react": "^1.5.14",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.9.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.65",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-slider/-/react-slider-9.1.65.tgz",
+ "integrity": "sha512-7kuJMIojxCmNOuiRmQwh9iiXx8zwxkrgvsWmReRIBX0WB6w1VqMcuuikq2Z2ISgNPmepCX8W+qDfx8Ne4F/HtQ==",
+ "dependencies": {
+ "@fluentui/react-field": "^9.1.50",
+ "@fluentui/react-jsx-runtime": "^9.0.27",
+ "@fluentui/react-shared-contexts": "^9.14.0",
+ "@fluentui/react-tabster": "^9.17.3",
+ "@fluentui/react-theme": "^9.1.16",
+ "@fluentui/react-utilities": "^9.16.1",
+ "@griffel/react": "^1.5.14",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.9.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.60",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-spinbutton/-/react-spinbutton-9.2.60.tgz",
+ "integrity": "sha512-0IIxEH0CTf4fNMoyvMa37bc63+0ZlznlsNy8lF3hujAT8Z9sUKVMH68e6tGUuXGJIkCUyDKU8HA+9FF2DyPvNA==",
+ "dependencies": {
+ "@fluentui/keyboard-keys": "^9.0.7",
+ "@fluentui/react-field": "^9.1.50",
+ "@fluentui/react-icons": "^2.0.224",
+ "@fluentui/react-jsx-runtime": "^9.0.27",
+ "@fluentui/react-shared-contexts": "^9.14.0",
+ "@fluentui/react-theme": "^9.1.16",
+ "@fluentui/react-utilities": "^9.16.1",
+ "@griffel/react": "^1.5.14",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.9.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.38",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-spinner/-/react-spinner-9.3.38.tgz",
+ "integrity": "sha512-dPJr7/rgU2Qe/K2BciJTAEwEd0ytGpCw3VOVyK2T25w7Jw5RAHmgP+mbw+7se44Mr6sd1LH76mh5sfmQ3tODgw==",
+ "dependencies": {
+ "@fluentui/react-jsx-runtime": "^9.0.27",
+ "@fluentui/react-label": "^9.1.58",
+ "@fluentui/react-shared-contexts": "^9.14.0",
+ "@fluentui/react-theme": "^9.1.16",
+ "@fluentui/react-utilities": "^9.16.1",
+ "@griffel/react": "^1.5.14",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.9.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.65",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-switch/-/react-switch-9.1.65.tgz",
+ "integrity": "sha512-P0DwogD6hZJ3O005zCFPDoFXuzkrpKMrAeQGh9X0fqFP5JyHXVCgAAZQOLcphbbT9QukoEF5irN2Z4L9gBn57A==",
+ "dependencies": {
+ "@fluentui/react-field": "^9.1.50",
+ "@fluentui/react-icons": "^2.0.224",
+ "@fluentui/react-jsx-runtime": "^9.0.27",
+ "@fluentui/react-label": "^9.1.58",
+ "@fluentui/react-shared-contexts": "^9.14.0",
+ "@fluentui/react-tabster": "^9.17.3",
+ "@fluentui/react-theme": "^9.1.16",
+ "@fluentui/react-utilities": "^9.16.1",
+ "@griffel/react": "^1.5.14",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.9.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.11.5",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-table/-/react-table-9.11.5.tgz",
+ "integrity": "sha512-roQRITOtl1aqXlachS2oTraVE45x3KdDrX0KyQGCdcQRxNprXJW6dIK9QjlbAL6yAsAMDafmFA4y9uRxl408dQ==",
+ "dependencies": {
+ "@fluentui/keyboard-keys": "^9.0.7",
+ "@fluentui/react-aria": "^9.7.3",
+ "@fluentui/react-avatar": "^9.6.9",
+ "@fluentui/react-checkbox": "^9.2.8",
+ "@fluentui/react-context-selector": "^9.1.49",
+ "@fluentui/react-icons": "^2.0.224",
+ "@fluentui/react-jsx-runtime": "^9.0.27",
+ "@fluentui/react-radio": "^9.2.3",
+ "@fluentui/react-shared-contexts": "^9.14.0",
+ "@fluentui/react-tabster": "^9.17.3",
+ "@fluentui/react-theme": "^9.1.16",
+ "@fluentui/react-utilities": "^9.16.1",
+ "@griffel/react": "^1.5.14",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.9.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.4.6",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-tabs/-/react-tabs-9.4.6.tgz",
+ "integrity": "sha512-LQvibLeJFyqKKiOjZUkRvbfLtsVosUhNUdh1SCQUPxQVpEPSK6XgwK0A1+jjoVhKn+PAJakxRINgnvqQD8pQBA==",
+ "dependencies": {
+ "@fluentui/react-context-selector": "^9.1.49",
+ "@fluentui/react-jsx-runtime": "^9.0.27",
+ "@fluentui/react-shared-contexts": "^9.14.0",
+ "@fluentui/react-tabster": "^9.17.3",
+ "@fluentui/react-theme": "^9.1.16",
+ "@fluentui/react-utilities": "^9.16.1",
+ "@griffel/react": "^1.5.14",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.9.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.17.3",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-tabster/-/react-tabster-9.17.3.tgz",
+ "integrity": "sha512-cFcUYrkGW15w5yXzCPTTVG/7x5kNXxnhQXuh8SPyCc9JZeG7XI3+hy1T37PsXGxNS4KN9ePHkBHzgDfYO4gzYQ==",
+ "dependencies": {
+ "@fluentui/react-shared-contexts": "^9.14.0",
+ "@fluentui/react-theme": "^9.1.16",
+ "@fluentui/react-utilities": "^9.16.1",
+ "@griffel/react": "^1.5.14",
+ "@swc/helpers": "^0.5.1",
+ "keyborg": "^2.3.0",
+ "tabster": "^5.0.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.9.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.22",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-tags/-/react-tags-9.0.22.tgz",
+ "integrity": "sha512-gQIOCVu3HIfGjtAmwOnwBEnTsNyRBU8Pvs6EugpUyyqkRjzbm5TnL3LtiUy4f6/+NuaRqcYAvhwpdUhrlciwcA==",
+ "dependencies": {
+ "@fluentui/keyboard-keys": "^9.0.7",
+ "@fluentui/react-aria": "^9.7.3",
+ "@fluentui/react-avatar": "^9.6.9",
+ "@fluentui/react-icons": "^2.0.224",
+ "@fluentui/react-jsx-runtime": "^9.0.27",
+ "@fluentui/react-shared-contexts": "^9.14.0",
+ "@fluentui/react-tabster": "^9.17.3",
+ "@fluentui/react-theme": "^9.1.16",
+ "@fluentui/react-utilities": "^9.16.1",
+ "@griffel/react": "^1.5.14",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.9.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.4.7",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-text/-/react-text-9.4.7.tgz",
+ "integrity": "sha512-c6uJ98B35L8sviYxhQj1i+LW+HVNDdco2ImS9VLv/Duo4HiYs1G2y1YhtBDDiGxLe2moIvfg9ajDzMZV29aXFw==",
+ "dependencies": {
+ "@fluentui/react-jsx-runtime": "^9.0.27",
+ "@fluentui/react-shared-contexts": "^9.14.0",
+ "@fluentui/react-theme": "^9.1.16",
+ "@fluentui/react-utilities": "^9.16.1",
+ "@griffel/react": "^1.5.14",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.9.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.60",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-textarea/-/react-textarea-9.3.60.tgz",
+ "integrity": "sha512-wH4MBWT4EOgNH9FXTjcgH34oANUaoduhmVjffnxaPl3R767Ak0fZPG7kky7yrLMjTDUSwILsEj/q+hsN6o+7Ag==",
+ "dependencies": {
+ "@fluentui/react-field": "^9.1.50",
+ "@fluentui/react-jsx-runtime": "^9.0.27",
+ "@fluentui/react-shared-contexts": "^9.14.0",
+ "@fluentui/react-theme": "^9.1.16",
+ "@fluentui/react-utilities": "^9.16.1",
+ "@griffel/react": "^1.5.14",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.9.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.27",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-toast/-/react-toast-9.3.27.tgz",
+ "integrity": "sha512-DbRAYyL5Bd/pcFiGHPpK+rQMyc4LBll9YBy496l97dGDO2HmqFuiwP74V1KznxLcr4inCNWwThIJws5VLFsJLg==",
+ "dependencies": {
+ "@fluentui/keyboard-keys": "^9.0.7",
+ "@fluentui/react-aria": "^9.7.3",
+ "@fluentui/react-icons": "^2.0.224",
+ "@fluentui/react-jsx-runtime": "^9.0.27",
+ "@fluentui/react-portal": "^9.4.10",
+ "@fluentui/react-shared-contexts": "^9.14.0",
+ "@fluentui/react-tabster": "^9.17.3",
+ "@fluentui/react-theme": "^9.1.16",
+ "@fluentui/react-utilities": "^9.16.1",
+ "@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.9.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.66",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-toolbar/-/react-toolbar-9.1.66.tgz",
+ "integrity": "sha512-ooNTp1R5MBZwiVK8fiJu29gE48vUx4NbXdwB2yHcCprasG3asjuoKQfOYM4+1NfFA0DetVrbK8L46IBeZyeBvA==",
+ "dependencies": {
+ "@fluentui/react-button": "^9.3.65",
+ "@fluentui/react-context-selector": "^9.1.49",
+ "@fluentui/react-divider": "^9.2.58",
+ "@fluentui/react-jsx-runtime": "^9.0.27",
+ "@fluentui/react-radio": "^9.2.3",
+ "@fluentui/react-shared-contexts": "^9.14.0",
+ "@fluentui/react-tabster": "^9.17.3",
+ "@fluentui/react-theme": "^9.1.16",
+ "@fluentui/react-utilities": "^9.16.1",
+ "@griffel/react": "^1.5.14",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.9.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.4.11",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-tooltip/-/react-tooltip-9.4.11.tgz",
+ "integrity": "sha512-HXm8yYuAHJuczeFExco0WQSjO3DzDj5AJxqICHF8qtbtihUKfWpPnKM1qQWR+yJR2zc2jzvOEIzZXEkxSG+fSg==",
+ "dependencies": {
+ "@fluentui/keyboard-keys": "^9.0.7",
+ "@fluentui/react-jsx-runtime": "^9.0.27",
+ "@fluentui/react-portal": "^9.4.10",
+ "@fluentui/react-positioning": "^9.12.4",
+ "@fluentui/react-shared-contexts": "^9.14.0",
+ "@fluentui/react-tabster": "^9.17.3",
+ "@fluentui/react-theme": "^9.1.16",
+ "@fluentui/react-utilities": "^9.16.1",
+ "@griffel/react": "^1.5.14",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.9.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.25",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-tree/-/react-tree-9.4.25.tgz",
+ "integrity": "sha512-7IMqnOiNFMRuPujnbxJUYD8AEh0z1OGXkdNkAeLyj3pkwuvQs9+TbaNtv5Z372YN+kwYF4EYalYcPuNsRlx7cQ==",
+ "dependencies": {
+ "@fluentui/keyboard-keys": "^9.0.7",
+ "@fluentui/react-aria": "^9.7.3",
+ "@fluentui/react-avatar": "^9.6.9",
+ "@fluentui/react-button": "^9.3.65",
+ "@fluentui/react-checkbox": "^9.2.8",
+ "@fluentui/react-context-selector": "^9.1.49",
+ "@fluentui/react-icons": "^2.0.224",
+ "@fluentui/react-jsx-runtime": "^9.0.27",
+ "@fluentui/react-radio": "^9.2.3",
+ "@fluentui/react-shared-contexts": "^9.14.0",
+ "@fluentui/react-tabster": "^9.17.3",
+ "@fluentui/react-theme": "^9.1.16",
+ "@fluentui/react-utilities": "^9.16.1",
+ "@griffel/react": "^1.5.14",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.9.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.16.1",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-utilities/-/react-utilities-9.16.1.tgz",
+ "integrity": "sha512-2wdwmgTFcVy14ZLbRNJ8Q6dCCBLekkJ8Znnok68gKRLDcwpPT3UjSraoU+DGjOA5BMfPppZBU8Yb5GqdIfd48g==",
+ "dependencies": {
+ "@fluentui/keyboard-keys": "^9.0.7",
+ "@fluentui/react-shared-contexts": "^9.14.0",
+ "@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.66",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-virtualizer/-/react-virtualizer-9.0.0-alpha.66.tgz",
+ "integrity": "sha512-x/ZOAIAwctt7pvOBIzS4iZGU0ahiPhQFS7iAHksFkF9LimneaV92A/02dW0Cy4v7dv9wZNoosQwhS05Yx3DVDQ==",
+ "dependencies": {
+ "@fluentui/react-jsx-runtime": "^9.0.27",
+ "@fluentui/react-shared-contexts": "^9.14.0",
+ "@fluentui/react-utilities": "^9.16.1",
+ "@griffel/react": "^1.5.14",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.9.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.2",
+ "resolved": "https://registry.npmjs.org/@fluentui/style-utilities/-/style-utilities-8.10.2.tgz",
+ "integrity": "sha512-ocELtMb/85nBa3rSfiAIwYx6TydN+3rQqv1P0H/L7etYNNtxOfS86JSWfn8zAsHMejbwUKJ1ZsIKs47c598XGQ==",
+ "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.2",
+ "resolved": "https://registry.npmjs.org/@griffel/core/-/core-1.15.2.tgz",
+ "integrity": "sha512-RlsIXoSS3gaYykUgxFpwKAs/DV9cRUKp3CW1kt3iPAtsDTWn/o+8bT1jvBws/tMM2GBu/Uc0EkaIzUPqD7uA+Q==",
+ "dependencies": {
+ "@emotion/hash": "^0.9.0",
+ "@griffel/style-types": "^1.0.3",
+ "csstype": "^3.1.3",
+ "rtl-css-js": "^1.16.1",
+ "stylis": "^4.2.0",
+ "tslib": "^2.1.0"
+ }
+ },
+ "node_modules/@griffel/react": {
+ "version": "1.5.20",
+ "resolved": "https://registry.npmjs.org/@griffel/react/-/react-1.5.20.tgz",
+ "integrity": "sha512-1P2yaPctENFSCwyPIYXBmgpNH68c0lc/jwSzPij1QATHDK1AASKuSeq6hW108I67RKjhRyHCcALshdZ3GcQXSg==",
+ "dependencies": {
+ "@griffel/core": "^1.15.2",
+ "tslib": "^2.1.0"
+ },
+ "peerDependencies": {
+ "react": ">=16.8.0 <19.0.0"
+ }
+ },
+ "node_modules/@griffel/style-types": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/@griffel/style-types/-/style-types-1.0.3.tgz",
+ "integrity": "sha512-AzbbYV/EobNIBtfMtyu2edFin895gjVxtu1nsRhTETUAIb0/LCZoue3Jd/kFLuPwe95rv5WRUBiQpVwJsrrFcw==",
+ "dependencies": {
+ "csstype": "^3.1.3"
+ }
+ },
+ "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.21",
+ "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.21.tgz",
+ "integrity": "sha512-SRfKmRe1KvYnxjEMtxEr+J4HIeMX5YBg/qhRHpxEIGjhX1rshcHlnFUE9K0GazhVKWM7B+nARSkV8LuvJdJ5/g==",
+ "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/@react-spring/animated": {
+ "version": "9.7.3",
+ "resolved": "https://registry.npmjs.org/@react-spring/animated/-/animated-9.7.3.tgz",
+ "integrity": "sha512-5CWeNJt9pNgyvuSzQH+uy2pvTg8Y4/OisoscZIR8/ZNLIOI+CatFBhGZpDGTF/OzdNFsAoGk3wiUYTwoJ0YIvw==",
+ "dependencies": {
+ "@react-spring/shared": "~9.7.3",
+ "@react-spring/types": "~9.7.3"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0 || ^18.0.0"
+ }
+ },
+ "node_modules/@react-spring/core": {
+ "version": "9.7.3",
+ "resolved": "https://registry.npmjs.org/@react-spring/core/-/core-9.7.3.tgz",
+ "integrity": "sha512-IqFdPVf3ZOC1Cx7+M0cXf4odNLxDC+n7IN3MDcVCTIOSBfqEcBebSv+vlY5AhM0zw05PDbjKrNmBpzv/AqpjnQ==",
+ "dependencies": {
+ "@react-spring/animated": "~9.7.3",
+ "@react-spring/shared": "~9.7.3",
+ "@react-spring/types": "~9.7.3"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/react-spring/donate"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0 || ^18.0.0"
+ }
+ },
+ "node_modules/@react-spring/shared": {
+ "version": "9.7.3",
+ "resolved": "https://registry.npmjs.org/@react-spring/shared/-/shared-9.7.3.tgz",
+ "integrity": "sha512-NEopD+9S5xYyQ0pGtioacLhL2luflh6HACSSDUZOwLHoxA5eku1UPuqcJqjwSD6luKjjLfiLOspxo43FUHKKSA==",
+ "dependencies": {
+ "@react-spring/types": "~9.7.3"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0 || ^18.0.0"
+ }
+ },
+ "node_modules/@react-spring/types": {
+ "version": "9.7.3",
+ "resolved": "https://registry.npmjs.org/@react-spring/types/-/types-9.7.3.tgz",
+ "integrity": "sha512-Kpx/fQ/ZFX31OtlqVEFfgaD1ACzul4NksrvIgYfIFq9JpDHFwQkMVZ10tbo0FU/grje4rcL4EIrjekl3kYwgWw=="
+ },
+ "node_modules/@react-spring/web": {
+ "version": "9.7.3",
+ "resolved": "https://registry.npmjs.org/@react-spring/web/-/web-9.7.3.tgz",
+ "integrity": "sha512-BXt6BpS9aJL/QdVqEIX9YoUy8CE6TJrU0mNCqSoxdXlIeNcEBWOfIyE6B14ENNsyQKS3wOWkiJfco0tCr/9tUg==",
+ "dependencies": {
+ "@react-spring/animated": "~9.7.3",
+ "@react-spring/core": "~9.7.3",
+ "@react-spring/shared": "~9.7.3",
+ "@react-spring/types": "~9.7.3"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0 || ^18.0.0",
+ "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0"
+ }
+ },
+ "node_modules/@remix-run/router": {
+ "version": "1.14.2",
+ "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.14.2.tgz",
+ "integrity": "sha512-ACXpdMM9hmKZww21yEqWwiLws/UPLhNKvimN8RrYSqPSvB3ov7sLvAcfvaxePeLvccTQKGdkDIhLYApZVDFuKg==",
+ "engines": {
+ "node": ">=14.0.0"
+ }
+ },
+ "node_modules/@rollup/plugin-typescript": {
+ "version": "11.1.3",
+ "resolved": "https://registry.npmjs.org/@rollup/plugin-typescript/-/plugin-typescript-11.1.3.tgz",
+ "integrity": "sha512-8o6cNgN44kQBcpsUJTbTXMTtb87oR1O0zgP3Dxm71hrNgparap3VujgofEilTYJo+ivf2ke6uy3/E5QEaiRlDA==",
+ "dependencies": {
+ "@rollup/pluginutils": "^5.0.1",
+ "resolve": "^1.22.1"
+ },
+ "engines": {
+ "node": ">=14.0.0"
+ },
+ "peerDependencies": {
+ "rollup": "^2.14.0||^3.0.0",
+ "tslib": "*",
+ "typescript": ">=3.7.0"
+ },
+ "peerDependenciesMeta": {
+ "rollup": {
+ "optional": true
+ },
+ "tslib": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@rollup/pluginutils": {
+ "version": "5.0.4",
+ "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.0.4.tgz",
+ "integrity": "sha512-0KJnIoRI8A+a1dqOYLxH8vBf8bphDmty5QvIm2hqm7oFCFYKCAZWWd2hXgMibaPsNDhI0AtpYfQZJG47pt/k4g==",
+ "dependencies": {
+ "@types/estree": "^1.0.0",
+ "estree-walker": "^2.0.2",
+ "picomatch": "^2.3.1"
+ },
+ "engines": {
+ "node": ">=14.0.0"
+ },
+ "peerDependencies": {
+ "rollup": "^1.20.0||^2.0.0||^3.0.0"
+ },
+ "peerDependenciesMeta": {
+ "rollup": {
+ "optional": true
+ }
+ }
+ },
+ "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.5",
+ "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz",
+ "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==",
+ "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.8",
+ "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.8.tgz",
+ "integrity": "sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw==",
+ "dev": true,
+ "dependencies": {
+ "@babel/types": "^7.0.0"
+ }
+ },
+ "node_modules/@types/babel__template": {
+ "version": "7.4.4",
+ "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz",
+ "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==",
+ "dev": true,
+ "dependencies": {
+ "@babel/parser": "^7.1.0",
+ "@babel/types": "^7.0.0"
+ }
+ },
+ "node_modules/@types/babel__traverse": {
+ "version": "7.20.5",
+ "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.5.tgz",
+ "integrity": "sha512-WXCyOcRtH37HAUkpXhUduaxdm82b4GSlyTqajXviN4EfiuPgNYR109xMCKvpl6zPIpua0DGlMEDCq+g8EdoheQ==",
+ "dev": true,
+ "dependencies": {
+ "@babel/types": "^7.20.7"
+ }
+ },
+ "node_modules/@types/dompurify": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/@types/dompurify/-/dompurify-3.0.3.tgz",
+ "integrity": "sha512-odiGr/9/qMqjcBOe5UhcNLOFHSYmKFOyr+bJ/Xu3Qp4k1pNPAlNLUVNNLcLfjQI7+W7ObX58EdD3H+3p3voOvA==",
+ "dev": true,
+ "dependencies": {
+ "@types/trusted-types": "*"
+ }
+ },
+ "node_modules/@types/estree": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.1.tgz",
+ "integrity": "sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA=="
+ },
+ "node_modules/@types/prop-types": {
+ "version": "15.7.5",
+ "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz",
+ "integrity": "sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w=="
+ },
+ "node_modules/@types/react": {
+ "version": "18.2.48",
+ "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.48.tgz",
+ "integrity": "sha512-qboRCl6Ie70DQQG9hhNREz81jqC1cs9EVNcjQ1AU+jH6NFfSAhVVbrrY/+nSF+Bsk4AOwm9Qa61InvMCyV+H3w==",
+ "dependencies": {
+ "@types/prop-types": "*",
+ "@types/scheduler": "*",
+ "csstype": "^3.0.2"
+ }
+ },
+ "node_modules/@types/react-dom": {
+ "version": "18.2.18",
+ "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.2.18.tgz",
+ "integrity": "sha512-TJxDm6OfAX2KJWJdMEVTwWke5Sc/E/RlnPGvGfS0W7+6ocy2xhDVQVh/KvC2Uf7kACs+gDytdusDSdWfWkaNzw==",
+ "dependencies": {
+ "@types/react": "*"
+ }
+ },
+ "node_modules/@types/scheduler": {
+ "version": "0.16.2",
+ "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.2.tgz",
+ "integrity": "sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew=="
+ },
+ "node_modules/@types/trusted-types": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.3.tgz",
+ "integrity": "sha512-NfQ4gyz38SL8sDNrSixxU2Os1a5xcdFxipAFxYEuLUlvU2uDwS4NUpsImcf1//SlWItCVMMLiylsxbmNMToV/g==",
+ "dev": true
+ },
+ "node_modules/@vitejs/plugin-react": {
+ "version": "4.2.1",
+ "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-4.2.1.tgz",
+ "integrity": "sha512-oojO9IDc4nCUUi8qIR11KoQm0XFFLIwsRBwHRR4d/88IWghn1y6ckz/bJ8GHDCsYEJee8mDzqtJxh15/cisJNQ==",
+ "dev": true,
+ "dependencies": {
+ "@babel/core": "^7.23.5",
+ "@babel/plugin-transform-react-jsx-self": "^7.23.3",
+ "@babel/plugin-transform-react-jsx-source": "^7.23.3",
+ "@types/babel__core": "^7.20.5",
+ "react-refresh": "^0.14.0"
+ },
+ "engines": {
+ "node": "^14.18.0 || >=16.0.0"
+ },
+ "peerDependencies": {
+ "vite": "^4.2.0 || ^5.0.0"
+ }
+ },
+ "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/browserslist": {
+ "version": "4.22.2",
+ "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.22.2.tgz",
+ "integrity": "sha512-0UgcrvQmBDvZHFGdYUehrCNIazki7/lUP3kkoi/r3YB2amZbFM9J43ZRkJTXBUZK4gmx56+Sqk9+Vs9mwZx9+A==",
+ "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.30001565",
+ "electron-to-chromium": "^1.4.601",
+ "node-releases": "^2.0.14",
+ "update-browserslist-db": "^1.0.13"
+ },
+ "bin": {
+ "browserslist": "cli.js"
+ },
+ "engines": {
+ "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7"
+ }
+ },
+ "node_modules/caniuse-lite": {
+ "version": "1.0.30001579",
+ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001579.tgz",
+ "integrity": "sha512-u5AUVkixruKHJjw/pj9wISlcMpgFWzSrczLZbrqBSxukQixmg0SJ5sZTpvaFvxU0HoQKd4yoyAogyrAz9pzJnA==",
+ "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/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/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/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/csstype": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz",
+ "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw=="
+ },
+ "node_modules/debug": {
+ "version": "4.3.4",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
+ "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
+ "dev": true,
+ "dependencies": {
+ "ms": "2.1.2"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/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/dompurify": {
+ "version": "3.0.6",
+ "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.0.6.tgz",
+ "integrity": "sha512-ilkD8YEnnGh1zJ240uJsW7AzE+2qpbOUYjacomn3AvJ6J4JhKGSZ2nh4wUIXPZrEPppaCLx5jFe8T89Rk8tQ7w=="
+ },
+ "node_modules/electron-to-chromium": {
+ "version": "1.4.639",
+ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.639.tgz",
+ "integrity": "sha512-CkKf3ZUVZchr+zDpAlNLEEy2NJJ9T64ULWaDgy3THXXlPVPkLu3VOs9Bac44nebVtdwl2geSj6AxTtGDOxoXhg==",
+ "dev": true
+ },
+ "node_modules/esbuild": {
+ "version": "0.18.11",
+ "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.11.tgz",
+ "integrity": "sha512-i8u6mQF0JKJUlGR3OdFLKldJQMMs8OqM9Cc3UCi9XXziJ9WERM5bfkHaEAy0YAvPRMgqSW55W7xYn84XtEFTtA==",
+ "dev": true,
+ "hasInstallScript": true,
+ "bin": {
+ "esbuild": "bin/esbuild"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "optionalDependencies": {
+ "@esbuild/android-arm": "0.18.11",
+ "@esbuild/android-arm64": "0.18.11",
+ "@esbuild/android-x64": "0.18.11",
+ "@esbuild/darwin-arm64": "0.18.11",
+ "@esbuild/darwin-x64": "0.18.11",
+ "@esbuild/freebsd-arm64": "0.18.11",
+ "@esbuild/freebsd-x64": "0.18.11",
+ "@esbuild/linux-arm": "0.18.11",
+ "@esbuild/linux-arm64": "0.18.11",
+ "@esbuild/linux-ia32": "0.18.11",
+ "@esbuild/linux-loong64": "0.18.11",
+ "@esbuild/linux-mips64el": "0.18.11",
+ "@esbuild/linux-ppc64": "0.18.11",
+ "@esbuild/linux-riscv64": "0.18.11",
+ "@esbuild/linux-s390x": "0.18.11",
+ "@esbuild/linux-x64": "0.18.11",
+ "@esbuild/netbsd-x64": "0.18.11",
+ "@esbuild/openbsd-x64": "0.18.11",
+ "@esbuild/sunos-x64": "0.18.11",
+ "@esbuild/win32-arm64": "0.18.11",
+ "@esbuild/win32-ia32": "0.18.11",
+ "@esbuild/win32-x64": "0.18.11"
+ }
+ },
+ "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/estree-walker": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz",
+ "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w=="
+ },
+ "node_modules/fsevents": {
+ "version": "2.3.2",
+ "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
+ "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
+ "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=="
+ },
+ "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/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/has": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
+ "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
+ "dependencies": {
+ "function-bind": "^1.1.1"
+ },
+ "engines": {
+ "node": ">= 0.4.0"
+ }
+ },
+ "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/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==",
+ "dependencies": {
+ "has": "^1.0.3"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "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/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/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/keyborg": {
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/keyborg/-/keyborg-2.4.1.tgz",
+ "integrity": "sha512-B9EZwDd36WKlIq6JmimaTsTDx5E0aUqZcxtgTfK66ut1FbRXYhBmiB7Al2qKzB7CCX9C49sTBiiyVzsXCA6J4Q=="
+ },
+ "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/ms": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
+ "dev": true
+ },
+ "node_modules/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/ndjson-readablestream": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/ndjson-readablestream/-/ndjson-readablestream-1.0.7.tgz",
+ "integrity": "sha512-4DDTwYTV4yRnCoXparQTF3JeahTNkLVy7XlA0RHXzAqQ3uU8vcu97bNW8rXAQOKQVJGs2aZoX+7cbvfs0LENEA=="
+ },
+ "node_modules/node-releases": {
+ "version": "2.0.14",
+ "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz",
+ "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==",
+ "dev": true
+ },
+ "node_modules/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/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=="
+ },
+ "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==",
+ "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/prettier": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.0.3.tgz",
+ "integrity": "sha512-L/4pUDMxcNa8R/EthV08Zt42WBO4h1rarVtK0K+QJG0X187OLo7l699jWw0GKuwzkPQ//jMFA/8Xm6Fh3J/DAg==",
+ "dev": true,
+ "bin": {
+ "prettier": "bin/prettier.cjs"
+ },
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "url": "https://github.com/prettier/prettier?sponsor=1"
+ }
+ },
+ "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/prop-types/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": {
+ "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": "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/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.21.3",
+ "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.21.3.tgz",
+ "integrity": "sha512-a0H638ZXULv1OdkmiK6s6itNhoy33ywxmUFT/xtSoVyf9VnC7n7+VT4LjVzdIHSaF5TIh9ylUgxMXksHTgGrKg==",
+ "dependencies": {
+ "@remix-run/router": "1.14.2"
+ },
+ "engines": {
+ "node": ">=14.0.0"
+ },
+ "peerDependencies": {
+ "react": ">=16.8"
+ }
+ },
+ "node_modules/react-router-dom": {
+ "version": "6.21.3",
+ "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.21.3.tgz",
+ "integrity": "sha512-kNzubk7n4YHSrErzjLK72j0B5i969GsuCGazRl3G6j1zqZBLjuSlYBdVdkDOgzGdPIffUOc9nmgiadTEVoq91g==",
+ "dependencies": {
+ "@remix-run/router": "1.14.2",
+ "react-router": "6.21.3"
+ },
+ "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/regenerator-runtime": {
+ "version": "0.14.1",
+ "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz",
+ "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw=="
+ },
+ "node_modules/resolve": {
+ "version": "1.22.4",
+ "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.4.tgz",
+ "integrity": "sha512-PXNdCiPqDqeUou+w1C2eTQbNfxKSuMxqTCuvlmmMsk1NWHL5fRrhY6Pl0qEYYc6+QqGClco1Qj8XnjPego4wfg==",
+ "dependencies": {
+ "is-core-module": "^2.13.0",
+ "path-parse": "^1.0.7",
+ "supports-preserve-symlinks-flag": "^1.0.0"
+ },
+ "bin": {
+ "resolve": "bin/resolve"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/rollup": {
+ "version": "3.29.4",
+ "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.29.4.tgz",
+ "integrity": "sha512-oWzmBZwvYrU0iJHtDmhsm662rC15FRXmcjCk1xD771dFDx5jJ02ufAQQTn0etB2emNk4J9EZg/yWKpsn9BWGRw==",
+ "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/scheduler": {
+ "version": "0.20.2",
+ "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.20.2.tgz",
+ "integrity": "sha512-2eWfGgAqqWFGqtdMmcL5zCMK1U8KlXv8SQFGglL3CEtd0aDVDWgeF/YoCmvln55m5zSk3J/20hTaSBeSObsQDQ==",
+ "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/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/stylis": {
+ "version": "4.3.1",
+ "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.3.1.tgz",
+ "integrity": "sha512-EQepAV+wMsIaGVGX1RECzgrcqRRU/0sYOHkeLsZ3fzHaHXZy4DaOOX0vOlGQdlsjkh3mFHAIlVimpwAs4dslyQ=="
+ },
+ "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==",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/tabster": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/tabster/-/tabster-5.2.0.tgz",
+ "integrity": "sha512-cSi3a0gGeM9Co/gTKHlhTFfiitwVjcA+kP9lJux0U7QaRrZox1yYrfbwZhJXM7N0fux7BgvCYaOxME5k0EQ0tA==",
+ "dependencies": {
+ "keyborg": "^2.2.0",
+ "tslib": "^2.3.1"
+ }
+ },
+ "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/tslib": {
+ "version": "2.5.0",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.0.tgz",
+ "integrity": "sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg=="
+ },
+ "node_modules/typescript": {
+ "version": "5.2.2",
+ "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz",
+ "integrity": "sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==",
+ "bin": {
+ "tsc": "bin/tsc",
+ "tsserver": "bin/tsserver"
+ },
+ "engines": {
+ "node": ">=14.17"
+ }
+ },
+ "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/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/vite": {
+ "version": "4.5.3",
+ "resolved": "https://registry.npmjs.org/vite/-/vite-4.5.3.tgz",
+ "integrity": "sha512-kQL23kMeX92v3ph7IauVkXkikdDRsYMGTVl5KY2E9OY4ONLvkHf04MDTbnfo6NKxZiDLWzVpP5oTa8hQD8U3dg==",
+ "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/yallist": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
+ "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==",
+ "dev": true
+ }
+ },
+ "dependencies": {
+ "@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,
+ "requires": {
+ "@jridgewell/gen-mapping": "^0.3.0",
+ "@jridgewell/trace-mapping": "^0.3.9"
+ }
+ },
+ "@azure/msal-browser": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/@azure/msal-browser/-/msal-browser-3.2.0.tgz",
+ "integrity": "sha512-le2qutddMiq0i3ErQaLKuwP1DpNgdd9iXPs3fSCsLuBrdGg9B4/j4ArCAHCwgxA82Ydj9BcqtMIL5BSWwU+P5A==",
+ "requires": {
+ "@azure/msal-common": "14.1.0"
+ }
+ },
+ "@azure/msal-common": {
+ "version": "14.1.0",
+ "resolved": "https://registry.npmjs.org/@azure/msal-common/-/msal-common-14.1.0.tgz",
+ "integrity": "sha512-xphmhcfl5VL+uq5//VKMwQn+wfEZLMKNpFCcMi8Ur8ej5UT166g6chBsxgMzc9xo9Y24R9FB3m/tjDiV03xMIA=="
+ },
+ "@azure/msal-react": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/@azure/msal-react/-/msal-react-2.0.4.tgz",
+ "integrity": "sha512-BujRm5FBDWYXyr3pnmubS4dIqZMlurYVtV2AyztoeAFUd+nh3XQZD9knHBqTyu53IDjhCCvUPUke/jSkv5WGlg==",
+ "requires": {
+ "@rollup/plugin-typescript": "^11.1.0",
+ "rollup": "^3.20.2"
+ }
+ },
+ "@babel/code-frame": {
+ "version": "7.23.5",
+ "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.23.5.tgz",
+ "integrity": "sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA==",
+ "dev": true,
+ "requires": {
+ "@babel/highlight": "^7.23.4",
+ "chalk": "^2.4.2"
+ }
+ },
+ "@babel/compat-data": {
+ "version": "7.23.5",
+ "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.23.5.tgz",
+ "integrity": "sha512-uU27kfDRlhfKl+w1U6vp16IuvSLtjAxdArVXPa9BvLkrr7CYIsxH5adpHObeAGY/41+syctUWOZ140a2Rvkgjw==",
+ "dev": true
+ },
+ "@babel/core": {
+ "version": "7.23.7",
+ "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.23.7.tgz",
+ "integrity": "sha512-+UpDgowcmqe36d4NwqvKsyPMlOLNGMsfMmQ5WGCu+siCe3t3dfe9njrzGfdN4qq+bcNUt0+Vw6haRxBOycs4dw==",
+ "dev": true,
+ "requires": {
+ "@ampproject/remapping": "^2.2.0",
+ "@babel/code-frame": "^7.23.5",
+ "@babel/generator": "^7.23.6",
+ "@babel/helper-compilation-targets": "^7.23.6",
+ "@babel/helper-module-transforms": "^7.23.3",
+ "@babel/helpers": "^7.23.7",
+ "@babel/parser": "^7.23.6",
+ "@babel/template": "^7.22.15",
+ "@babel/traverse": "^7.23.7",
+ "@babel/types": "^7.23.6",
+ "convert-source-map": "^2.0.0",
+ "debug": "^4.1.0",
+ "gensync": "^1.0.0-beta.2",
+ "json5": "^2.2.3",
+ "semver": "^6.3.1"
+ }
+ },
+ "@babel/generator": {
+ "version": "7.23.6",
+ "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.6.tgz",
+ "integrity": "sha512-qrSfCYxYQB5owCmGLbl8XRpX1ytXlpueOb0N0UmQwA073KZxejgQTzAmJezxvpwQD9uGtK2shHdi55QT+MbjIw==",
+ "dev": true,
+ "requires": {
+ "@babel/types": "^7.23.6",
+ "@jridgewell/gen-mapping": "^0.3.2",
+ "@jridgewell/trace-mapping": "^0.3.17",
+ "jsesc": "^2.5.1"
+ }
+ },
+ "@babel/helper-compilation-targets": {
+ "version": "7.23.6",
+ "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.23.6.tgz",
+ "integrity": "sha512-9JB548GZoQVmzrFgp8o7KxdgkTGm6xs9DW0o/Pim72UDjzr5ObUQ6ZzYPqA+g9OTS2bBQoctLJrky0RDCAWRgQ==",
+ "dev": true,
+ "requires": {
+ "@babel/compat-data": "^7.23.5",
+ "@babel/helper-validator-option": "^7.23.5",
+ "browserslist": "^4.22.2",
+ "lru-cache": "^5.1.1",
+ "semver": "^6.3.1"
+ }
+ },
+ "@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
+ },
+ "@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,
+ "requires": {
+ "@babel/template": "^7.22.15",
+ "@babel/types": "^7.23.0"
+ }
+ },
+ "@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,
+ "requires": {
+ "@babel/types": "^7.22.5"
+ }
+ },
+ "@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,
+ "requires": {
+ "@babel/types": "^7.22.15"
+ }
+ },
+ "@babel/helper-module-transforms": {
+ "version": "7.23.3",
+ "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.23.3.tgz",
+ "integrity": "sha512-7bBs4ED9OmswdfDzpz4MpWgSrV7FXlc3zIagvLFjS5H+Mk7Snr21vQ6QwrsoCGMfNC4e4LQPdoULEt4ykz0SRQ==",
+ "dev": true,
+ "requires": {
+ "@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"
+ }
+ },
+ "@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
+ },
+ "@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,
+ "requires": {
+ "@babel/types": "^7.22.5"
+ }
+ },
+ "@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,
+ "requires": {
+ "@babel/types": "^7.22.5"
+ }
+ },
+ "@babel/helper-string-parser": {
+ "version": "7.23.4",
+ "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.23.4.tgz",
+ "integrity": "sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ==",
+ "dev": true
+ },
+ "@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
+ },
+ "@babel/helper-validator-option": {
+ "version": "7.23.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.23.5.tgz",
+ "integrity": "sha512-85ttAOMLsr53VgXkTbkx8oA6YTfT4q7/HzXSLEYmjcSTJPMPQtvq1BD79Byep5xMUYbGRzEpDsjUf3dyp54IKw==",
+ "dev": true
+ },
+ "@babel/helpers": {
+ "version": "7.23.8",
+ "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.23.8.tgz",
+ "integrity": "sha512-KDqYz4PiOWvDFrdHLPhKtCThtIcKVy6avWD2oG4GEvyQ+XDZwHD4YQd+H2vNMnq2rkdxsDkU82T+Vk8U/WXHRQ==",
+ "dev": true,
+ "requires": {
+ "@babel/template": "^7.22.15",
+ "@babel/traverse": "^7.23.7",
+ "@babel/types": "^7.23.6"
+ }
+ },
+ "@babel/highlight": {
+ "version": "7.23.4",
+ "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.23.4.tgz",
+ "integrity": "sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-validator-identifier": "^7.22.20",
+ "chalk": "^2.4.2",
+ "js-tokens": "^4.0.0"
+ }
+ },
+ "@babel/parser": {
+ "version": "7.23.6",
+ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.6.tgz",
+ "integrity": "sha512-Z2uID7YJ7oNvAI20O9X0bblw7Qqs8Q2hFy0R9tAfnfLkp5MW0UH9eUvnDSnFwKZ0AvgS1ucqR4KzvVHgnke1VQ==",
+ "dev": true
+ },
+ "@babel/plugin-transform-react-jsx-self": {
+ "version": "7.23.3",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.23.3.tgz",
+ "integrity": "sha512-qXRvbeKDSfwnlJnanVRp0SfuWE5DQhwQr5xtLBzp56Wabyo+4CMosF6Kfp+eOD/4FYpql64XVJ2W0pVLlJZxOQ==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.22.5"
+ }
+ },
+ "@babel/plugin-transform-react-jsx-source": {
+ "version": "7.23.3",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.23.3.tgz",
+ "integrity": "sha512-91RS0MDnAWDNvGC6Wio5XYkyWI39FMFO+JK9+4AlgaTH+yWwVTsw7/sn6LK0lH7c5F+TFkpv/3LfCJ1Ydwof/g==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.22.5"
+ }
+ },
+ "@babel/runtime": {
+ "version": "7.23.8",
+ "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.23.8.tgz",
+ "integrity": "sha512-Y7KbAP984rn1VGMbGqKmBLio9V7y5Je9GvU4rQPCPinCyNfUcToxIXl06d59URp/F3LwinvODxab5N/G6qggkw==",
+ "requires": {
+ "regenerator-runtime": "^0.14.0"
+ }
+ },
+ "@babel/template": {
+ "version": "7.22.15",
+ "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz",
+ "integrity": "sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==",
+ "dev": true,
+ "requires": {
+ "@babel/code-frame": "^7.22.13",
+ "@babel/parser": "^7.22.15",
+ "@babel/types": "^7.22.15"
+ }
+ },
+ "@babel/traverse": {
+ "version": "7.23.7",
+ "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.7.tgz",
+ "integrity": "sha512-tY3mM8rH9jM0YHFGyfC0/xf+SB5eKUu7HPj7/k3fpi9dAlsMc5YbQvDi0Sh2QTPXqMhyaAtzAr807TIyfQrmyg==",
+ "dev": true,
+ "requires": {
+ "@babel/code-frame": "^7.23.5",
+ "@babel/generator": "^7.23.6",
+ "@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.6",
+ "@babel/types": "^7.23.6",
+ "debug": "^4.3.1",
+ "globals": "^11.1.0"
+ }
+ },
+ "@babel/types": {
+ "version": "7.23.6",
+ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.6.tgz",
+ "integrity": "sha512-+uarb83brBzPKN38NX1MkB6vb6+mwvR6amUulqAE7ccQw1pEl+bCia9TbdG1lsnFP7lZySvUn37CHyXQdfTwzg==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-string-parser": "^7.23.4",
+ "@babel/helper-validator-identifier": "^7.22.20",
+ "to-fast-properties": "^2.0.0"
+ }
+ },
+ "@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=="
+ },
+ "@esbuild/android-arm": {
+ "version": "0.18.11",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.11.tgz",
+ "integrity": "sha512-q4qlUf5ucwbUJZXF5tEQ8LF7y0Nk4P58hOsGk3ucY0oCwgQqAnqXVbUuahCddVHfrxmpyewRpiTHwVHIETYu7Q==",
+ "dev": true,
+ "optional": true
+ },
+ "@esbuild/android-arm64": {
+ "version": "0.18.11",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.18.11.tgz",
+ "integrity": "sha512-snieiq75Z1z5LJX9cduSAjUr7vEI1OdlzFPMw0HH5YI7qQHDd3qs+WZoMrWYDsfRJSq36lIA6mfZBkvL46KoIw==",
+ "dev": true,
+ "optional": true
+ },
+ "@esbuild/android-x64": {
+ "version": "0.18.11",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.18.11.tgz",
+ "integrity": "sha512-iPuoxQEV34+hTF6FT7om+Qwziv1U519lEOvekXO9zaMMlT9+XneAhKL32DW3H7okrCOBQ44BMihE8dclbZtTuw==",
+ "dev": true,
+ "optional": true
+ },
+ "@esbuild/darwin-arm64": {
+ "version": "0.18.11",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.18.11.tgz",
+ "integrity": "sha512-Gm0QkI3k402OpfMKyQEEMG0RuW2LQsSmI6OeO4El2ojJMoF5NLYb3qMIjvbG/lbMeLOGiW6ooU8xqc+S0fgz2w==",
+ "dev": true,
+ "optional": true
+ },
+ "@esbuild/darwin-x64": {
+ "version": "0.18.11",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.18.11.tgz",
+ "integrity": "sha512-N15Vzy0YNHu6cfyDOjiyfJlRJCB/ngKOAvoBf1qybG3eOq0SL2Lutzz9N7DYUbb7Q23XtHPn6lMDF6uWbGv9Fw==",
+ "dev": true,
+ "optional": true
+ },
+ "@esbuild/freebsd-arm64": {
+ "version": "0.18.11",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.11.tgz",
+ "integrity": "sha512-atEyuq6a3omEY5qAh5jIORWk8MzFnCpSTUruBgeyN9jZq1K/QI9uke0ATi3MHu4L8c59CnIi4+1jDKMuqmR71A==",
+ "dev": true,
+ "optional": true
+ },
+ "@esbuild/freebsd-x64": {
+ "version": "0.18.11",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.18.11.tgz",
+ "integrity": "sha512-XtuPrEfBj/YYYnAAB7KcorzzpGTvOr/dTtXPGesRfmflqhA4LMF0Gh/n5+a9JBzPuJ+CGk17CA++Hmr1F/gI0Q==",
+ "dev": true,
+ "optional": true
+ },
+ "@esbuild/linux-arm": {
+ "version": "0.18.11",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.18.11.tgz",
+ "integrity": "sha512-Idipz+Taso/toi2ETugShXjQ3S59b6m62KmLHkJlSq/cBejixmIydqrtM2XTvNCywFl3VC7SreSf6NV0i6sRyg==",
+ "dev": true,
+ "optional": true
+ },
+ "@esbuild/linux-arm64": {
+ "version": "0.18.11",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.18.11.tgz",
+ "integrity": "sha512-c6Vh2WS9VFKxKZ2TvJdA7gdy0n6eSy+yunBvv4aqNCEhSWVor1TU43wNRp2YLO9Vng2G+W94aRz+ILDSwAiYog==",
+ "dev": true,
+ "optional": true
+ },
+ "@esbuild/linux-ia32": {
+ "version": "0.18.11",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.18.11.tgz",
+ "integrity": "sha512-S3hkIF6KUqRh9n1Q0dSyYcWmcVa9Cg+mSoZEfFuzoYXXsk6196qndrM+ZiHNwpZKi3XOXpShZZ+9dfN5ykqjjw==",
+ "dev": true,
+ "optional": true
+ },
+ "@esbuild/linux-loong64": {
+ "version": "0.18.11",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.18.11.tgz",
+ "integrity": "sha512-MRESANOoObQINBA+RMZW+Z0TJWpibtE7cPFnahzyQHDCA9X9LOmGh68MVimZlM9J8n5Ia8lU773te6O3ILW8kw==",
+ "dev": true,
+ "optional": true
+ },
+ "@esbuild/linux-mips64el": {
+ "version": "0.18.11",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.18.11.tgz",
+ "integrity": "sha512-qVyPIZrXNMOLYegtD1u8EBccCrBVshxMrn5MkuFc3mEVsw7CCQHaqZ4jm9hbn4gWY95XFnb7i4SsT3eflxZsUg==",
+ "dev": true,
+ "optional": true
+ },
+ "@esbuild/linux-ppc64": {
+ "version": "0.18.11",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.18.11.tgz",
+ "integrity": "sha512-T3yd8vJXfPirZaUOoA9D2ZjxZX4Gr3QuC3GztBJA6PklLotc/7sXTOuuRkhE9W/5JvJP/K9b99ayPNAD+R+4qQ==",
+ "dev": true,
+ "optional": true
+ },
+ "@esbuild/linux-riscv64": {
+ "version": "0.18.11",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.18.11.tgz",
+ "integrity": "sha512-evUoRPWiwuFk++snjH9e2cAjF5VVSTj+Dnf+rkO/Q20tRqv+644279TZlPK8nUGunjPAtQRCj1jQkDAvL6rm2w==",
+ "dev": true,
+ "optional": true
+ },
+ "@esbuild/linux-s390x": {
+ "version": "0.18.11",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.18.11.tgz",
+ "integrity": "sha512-/SlRJ15XR6i93gRWquRxYCfhTeC5PdqEapKoLbX63PLCmAkXZHY2uQm2l9bN0oPHBsOw2IswRZctMYS0MijFcg==",
+ "dev": true,
+ "optional": true
+ },
+ "@esbuild/linux-x64": {
+ "version": "0.18.11",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.18.11.tgz",
+ "integrity": "sha512-xcncej+wF16WEmIwPtCHi0qmx1FweBqgsRtEL1mSHLFR6/mb3GEZfLQnx+pUDfRDEM4DQF8dpXIW7eDOZl1IbA==",
+ "dev": true,
+ "optional": true
+ },
+ "@esbuild/netbsd-x64": {
+ "version": "0.18.11",
+ "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.18.11.tgz",
+ "integrity": "sha512-aSjMHj/F7BuS1CptSXNg6S3M4F3bLp5wfFPIJM+Km2NfIVfFKhdmfHF9frhiCLIGVzDziggqWll0B+9AUbud/Q==",
+ "dev": true,
+ "optional": true
+ },
+ "@esbuild/openbsd-x64": {
+ "version": "0.18.11",
+ "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.18.11.tgz",
+ "integrity": "sha512-tNBq+6XIBZtht0xJGv7IBB5XaSyvYPCm1PxJ33zLQONdZoLVM0bgGqUrXnJyiEguD9LU4AHiu+GCXy/Hm9LsdQ==",
+ "dev": true,
+ "optional": true
+ },
+ "@esbuild/sunos-x64": {
+ "version": "0.18.11",
+ "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.18.11.tgz",
+ "integrity": "sha512-kxfbDOrH4dHuAAOhr7D7EqaYf+W45LsAOOhAet99EyuxxQmjbk8M9N4ezHcEiCYPaiW8Dj3K26Z2V17Gt6p3ng==",
+ "dev": true,
+ "optional": true
+ },
+ "@esbuild/win32-arm64": {
+ "version": "0.18.11",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.18.11.tgz",
+ "integrity": "sha512-Sh0dDRyk1Xi348idbal7lZyfSkjhJsdFeuC13zqdipsvMetlGiFQNdO+Yfp6f6B4FbyQm7qsk16yaZk25LChzg==",
+ "dev": true,
+ "optional": true
+ },
+ "@esbuild/win32-ia32": {
+ "version": "0.18.11",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.18.11.tgz",
+ "integrity": "sha512-o9JUIKF1j0rqJTFbIoF4bXj6rvrTZYOrfRcGyL0Vm5uJ/j5CkBD/51tpdxe9lXEDouhRgdr/BYzUrDOvrWwJpg==",
+ "dev": true,
+ "optional": true
+ },
+ "@esbuild/win32-x64": {
+ "version": "0.18.11",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.18.11.tgz",
+ "integrity": "sha512-rQI4cjLHd2hGsM1LqgDI7oOCYbQ6IBOVsX9ejuRMSze0GqXUG2ekwiKkiBU1pRGSeCqFFHxTrcEydB2Hyoz9CA==",
+ "dev": true,
+ "optional": true
+ },
+ "@floating-ui/core": {
+ "version": "1.5.3",
+ "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.5.3.tgz",
+ "integrity": "sha512-O0WKDOo0yhJuugCx6trZQj5jVJ9yR0ystG2JaNAemYUWce+pmM6WUEFIibnWyEJKdrDxhm75NoSRME35FNaM/Q==",
+ "requires": {
+ "@floating-ui/utils": "^0.2.0"
+ }
+ },
+ "@floating-ui/devtools": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/@floating-ui/devtools/-/devtools-0.2.1.tgz",
+ "integrity": "sha512-8PHJLbD6VhBh+LJ1uty/Bz30qs02NXCE5u8WpOhSewlYXUWl03GNXknr9AS2yaAWJEQaY27x7eByJs44gODBcw==",
+ "requires": {}
+ },
+ "@floating-ui/dom": {
+ "version": "1.5.4",
+ "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.5.4.tgz",
+ "integrity": "sha512-jByEsHIY+eEdCjnTVu+E3ephzTOzkQ8hgUfGwos+bg7NlH33Zc5uO+QHz1mrQUOgIKKDD1RtS201P9NvAfq3XQ==",
+ "requires": {
+ "@floating-ui/core": "^1.5.3",
+ "@floating-ui/utils": "^0.2.0"
+ }
+ },
+ "@floating-ui/utils": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.1.tgz",
+ "integrity": "sha512-9TANp6GPoMtYzQdt54kfAyMmz1+osLlXdg2ENroU7zzrtflTLrrC/lgrIfaSe+Wu0b89GKccT7vxXA0MoAIO+Q=="
+ },
+ "@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==",
+ "requires": {
+ "@fluentui/set-version": "^8.2.14",
+ "tslib": "^2.1.0"
+ }
+ },
+ "@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==",
+ "requires": {
+ "@fluentui/set-version": "^8.2.14",
+ "tslib": "^2.1.0"
+ }
+ },
+ "@fluentui/font-icons-mdl2": {
+ "version": "8.5.31",
+ "resolved": "https://registry.npmjs.org/@fluentui/font-icons-mdl2/-/font-icons-mdl2-8.5.31.tgz",
+ "integrity": "sha512-jioHZ9XUfR9vUT5XnxdCrJ+hoC9TpYim+4YdtlUE/euI8kdW1tDZ5zqlSNk1GLDR34n03R09yWj5gVDCcMJbyQ==",
+ "requires": {
+ "@fluentui/set-version": "^8.2.14",
+ "@fluentui/style-utilities": "^8.10.2",
+ "@fluentui/utilities": "^8.13.24",
+ "tslib": "^2.1.0"
+ }
+ },
+ "@fluentui/foundation-legacy": {
+ "version": "8.2.51",
+ "resolved": "https://registry.npmjs.org/@fluentui/foundation-legacy/-/foundation-legacy-8.2.51.tgz",
+ "integrity": "sha512-z/jrp1imV66/D2MGpN/55LGk/Istymk5tN+XUFHDENDi+9zyb2MgSxFshp774DJIrg3vVlyuS8oo+dBuTM3UbQ==",
+ "requires": {
+ "@fluentui/merge-styles": "^8.5.15",
+ "@fluentui/set-version": "^8.2.14",
+ "@fluentui/style-utilities": "^8.10.2",
+ "@fluentui/utilities": "^8.13.24",
+ "tslib": "^2.1.0"
+ }
+ },
+ "@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==",
+ "requires": {
+ "tslib": "^2.1.0"
+ }
+ },
+ "@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==",
+ "requires": {
+ "@swc/helpers": "^0.5.1"
+ }
+ },
+ "@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==",
+ "requires": {
+ "@fluentui/set-version": "^8.2.14",
+ "tslib": "^2.1.0"
+ }
+ },
+ "@fluentui/priority-overflow": {
+ "version": "9.1.11",
+ "resolved": "https://registry.npmjs.org/@fluentui/priority-overflow/-/priority-overflow-9.1.11.tgz",
+ "integrity": "sha512-sdrpavvKX2kepQ1d6IaI3ObLq5SAQBPRHPGx2+wiMWL7cEx9vGGM0fmeicl3soqqmM5uwCmWnZk9QZv9XOY98w==",
+ "requires": {
+ "@swc/helpers": "^0.5.1"
+ }
+ },
+ "@fluentui/react": {
+ "version": "8.114.4",
+ "resolved": "https://registry.npmjs.org/@fluentui/react/-/react-8.114.4.tgz",
+ "integrity": "sha512-dVpfFSpWUxdyqWlCVSXX5d34S760h4MaQjGR2/TPavtcJRRpJDHbBN2Hn7s4riA6YX5N7bTdN372UvIVbBbzuw==",
+ "requires": {
+ "@fluentui/date-time-utilities": "^8.5.16",
+ "@fluentui/font-icons-mdl2": "^8.5.31",
+ "@fluentui/foundation-legacy": "^8.2.51",
+ "@fluentui/merge-styles": "^8.5.15",
+ "@fluentui/react-focus": "^8.8.38",
+ "@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.2",
+ "@fluentui/theme": "^2.6.41",
+ "@fluentui/utilities": "^8.13.24",
+ "@microsoft/load-themed-styles": "^1.10.26",
+ "tslib": "^2.1.0"
+ }
+ },
+ "@fluentui/react-accordion": {
+ "version": "9.3.38",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-accordion/-/react-accordion-9.3.38.tgz",
+ "integrity": "sha512-BB8d9+Jr0v4SW58OJTIyvsxhA/iOBbvIkQZlVHKqt4tL8dHOIFPrApw5WqQqaSYJsEwt4HxmlNU4Dv8qRughbg==",
+ "requires": {
+ "@fluentui/react-aria": "^9.7.3",
+ "@fluentui/react-context-selector": "^9.1.49",
+ "@fluentui/react-icons": "^2.0.224",
+ "@fluentui/react-jsx-runtime": "^9.0.27",
+ "@fluentui/react-shared-contexts": "^9.14.0",
+ "@fluentui/react-tabster": "^9.17.3",
+ "@fluentui/react-theme": "^9.1.16",
+ "@fluentui/react-utilities": "^9.16.1",
+ "@griffel/react": "^1.5.14",
+ "@swc/helpers": "^0.5.1"
+ }
+ },
+ "@fluentui/react-alert": {
+ "version": "9.0.0-beta.104",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-alert/-/react-alert-9.0.0-beta.104.tgz",
+ "integrity": "sha512-Z8BGSyzEKok5wlJF2cUc8GUj2q+c1D+119YF0WtHLiieh7pwOHjBcDJOHqnaVnQNbhetIA3NUht2z0e1wgOK5w==",
+ "requires": {
+ "@fluentui/react-avatar": "^9.6.9",
+ "@fluentui/react-button": "^9.3.65",
+ "@fluentui/react-icons": "^2.0.224",
+ "@fluentui/react-jsx-runtime": "^9.0.27",
+ "@fluentui/react-tabster": "^9.17.3",
+ "@fluentui/react-theme": "^9.1.16",
+ "@fluentui/react-utilities": "^9.16.1",
+ "@griffel/react": "^1.5.14",
+ "@swc/helpers": "^0.5.1"
+ }
+ },
+ "@fluentui/react-aria": {
+ "version": "9.7.3",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-aria/-/react-aria-9.7.3.tgz",
+ "integrity": "sha512-YwyPNEcBDCdY6YzhrIrtlSrLs2Le7X1jLq9em8OnqHeiO22dBmg5xlBJoAMwJ8awCpI9xhu1PhU/2VJY4YqNuA==",
+ "requires": {
+ "@fluentui/keyboard-keys": "^9.0.7",
+ "@fluentui/react-shared-contexts": "^9.14.0",
+ "@fluentui/react-tabster": "^9.17.3",
+ "@fluentui/react-utilities": "^9.16.1",
+ "@swc/helpers": "^0.5.1"
+ }
+ },
+ "@fluentui/react-avatar": {
+ "version": "9.6.9",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-avatar/-/react-avatar-9.6.9.tgz",
+ "integrity": "sha512-3aZeUhGOg+UlHsp2x//G4VKRWKclcsZvX6L9UVnHsA/nQqRw7C5Bfo9iFNsEeJ3R5W5mFA6LyEFWedJ7QdAmdQ==",
+ "requires": {
+ "@fluentui/react-badge": "^9.2.22",
+ "@fluentui/react-context-selector": "^9.1.49",
+ "@fluentui/react-icons": "^2.0.224",
+ "@fluentui/react-jsx-runtime": "^9.0.27",
+ "@fluentui/react-popover": "^9.8.33",
+ "@fluentui/react-shared-contexts": "^9.14.0",
+ "@fluentui/react-tabster": "^9.17.3",
+ "@fluentui/react-theme": "^9.1.16",
+ "@fluentui/react-tooltip": "^9.4.11",
+ "@fluentui/react-utilities": "^9.16.1",
+ "@griffel/react": "^1.5.14",
+ "@swc/helpers": "^0.5.1"
+ }
+ },
+ "@fluentui/react-badge": {
+ "version": "9.2.22",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-badge/-/react-badge-9.2.22.tgz",
+ "integrity": "sha512-zzimP5mZiiCOm8expUTzD6yvvKbnKq22PK/L6+oNpifrvQnDwJF/0nwXQVjA3+icNoYTaHe/q0fFivpXV+Js6g==",
+ "requires": {
+ "@fluentui/react-icons": "^2.0.224",
+ "@fluentui/react-jsx-runtime": "^9.0.27",
+ "@fluentui/react-shared-contexts": "^9.14.0",
+ "@fluentui/react-theme": "^9.1.16",
+ "@fluentui/react-utilities": "^9.16.1",
+ "@griffel/react": "^1.5.14",
+ "@swc/helpers": "^0.5.1"
+ }
+ },
+ "@fluentui/react-breadcrumb": {
+ "version": "9.0.11",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-breadcrumb/-/react-breadcrumb-9.0.11.tgz",
+ "integrity": "sha512-L+AQqZz1gqkScD8IW1CjZWGNrDaHDc/gSv+PrvgSZeGDPibGj6TnLygJ7BKM+rQ+Hc2SbCogKbERpQZCbrSFvA==",
+ "requires": {
+ "@fluentui/react-aria": "^9.7.3",
+ "@fluentui/react-button": "^9.3.65",
+ "@fluentui/react-icons": "^2.0.224",
+ "@fluentui/react-jsx-runtime": "^9.0.27",
+ "@fluentui/react-link": "^9.2.7",
+ "@fluentui/react-shared-contexts": "^9.14.0",
+ "@fluentui/react-tabster": "^9.17.3",
+ "@fluentui/react-theme": "^9.1.16",
+ "@fluentui/react-utilities": "^9.16.1",
+ "@griffel/react": "^1.5.14",
+ "@swc/helpers": "^0.5.1"
+ }
+ },
+ "@fluentui/react-button": {
+ "version": "9.3.65",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-button/-/react-button-9.3.65.tgz",
+ "integrity": "sha512-3VOt29AugkfR7VMnkKON449E7Sn/nvc6BBT4kJDGKQY+Nm5d2p9e4HmHp1UaM9zRPt47lagTY2WFJNrKKSe/BA==",
+ "requires": {
+ "@fluentui/keyboard-keys": "^9.0.7",
+ "@fluentui/react-aria": "^9.7.3",
+ "@fluentui/react-icons": "^2.0.224",
+ "@fluentui/react-jsx-runtime": "^9.0.27",
+ "@fluentui/react-shared-contexts": "^9.14.0",
+ "@fluentui/react-tabster": "^9.17.3",
+ "@fluentui/react-theme": "^9.1.16",
+ "@fluentui/react-utilities": "^9.16.1",
+ "@griffel/react": "^1.5.14",
+ "@swc/helpers": "^0.5.1"
+ }
+ },
+ "@fluentui/react-card": {
+ "version": "9.0.64",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-card/-/react-card-9.0.64.tgz",
+ "integrity": "sha512-TB/Zk+tLDUPNyAd2y8BvN0T2nroimtBOpB5GTK72E5sWPk0kaKIHwBEfXxNFGdGXcw0TAmVNqYi4ks37vh0Rgg==",
+ "requires": {
+ "@fluentui/keyboard-keys": "^9.0.7",
+ "@fluentui/react-jsx-runtime": "^9.0.27",
+ "@fluentui/react-tabster": "^9.17.3",
+ "@fluentui/react-theme": "^9.1.16",
+ "@fluentui/react-utilities": "^9.16.1",
+ "@griffel/react": "^1.5.14",
+ "@swc/helpers": "^0.5.1"
+ }
+ },
+ "@fluentui/react-checkbox": {
+ "version": "9.2.8",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-checkbox/-/react-checkbox-9.2.8.tgz",
+ "integrity": "sha512-L4aWzeZdi98d0ZhgNPtxghfhasQv1qlxIRMaPxtwvk5TN6i9YmRF8vf5Pmf0PESjT+zp3VPcisHcIfcqG26SmQ==",
+ "requires": {
+ "@fluentui/react-field": "^9.1.50",
+ "@fluentui/react-icons": "^2.0.224",
+ "@fluentui/react-jsx-runtime": "^9.0.27",
+ "@fluentui/react-label": "^9.1.58",
+ "@fluentui/react-shared-contexts": "^9.14.0",
+ "@fluentui/react-tabster": "^9.17.3",
+ "@fluentui/react-theme": "^9.1.16",
+ "@fluentui/react-utilities": "^9.16.1",
+ "@griffel/react": "^1.5.14",
+ "@swc/helpers": "^0.5.1"
+ }
+ },
+ "@fluentui/react-combobox": {
+ "version": "9.7.0",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-combobox/-/react-combobox-9.7.0.tgz",
+ "integrity": "sha512-YmTdg04rvsg2+Dkw3ob+YLnS9rm3TLVMMNYTH0T64/FM3qirHntIXGbhMZXP5Cdo14gzQwr/e78NjBRKfYO4Wg==",
+ "requires": {
+ "@fluentui/keyboard-keys": "^9.0.7",
+ "@fluentui/react-context-selector": "^9.1.49",
+ "@fluentui/react-field": "^9.1.50",
+ "@fluentui/react-icons": "^2.0.224",
+ "@fluentui/react-jsx-runtime": "^9.0.27",
+ "@fluentui/react-portal": "^9.4.10",
+ "@fluentui/react-positioning": "^9.12.4",
+ "@fluentui/react-shared-contexts": "^9.14.0",
+ "@fluentui/react-tabster": "^9.17.3",
+ "@fluentui/react-theme": "^9.1.16",
+ "@fluentui/react-utilities": "^9.16.1",
+ "@griffel/react": "^1.5.14",
+ "@swc/helpers": "^0.5.1"
+ }
+ },
+ "@fluentui/react-components": {
+ "version": "9.45.0",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-components/-/react-components-9.45.0.tgz",
+ "integrity": "sha512-Y+Laj1dvRcCp/nWT0DExRXoh7oKTX458g6oltrGjhIHikq4D6/kssK5tfhCyknPLwIlVSYi5J+G6L3NfvI8a8w==",
+ "requires": {
+ "@fluentui/react-accordion": "^9.3.38",
+ "@fluentui/react-alert": "9.0.0-beta.104",
+ "@fluentui/react-avatar": "^9.6.9",
+ "@fluentui/react-badge": "^9.2.22",
+ "@fluentui/react-breadcrumb": "^9.0.11",
+ "@fluentui/react-button": "^9.3.65",
+ "@fluentui/react-card": "^9.0.64",
+ "@fluentui/react-checkbox": "^9.2.8",
+ "@fluentui/react-combobox": "^9.7.0",
+ "@fluentui/react-dialog": "^9.9.7",
+ "@fluentui/react-divider": "^9.2.58",
+ "@fluentui/react-drawer": "^9.1.1",
+ "@fluentui/react-field": "^9.1.50",
+ "@fluentui/react-image": "^9.1.55",
+ "@fluentui/react-infobutton": "9.0.0-beta.88",
+ "@fluentui/react-infolabel": "^9.0.16",
+ "@fluentui/react-input": "^9.4.60",
+ "@fluentui/react-label": "^9.1.58",
+ "@fluentui/react-link": "^9.2.7",
+ "@fluentui/react-menu": "^9.12.45",
+ "@fluentui/react-message-bar": "^9.0.16",
+ "@fluentui/react-overflow": "^9.1.8",
+ "@fluentui/react-persona": "^9.2.68",
+ "@fluentui/react-popover": "^9.8.33",
+ "@fluentui/react-portal": "^9.4.10",
+ "@fluentui/react-positioning": "^9.12.4",
+ "@fluentui/react-progress": "^9.1.60",
+ "@fluentui/react-provider": "^9.13.8",
+ "@fluentui/react-radio": "^9.2.3",
+ "@fluentui/react-select": "^9.1.60",
+ "@fluentui/react-shared-contexts": "^9.14.0",
+ "@fluentui/react-skeleton": "^9.0.48",
+ "@fluentui/react-slider": "^9.1.65",
+ "@fluentui/react-spinbutton": "^9.2.60",
+ "@fluentui/react-spinner": "^9.3.38",
+ "@fluentui/react-switch": "^9.1.65",
+ "@fluentui/react-table": "^9.11.5",
+ "@fluentui/react-tabs": "^9.4.6",
+ "@fluentui/react-tabster": "^9.17.3",
+ "@fluentui/react-tags": "^9.0.22",
+ "@fluentui/react-text": "^9.4.7",
+ "@fluentui/react-textarea": "^9.3.60",
+ "@fluentui/react-theme": "^9.1.16",
+ "@fluentui/react-toast": "^9.3.27",
+ "@fluentui/react-toolbar": "^9.1.66",
+ "@fluentui/react-tooltip": "^9.4.11",
+ "@fluentui/react-tree": "^9.4.25",
+ "@fluentui/react-utilities": "^9.16.1",
+ "@fluentui/react-virtualizer": "9.0.0-alpha.66",
+ "@griffel/react": "^1.5.14",
+ "@swc/helpers": "^0.5.1"
+ }
+ },
+ "@fluentui/react-context-selector": {
+ "version": "9.1.49",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-context-selector/-/react-context-selector-9.1.49.tgz",
+ "integrity": "sha512-u4wRNfnyfuZDalVEESBPFQ0Ue4yYu+ozkPQvuEV6kriQGnAQQyyVbIidOCuP7Sja0nBwgM8eAzK0uX/slmmj3Q==",
+ "requires": {
+ "@fluentui/react-utilities": "^9.16.1",
+ "@swc/helpers": "^0.5.1"
+ }
+ },
+ "@fluentui/react-dialog": {
+ "version": "9.9.7",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-dialog/-/react-dialog-9.9.7.tgz",
+ "integrity": "sha512-5/6MeaHOYpx8Vt0auMJGLCjn6O1IYtl6IhwdwRNXL6AS1o4F24IKXdWZPtiHWuvzbuZAQd3+5nRDUE5KC9We6A==",
+ "requires": {
+ "@fluentui/keyboard-keys": "^9.0.7",
+ "@fluentui/react-aria": "^9.7.3",
+ "@fluentui/react-context-selector": "^9.1.49",
+ "@fluentui/react-icons": "^2.0.224",
+ "@fluentui/react-jsx-runtime": "^9.0.27",
+ "@fluentui/react-portal": "^9.4.10",
+ "@fluentui/react-shared-contexts": "^9.14.0",
+ "@fluentui/react-tabster": "^9.17.3",
+ "@fluentui/react-theme": "^9.1.16",
+ "@fluentui/react-utilities": "^9.16.1",
+ "@griffel/react": "^1.5.14",
+ "@swc/helpers": "^0.5.1",
+ "react-transition-group": "^4.4.1"
+ }
+ },
+ "@fluentui/react-divider": {
+ "version": "9.2.58",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-divider/-/react-divider-9.2.58.tgz",
+ "integrity": "sha512-y1ECy1zM4imKhpyOyUGugB+J30tfySO5hhrsIcpaiUQxRjE4IhZf2ZG6EqAQYLinJ+hV06yLZoazekljlvk6yw==",
+ "requires": {
+ "@fluentui/react-jsx-runtime": "^9.0.27",
+ "@fluentui/react-shared-contexts": "^9.14.0",
+ "@fluentui/react-theme": "^9.1.16",
+ "@fluentui/react-utilities": "^9.16.1",
+ "@griffel/react": "^1.5.14",
+ "@swc/helpers": "^0.5.1"
+ }
+ },
+ "@fluentui/react-drawer": {
+ "version": "9.1.1",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-drawer/-/react-drawer-9.1.1.tgz",
+ "integrity": "sha512-3zvbbeaLLJZa4MXRpW8Ta4DFZ5457Tq9/4a0CqsIW/+8EuwtJwO+FB5a0DS6j0q6kN4mjkWF19OvzMkJsSTRVw==",
+ "requires": {
+ "@fluentui/react-dialog": "^9.9.7",
+ "@fluentui/react-jsx-runtime": "^9.0.27",
+ "@fluentui/react-motion-preview": "^0.5.10",
+ "@fluentui/react-shared-contexts": "^9.14.0",
+ "@fluentui/react-tabster": "^9.17.3",
+ "@fluentui/react-theme": "^9.1.16",
+ "@fluentui/react-utilities": "^9.16.1",
+ "@griffel/react": "^1.5.14",
+ "@swc/helpers": "^0.5.1"
+ }
+ },
+ "@fluentui/react-field": {
+ "version": "9.1.50",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-field/-/react-field-9.1.50.tgz",
+ "integrity": "sha512-2mbx7YReMWvrgi3set9KepLLgMyNJ7StLu/HiHMM3jkcgPt3mGfwoJEsEKt+xd8eUAo4b82F7t+tHI4f9yzJaQ==",
+ "requires": {
+ "@fluentui/react-context-selector": "^9.1.49",
+ "@fluentui/react-icons": "^2.0.224",
+ "@fluentui/react-jsx-runtime": "^9.0.27",
+ "@fluentui/react-label": "^9.1.58",
+ "@fluentui/react-theme": "^9.1.16",
+ "@fluentui/react-utilities": "^9.16.1",
+ "@griffel/react": "^1.5.14",
+ "@swc/helpers": "^0.5.1"
+ }
+ },
+ "@fluentui/react-focus": {
+ "version": "8.8.38",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-focus/-/react-focus-8.8.38.tgz",
+ "integrity": "sha512-vnsaY7hJSPIJBxm5Pj0FrcFDumV6kKgFVpsKsEKJzb1D88rDDLcmvz9jWUx68a3ru6idEbZYmyePGT1IiRsAug==",
+ "requires": {
+ "@fluentui/keyboard-key": "^0.4.14",
+ "@fluentui/merge-styles": "^8.5.15",
+ "@fluentui/set-version": "^8.2.14",
+ "@fluentui/style-utilities": "^8.10.2",
+ "@fluentui/utilities": "^8.13.24",
+ "tslib": "^2.1.0"
+ }
+ },
+ "@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==",
+ "requires": {
+ "@fluentui/react-window-provider": "^2.2.18",
+ "@fluentui/set-version": "^8.2.14",
+ "@fluentui/utilities": "^8.13.24",
+ "tslib": "^2.1.0"
+ }
+ },
+ "@fluentui/react-icons": {
+ "version": "2.0.225",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-icons/-/react-icons-2.0.225.tgz",
+ "integrity": "sha512-L9phN3bAMlZCa5+/ObGjIO+5GI8M50ym766sraSq92jaJwgAXrCJDLWuDGWZRGrC63DcagtR2culptj3q7gMMg==",
+ "requires": {
+ "@griffel/react": "^1.0.0",
+ "tslib": "^2.1.0"
+ }
+ },
+ "@fluentui/react-image": {
+ "version": "9.1.55",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-image/-/react-image-9.1.55.tgz",
+ "integrity": "sha512-hYP61OWLuGSJNPOGJXtphbiDESfLB+/vsODKQsJhrDRJ2CSNMAfNznPHucqGRRN6AWQOI/BynJDS5F22Y//7CQ==",
+ "requires": {
+ "@fluentui/react-jsx-runtime": "^9.0.27",
+ "@fluentui/react-shared-contexts": "^9.14.0",
+ "@fluentui/react-theme": "^9.1.16",
+ "@fluentui/react-utilities": "^9.16.1",
+ "@griffel/react": "^1.5.14",
+ "@swc/helpers": "^0.5.1"
+ }
+ },
+ "@fluentui/react-infobutton": {
+ "version": "9.0.0-beta.88",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-infobutton/-/react-infobutton-9.0.0-beta.88.tgz",
+ "integrity": "sha512-NVZyfrLtoFNu7cGkp2ORWsxJiCk1JgN4CVBDj03QSIh14EsPMwphYgDwfQ8TZOF2Nub0DGtC7/tF8IUlb/aP6g==",
+ "requires": {
+ "@fluentui/react-icons": "^2.0.224",
+ "@fluentui/react-jsx-runtime": "^9.0.27",
+ "@fluentui/react-label": "^9.1.58",
+ "@fluentui/react-popover": "^9.8.33",
+ "@fluentui/react-tabster": "^9.17.3",
+ "@fluentui/react-theme": "^9.1.16",
+ "@fluentui/react-utilities": "^9.16.1",
+ "@griffel/react": "^1.5.14",
+ "@swc/helpers": "^0.5.1"
+ }
+ },
+ "@fluentui/react-infolabel": {
+ "version": "9.0.16",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-infolabel/-/react-infolabel-9.0.16.tgz",
+ "integrity": "sha512-UCY+2vB4vOn0LfVhbgkyNG0EiuKIe0PdxEAtLU2PqosHLkaLKnYDKJdiIS/oaFmyNtGHmMxRkigvZpZ7h74f9g==",
+ "requires": {
+ "@fluentui/react-icons": "^2.0.224",
+ "@fluentui/react-jsx-runtime": "^9.0.27",
+ "@fluentui/react-label": "^9.1.58",
+ "@fluentui/react-popover": "^9.8.33",
+ "@fluentui/react-tabster": "^9.17.3",
+ "@fluentui/react-theme": "^9.1.16",
+ "@fluentui/react-utilities": "^9.16.1",
+ "@griffel/react": "^1.5.14",
+ "@swc/helpers": "^0.5.1"
+ }
+ },
+ "@fluentui/react-input": {
+ "version": "9.4.60",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-input/-/react-input-9.4.60.tgz",
+ "integrity": "sha512-kuk24K0X0gckTCssXoiWvZsTFVpZJv+WPl2fkjxeffzmFfBZtJUFQkXeC4/hcAg+aScjZnEtqjHjwDEbjZqkeA==",
+ "requires": {
+ "@fluentui/react-field": "^9.1.50",
+ "@fluentui/react-jsx-runtime": "^9.0.27",
+ "@fluentui/react-shared-contexts": "^9.14.0",
+ "@fluentui/react-theme": "^9.1.16",
+ "@fluentui/react-utilities": "^9.16.1",
+ "@griffel/react": "^1.5.14",
+ "@swc/helpers": "^0.5.1"
+ }
+ },
+ "@fluentui/react-jsx-runtime": {
+ "version": "9.0.27",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-jsx-runtime/-/react-jsx-runtime-9.0.27.tgz",
+ "integrity": "sha512-9wxsWxVI7RLXsdK+7lzp7TK0FJKnrrj+Igxn0prqAvXdBRiFcuycoCJaHzC4Ka+Hsiol8NQg6xaIR59a28lmyQ==",
+ "requires": {
+ "@fluentui/react-utilities": "^9.16.1",
+ "@swc/helpers": "^0.5.1",
+ "react-is": "^17.0.2"
+ }
+ },
+ "@fluentui/react-label": {
+ "version": "9.1.58",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-label/-/react-label-9.1.58.tgz",
+ "integrity": "sha512-0ouSMop4vpXJzMvAyfmIr3TgDM/W1k+GFm8ZPD5fDQCopSJ+h3kvUZg5pqaXpBwamvZ16+qRARfTNITp2U7Rjw==",
+ "requires": {
+ "@fluentui/react-jsx-runtime": "^9.0.27",
+ "@fluentui/react-shared-contexts": "^9.14.0",
+ "@fluentui/react-theme": "^9.1.16",
+ "@fluentui/react-utilities": "^9.16.1",
+ "@griffel/react": "^1.5.14",
+ "@swc/helpers": "^0.5.1"
+ }
+ },
+ "@fluentui/react-link": {
+ "version": "9.2.7",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-link/-/react-link-9.2.7.tgz",
+ "integrity": "sha512-z4X9dcUc/7FlqDxbGKbOfWubru+QimtzgMtlVxZ30pkC959hfIbFpbBY6Me76UOuFiOZxUPdfyY/73ekhhhVxw==",
+ "requires": {
+ "@fluentui/keyboard-keys": "^9.0.7",
+ "@fluentui/react-jsx-runtime": "^9.0.27",
+ "@fluentui/react-shared-contexts": "^9.14.0",
+ "@fluentui/react-tabster": "^9.17.3",
+ "@fluentui/react-theme": "^9.1.16",
+ "@fluentui/react-utilities": "^9.16.1",
+ "@griffel/react": "^1.5.14",
+ "@swc/helpers": "^0.5.1"
+ }
+ },
+ "@fluentui/react-menu": {
+ "version": "9.12.45",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-menu/-/react-menu-9.12.45.tgz",
+ "integrity": "sha512-qhpmuvAB4DUmmC5lNMakVvZjTdj/GZnH6WctNGZp94iCZLhcnIQcM9l0PvRpUpU1v3irXRyE5QV+x+wXC0awTw==",
+ "requires": {
+ "@fluentui/keyboard-keys": "^9.0.7",
+ "@fluentui/react-aria": "^9.7.3",
+ "@fluentui/react-context-selector": "^9.1.49",
+ "@fluentui/react-icons": "^2.0.224",
+ "@fluentui/react-jsx-runtime": "^9.0.27",
+ "@fluentui/react-portal": "^9.4.10",
+ "@fluentui/react-positioning": "^9.12.4",
+ "@fluentui/react-shared-contexts": "^9.14.0",
+ "@fluentui/react-tabster": "^9.17.3",
+ "@fluentui/react-theme": "^9.1.16",
+ "@fluentui/react-utilities": "^9.16.1",
+ "@griffel/react": "^1.5.14",
+ "@swc/helpers": "^0.5.1"
+ }
+ },
+ "@fluentui/react-message-bar": {
+ "version": "9.0.16",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-message-bar/-/react-message-bar-9.0.16.tgz",
+ "integrity": "sha512-R1VnqcFwu0pM2Yk8rjkN48Lx/n44UFD13BuY8/JeEuU8XQ8hLnEBVtdHjzRPJk+iM5in2ScMMQj4Z0nWyCRM1Q==",
+ "requires": {
+ "@fluentui/react-button": "^9.3.65",
+ "@fluentui/react-icons": "^2.0.224",
+ "@fluentui/react-jsx-runtime": "^9.0.27",
+ "@fluentui/react-shared-contexts": "^9.14.0",
+ "@fluentui/react-theme": "^9.1.16",
+ "@fluentui/react-utilities": "^9.16.1",
+ "@griffel/react": "^1.5.14",
+ "@swc/helpers": "^0.5.1",
+ "react-transition-group": "^4.4.1"
+ }
+ },
+ "@fluentui/react-motion-preview": {
+ "version": "0.5.10",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-motion-preview/-/react-motion-preview-0.5.10.tgz",
+ "integrity": "sha512-6iwF3N4hB6IxCoFVusgA2mp6mrTknwcsVGNYEQw1YF5WgGOMF3M0N1xNpN61/SYziT6HSUaI38NaA7LI3Dp3Sw==",
+ "requires": {
+ "@fluentui/react-jsx-runtime": "^9.0.27",
+ "@fluentui/react-shared-contexts": "^9.14.0",
+ "@fluentui/react-theme": "^9.1.16",
+ "@fluentui/react-utilities": "^9.16.1",
+ "@griffel/react": "^1.5.14",
+ "@swc/helpers": "^0.5.1"
+ }
+ },
+ "@fluentui/react-overflow": {
+ "version": "9.1.8",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-overflow/-/react-overflow-9.1.8.tgz",
+ "integrity": "sha512-W8L68+0bUtfGr72LRx+U05EZLO0E8VMfscDiNKiEjDrOqdBnqNAIDN86825wrN77HH2wvILN07EhPOauqzz8YQ==",
+ "requires": {
+ "@fluentui/priority-overflow": "^9.1.11",
+ "@fluentui/react-context-selector": "^9.1.49",
+ "@fluentui/react-theme": "^9.1.16",
+ "@fluentui/react-utilities": "^9.16.1",
+ "@griffel/react": "^1.5.14",
+ "@swc/helpers": "^0.5.1"
+ }
+ },
+ "@fluentui/react-persona": {
+ "version": "9.2.68",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-persona/-/react-persona-9.2.68.tgz",
+ "integrity": "sha512-CYtDiZ34GGaw7lZ85uHZOuYXzkY21VHN6cUlGY1TJn98+Xz+y7JoVLIG7KZHHp2JzmmjtwjvgnqAdOun5LrWig==",
+ "requires": {
+ "@fluentui/react-avatar": "^9.6.9",
+ "@fluentui/react-badge": "^9.2.22",
+ "@fluentui/react-jsx-runtime": "^9.0.27",
+ "@fluentui/react-shared-contexts": "^9.14.0",
+ "@fluentui/react-theme": "^9.1.16",
+ "@fluentui/react-utilities": "^9.16.1",
+ "@griffel/react": "^1.5.14",
+ "@swc/helpers": "^0.5.1"
+ }
+ },
+ "@fluentui/react-popover": {
+ "version": "9.8.33",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-popover/-/react-popover-9.8.33.tgz",
+ "integrity": "sha512-0yPX6KCdMEGmrvJnQles5iTKN0OZ2vNSPVdkbyEKIUKj5DrNK1cMZEV/7Tgrtn922fx3/74FLMqEpEDTdrvQ/Q==",
+ "requires": {
+ "@fluentui/keyboard-keys": "^9.0.7",
+ "@fluentui/react-aria": "^9.7.3",
+ "@fluentui/react-context-selector": "^9.1.49",
+ "@fluentui/react-jsx-runtime": "^9.0.27",
+ "@fluentui/react-portal": "^9.4.10",
+ "@fluentui/react-positioning": "^9.12.4",
+ "@fluentui/react-shared-contexts": "^9.14.0",
+ "@fluentui/react-tabster": "^9.17.3",
+ "@fluentui/react-theme": "^9.1.16",
+ "@fluentui/react-utilities": "^9.16.1",
+ "@griffel/react": "^1.5.14",
+ "@swc/helpers": "^0.5.1"
+ }
+ },
+ "@fluentui/react-portal": {
+ "version": "9.4.10",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-portal/-/react-portal-9.4.10.tgz",
+ "integrity": "sha512-k8fTRv9wTPSPCuNBFE2HxIhXsVYoG6Azb6Ib2xaDK+nczoW2WbsmNmwBJGEGi8UKjIoQzV+95KsYQ9me+uqKPA==",
+ "requires": {
+ "@fluentui/react-shared-contexts": "^9.14.0",
+ "@fluentui/react-tabster": "^9.17.3",
+ "@fluentui/react-utilities": "^9.16.1",
+ "@griffel/react": "^1.5.14",
+ "@swc/helpers": "^0.5.1",
+ "use-disposable": "^1.0.1"
+ }
+ },
+ "@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==",
+ "requires": {
+ "@swc/helpers": "^0.5.1"
+ }
+ },
+ "@fluentui/react-positioning": {
+ "version": "9.12.4",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-positioning/-/react-positioning-9.12.4.tgz",
+ "integrity": "sha512-qQAjHF/FJFs2TyK0x08t0iFtDQlGNGH0OFC3jrG1xIFEe3nFPoeYeNT3zxOmj+D7bvlcJTIITcoe++YQTnCf4w==",
+ "requires": {
+ "@floating-ui/devtools": "0.2.1",
+ "@floating-ui/dom": "^1.2.0",
+ "@fluentui/react-shared-contexts": "^9.14.0",
+ "@fluentui/react-theme": "^9.1.16",
+ "@fluentui/react-utilities": "^9.16.1",
+ "@griffel/react": "^1.5.14",
+ "@swc/helpers": "^0.5.1"
+ }
+ },
+ "@fluentui/react-progress": {
+ "version": "9.1.60",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-progress/-/react-progress-9.1.60.tgz",
+ "integrity": "sha512-9wC7lWdo3S8rhxKWlIhcYAzsZNw+rL2HvNJTvEvFxXcOG7nJxP/3mGclV/jCCwDoPDnt9BT+40pGK84eD0BNIA==",
+ "requires": {
+ "@fluentui/react-field": "^9.1.50",
+ "@fluentui/react-jsx-runtime": "^9.0.27",
+ "@fluentui/react-shared-contexts": "^9.14.0",
+ "@fluentui/react-theme": "^9.1.16",
+ "@fluentui/react-utilities": "^9.16.1",
+ "@griffel/react": "^1.5.14",
+ "@swc/helpers": "^0.5.1"
+ }
+ },
+ "@fluentui/react-provider": {
+ "version": "9.13.8",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-provider/-/react-provider-9.13.8.tgz",
+ "integrity": "sha512-FCvDMjs/BNAcqJuHU+kN/lqLB2RDQ/LQo29ltfLKFlTR1nTUNJvPMOVhjj6eEt+t81628LOYhbbaXOj9rYtfGg==",
+ "requires": {
+ "@fluentui/react-icons": "^2.0.224",
+ "@fluentui/react-jsx-runtime": "^9.0.27",
+ "@fluentui/react-shared-contexts": "^9.14.0",
+ "@fluentui/react-tabster": "^9.17.3",
+ "@fluentui/react-theme": "^9.1.16",
+ "@fluentui/react-utilities": "^9.16.1",
+ "@griffel/core": "^1.14.1",
+ "@griffel/react": "^1.5.14",
+ "@swc/helpers": "^0.5.1"
+ }
+ },
+ "@fluentui/react-radio": {
+ "version": "9.2.3",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-radio/-/react-radio-9.2.3.tgz",
+ "integrity": "sha512-8eKeUL0ZNr792Q6NGWPp7dpOV2IFcjAQ2oWR2/bruQVu8LMzYYKe2o6pQWdCag6UGPZuszkms9Xl7zPdDQBUdA==",
+ "requires": {
+ "@fluentui/react-field": "^9.1.50",
+ "@fluentui/react-jsx-runtime": "^9.0.27",
+ "@fluentui/react-label": "^9.1.58",
+ "@fluentui/react-shared-contexts": "^9.14.0",
+ "@fluentui/react-tabster": "^9.17.3",
+ "@fluentui/react-theme": "^9.1.16",
+ "@fluentui/react-utilities": "^9.16.1",
+ "@griffel/react": "^1.5.14",
+ "@swc/helpers": "^0.5.1"
+ }
+ },
+ "@fluentui/react-select": {
+ "version": "9.1.60",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-select/-/react-select-9.1.60.tgz",
+ "integrity": "sha512-4HfRRTlGStOgtO00RY6jmOwz6MXnoa9gtjkV7StLmJZ2U5NTjVUrnp2dP1Vjb6hO13xaihWGEYyYKnsQ3R7kIw==",
+ "requires": {
+ "@fluentui/react-field": "^9.1.50",
+ "@fluentui/react-icons": "^2.0.224",
+ "@fluentui/react-jsx-runtime": "^9.0.27",
+ "@fluentui/react-shared-contexts": "^9.14.0",
+ "@fluentui/react-theme": "^9.1.16",
+ "@fluentui/react-utilities": "^9.16.1",
+ "@griffel/react": "^1.5.14",
+ "@swc/helpers": "^0.5.1"
+ }
+ },
+ "@fluentui/react-shared-contexts": {
+ "version": "9.14.0",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-shared-contexts/-/react-shared-contexts-9.14.0.tgz",
+ "integrity": "sha512-P9yhg31WYfB1W66/gD3+qVCLBsyIEcOzQvKVaIQvd9UhF67lNW4kMXUB6YVOk5PV0Og4hXnkH/vuHl7YMD9RHw==",
+ "requires": {
+ "@fluentui/react-theme": "^9.1.16",
+ "@swc/helpers": "^0.5.1"
+ }
+ },
+ "@fluentui/react-skeleton": {
+ "version": "9.0.48",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-skeleton/-/react-skeleton-9.0.48.tgz",
+ "integrity": "sha512-P0Rw5hIOn5CrZIWg7nVoK3gamxFhZI80KcRVaWap4O3gLo5C8nKHJWOtyBQZ5WKH+S6hoEGZ2USL6CoyXslxeQ==",
+ "requires": {
+ "@fluentui/react-field": "^9.1.50",
+ "@fluentui/react-jsx-runtime": "^9.0.27",
+ "@fluentui/react-shared-contexts": "^9.14.0",
+ "@fluentui/react-theme": "^9.1.16",
+ "@fluentui/react-utilities": "^9.16.1",
+ "@griffel/react": "^1.5.14",
+ "@swc/helpers": "^0.5.1"
+ }
+ },
+ "@fluentui/react-slider": {
+ "version": "9.1.65",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-slider/-/react-slider-9.1.65.tgz",
+ "integrity": "sha512-7kuJMIojxCmNOuiRmQwh9iiXx8zwxkrgvsWmReRIBX0WB6w1VqMcuuikq2Z2ISgNPmepCX8W+qDfx8Ne4F/HtQ==",
+ "requires": {
+ "@fluentui/react-field": "^9.1.50",
+ "@fluentui/react-jsx-runtime": "^9.0.27",
+ "@fluentui/react-shared-contexts": "^9.14.0",
+ "@fluentui/react-tabster": "^9.17.3",
+ "@fluentui/react-theme": "^9.1.16",
+ "@fluentui/react-utilities": "^9.16.1",
+ "@griffel/react": "^1.5.14",
+ "@swc/helpers": "^0.5.1"
+ }
+ },
+ "@fluentui/react-spinbutton": {
+ "version": "9.2.60",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-spinbutton/-/react-spinbutton-9.2.60.tgz",
+ "integrity": "sha512-0IIxEH0CTf4fNMoyvMa37bc63+0ZlznlsNy8lF3hujAT8Z9sUKVMH68e6tGUuXGJIkCUyDKU8HA+9FF2DyPvNA==",
+ "requires": {
+ "@fluentui/keyboard-keys": "^9.0.7",
+ "@fluentui/react-field": "^9.1.50",
+ "@fluentui/react-icons": "^2.0.224",
+ "@fluentui/react-jsx-runtime": "^9.0.27",
+ "@fluentui/react-shared-contexts": "^9.14.0",
+ "@fluentui/react-theme": "^9.1.16",
+ "@fluentui/react-utilities": "^9.16.1",
+ "@griffel/react": "^1.5.14",
+ "@swc/helpers": "^0.5.1"
+ }
+ },
+ "@fluentui/react-spinner": {
+ "version": "9.3.38",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-spinner/-/react-spinner-9.3.38.tgz",
+ "integrity": "sha512-dPJr7/rgU2Qe/K2BciJTAEwEd0ytGpCw3VOVyK2T25w7Jw5RAHmgP+mbw+7se44Mr6sd1LH76mh5sfmQ3tODgw==",
+ "requires": {
+ "@fluentui/react-jsx-runtime": "^9.0.27",
+ "@fluentui/react-label": "^9.1.58",
+ "@fluentui/react-shared-contexts": "^9.14.0",
+ "@fluentui/react-theme": "^9.1.16",
+ "@fluentui/react-utilities": "^9.16.1",
+ "@griffel/react": "^1.5.14",
+ "@swc/helpers": "^0.5.1"
+ }
+ },
+ "@fluentui/react-switch": {
+ "version": "9.1.65",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-switch/-/react-switch-9.1.65.tgz",
+ "integrity": "sha512-P0DwogD6hZJ3O005zCFPDoFXuzkrpKMrAeQGh9X0fqFP5JyHXVCgAAZQOLcphbbT9QukoEF5irN2Z4L9gBn57A==",
+ "requires": {
+ "@fluentui/react-field": "^9.1.50",
+ "@fluentui/react-icons": "^2.0.224",
+ "@fluentui/react-jsx-runtime": "^9.0.27",
+ "@fluentui/react-label": "^9.1.58",
+ "@fluentui/react-shared-contexts": "^9.14.0",
+ "@fluentui/react-tabster": "^9.17.3",
+ "@fluentui/react-theme": "^9.1.16",
+ "@fluentui/react-utilities": "^9.16.1",
+ "@griffel/react": "^1.5.14",
+ "@swc/helpers": "^0.5.1"
+ }
+ },
+ "@fluentui/react-table": {
+ "version": "9.11.5",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-table/-/react-table-9.11.5.tgz",
+ "integrity": "sha512-roQRITOtl1aqXlachS2oTraVE45x3KdDrX0KyQGCdcQRxNprXJW6dIK9QjlbAL6yAsAMDafmFA4y9uRxl408dQ==",
+ "requires": {
+ "@fluentui/keyboard-keys": "^9.0.7",
+ "@fluentui/react-aria": "^9.7.3",
+ "@fluentui/react-avatar": "^9.6.9",
+ "@fluentui/react-checkbox": "^9.2.8",
+ "@fluentui/react-context-selector": "^9.1.49",
+ "@fluentui/react-icons": "^2.0.224",
+ "@fluentui/react-jsx-runtime": "^9.0.27",
+ "@fluentui/react-radio": "^9.2.3",
+ "@fluentui/react-shared-contexts": "^9.14.0",
+ "@fluentui/react-tabster": "^9.17.3",
+ "@fluentui/react-theme": "^9.1.16",
+ "@fluentui/react-utilities": "^9.16.1",
+ "@griffel/react": "^1.5.14",
+ "@swc/helpers": "^0.5.1"
+ }
+ },
+ "@fluentui/react-tabs": {
+ "version": "9.4.6",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-tabs/-/react-tabs-9.4.6.tgz",
+ "integrity": "sha512-LQvibLeJFyqKKiOjZUkRvbfLtsVosUhNUdh1SCQUPxQVpEPSK6XgwK0A1+jjoVhKn+PAJakxRINgnvqQD8pQBA==",
+ "requires": {
+ "@fluentui/react-context-selector": "^9.1.49",
+ "@fluentui/react-jsx-runtime": "^9.0.27",
+ "@fluentui/react-shared-contexts": "^9.14.0",
+ "@fluentui/react-tabster": "^9.17.3",
+ "@fluentui/react-theme": "^9.1.16",
+ "@fluentui/react-utilities": "^9.16.1",
+ "@griffel/react": "^1.5.14",
+ "@swc/helpers": "^0.5.1"
+ }
+ },
+ "@fluentui/react-tabster": {
+ "version": "9.17.3",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-tabster/-/react-tabster-9.17.3.tgz",
+ "integrity": "sha512-cFcUYrkGW15w5yXzCPTTVG/7x5kNXxnhQXuh8SPyCc9JZeG7XI3+hy1T37PsXGxNS4KN9ePHkBHzgDfYO4gzYQ==",
+ "requires": {
+ "@fluentui/react-shared-contexts": "^9.14.0",
+ "@fluentui/react-theme": "^9.1.16",
+ "@fluentui/react-utilities": "^9.16.1",
+ "@griffel/react": "^1.5.14",
+ "@swc/helpers": "^0.5.1",
+ "keyborg": "^2.3.0",
+ "tabster": "^5.0.1"
+ }
+ },
+ "@fluentui/react-tags": {
+ "version": "9.0.22",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-tags/-/react-tags-9.0.22.tgz",
+ "integrity": "sha512-gQIOCVu3HIfGjtAmwOnwBEnTsNyRBU8Pvs6EugpUyyqkRjzbm5TnL3LtiUy4f6/+NuaRqcYAvhwpdUhrlciwcA==",
+ "requires": {
+ "@fluentui/keyboard-keys": "^9.0.7",
+ "@fluentui/react-aria": "^9.7.3",
+ "@fluentui/react-avatar": "^9.6.9",
+ "@fluentui/react-icons": "^2.0.224",
+ "@fluentui/react-jsx-runtime": "^9.0.27",
+ "@fluentui/react-shared-contexts": "^9.14.0",
+ "@fluentui/react-tabster": "^9.17.3",
+ "@fluentui/react-theme": "^9.1.16",
+ "@fluentui/react-utilities": "^9.16.1",
+ "@griffel/react": "^1.5.14",
+ "@swc/helpers": "^0.5.1"
+ }
+ },
+ "@fluentui/react-text": {
+ "version": "9.4.7",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-text/-/react-text-9.4.7.tgz",
+ "integrity": "sha512-c6uJ98B35L8sviYxhQj1i+LW+HVNDdco2ImS9VLv/Duo4HiYs1G2y1YhtBDDiGxLe2moIvfg9ajDzMZV29aXFw==",
+ "requires": {
+ "@fluentui/react-jsx-runtime": "^9.0.27",
+ "@fluentui/react-shared-contexts": "^9.14.0",
+ "@fluentui/react-theme": "^9.1.16",
+ "@fluentui/react-utilities": "^9.16.1",
+ "@griffel/react": "^1.5.14",
+ "@swc/helpers": "^0.5.1"
+ }
+ },
+ "@fluentui/react-textarea": {
+ "version": "9.3.60",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-textarea/-/react-textarea-9.3.60.tgz",
+ "integrity": "sha512-wH4MBWT4EOgNH9FXTjcgH34oANUaoduhmVjffnxaPl3R767Ak0fZPG7kky7yrLMjTDUSwILsEj/q+hsN6o+7Ag==",
+ "requires": {
+ "@fluentui/react-field": "^9.1.50",
+ "@fluentui/react-jsx-runtime": "^9.0.27",
+ "@fluentui/react-shared-contexts": "^9.14.0",
+ "@fluentui/react-theme": "^9.1.16",
+ "@fluentui/react-utilities": "^9.16.1",
+ "@griffel/react": "^1.5.14",
+ "@swc/helpers": "^0.5.1"
+ }
+ },
+ "@fluentui/react-theme": {
+ "version": "9.1.16",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-theme/-/react-theme-9.1.16.tgz",
+ "integrity": "sha512-QK2dGE5aQXN1UGdiEmGKpYGP3tHXIchLvFf8DEEOWnF4XBc9SiEPNFYkvLMJjHxZmDz4D670rsOPe0r5jFDEKQ==",
+ "requires": {
+ "@fluentui/tokens": "1.0.0-alpha.13",
+ "@swc/helpers": "^0.5.1"
+ }
+ },
+ "@fluentui/react-toast": {
+ "version": "9.3.27",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-toast/-/react-toast-9.3.27.tgz",
+ "integrity": "sha512-DbRAYyL5Bd/pcFiGHPpK+rQMyc4LBll9YBy496l97dGDO2HmqFuiwP74V1KznxLcr4inCNWwThIJws5VLFsJLg==",
+ "requires": {
+ "@fluentui/keyboard-keys": "^9.0.7",
+ "@fluentui/react-aria": "^9.7.3",
+ "@fluentui/react-icons": "^2.0.224",
+ "@fluentui/react-jsx-runtime": "^9.0.27",
+ "@fluentui/react-portal": "^9.4.10",
+ "@fluentui/react-shared-contexts": "^9.14.0",
+ "@fluentui/react-tabster": "^9.17.3",
+ "@fluentui/react-theme": "^9.1.16",
+ "@fluentui/react-utilities": "^9.16.1",
+ "@griffel/react": "^1.5.14",
+ "@swc/helpers": "^0.5.1",
+ "react-transition-group": "^4.4.1"
+ }
+ },
+ "@fluentui/react-toolbar": {
+ "version": "9.1.66",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-toolbar/-/react-toolbar-9.1.66.tgz",
+ "integrity": "sha512-ooNTp1R5MBZwiVK8fiJu29gE48vUx4NbXdwB2yHcCprasG3asjuoKQfOYM4+1NfFA0DetVrbK8L46IBeZyeBvA==",
+ "requires": {
+ "@fluentui/react-button": "^9.3.65",
+ "@fluentui/react-context-selector": "^9.1.49",
+ "@fluentui/react-divider": "^9.2.58",
+ "@fluentui/react-jsx-runtime": "^9.0.27",
+ "@fluentui/react-radio": "^9.2.3",
+ "@fluentui/react-shared-contexts": "^9.14.0",
+ "@fluentui/react-tabster": "^9.17.3",
+ "@fluentui/react-theme": "^9.1.16",
+ "@fluentui/react-utilities": "^9.16.1",
+ "@griffel/react": "^1.5.14",
+ "@swc/helpers": "^0.5.1"
+ }
+ },
+ "@fluentui/react-tooltip": {
+ "version": "9.4.11",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-tooltip/-/react-tooltip-9.4.11.tgz",
+ "integrity": "sha512-HXm8yYuAHJuczeFExco0WQSjO3DzDj5AJxqICHF8qtbtihUKfWpPnKM1qQWR+yJR2zc2jzvOEIzZXEkxSG+fSg==",
+ "requires": {
+ "@fluentui/keyboard-keys": "^9.0.7",
+ "@fluentui/react-jsx-runtime": "^9.0.27",
+ "@fluentui/react-portal": "^9.4.10",
+ "@fluentui/react-positioning": "^9.12.4",
+ "@fluentui/react-shared-contexts": "^9.14.0",
+ "@fluentui/react-tabster": "^9.17.3",
+ "@fluentui/react-theme": "^9.1.16",
+ "@fluentui/react-utilities": "^9.16.1",
+ "@griffel/react": "^1.5.14",
+ "@swc/helpers": "^0.5.1"
+ }
+ },
+ "@fluentui/react-tree": {
+ "version": "9.4.25",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-tree/-/react-tree-9.4.25.tgz",
+ "integrity": "sha512-7IMqnOiNFMRuPujnbxJUYD8AEh0z1OGXkdNkAeLyj3pkwuvQs9+TbaNtv5Z372YN+kwYF4EYalYcPuNsRlx7cQ==",
+ "requires": {
+ "@fluentui/keyboard-keys": "^9.0.7",
+ "@fluentui/react-aria": "^9.7.3",
+ "@fluentui/react-avatar": "^9.6.9",
+ "@fluentui/react-button": "^9.3.65",
+ "@fluentui/react-checkbox": "^9.2.8",
+ "@fluentui/react-context-selector": "^9.1.49",
+ "@fluentui/react-icons": "^2.0.224",
+ "@fluentui/react-jsx-runtime": "^9.0.27",
+ "@fluentui/react-radio": "^9.2.3",
+ "@fluentui/react-shared-contexts": "^9.14.0",
+ "@fluentui/react-tabster": "^9.17.3",
+ "@fluentui/react-theme": "^9.1.16",
+ "@fluentui/react-utilities": "^9.16.1",
+ "@griffel/react": "^1.5.14",
+ "@swc/helpers": "^0.5.1"
+ }
+ },
+ "@fluentui/react-utilities": {
+ "version": "9.16.1",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-utilities/-/react-utilities-9.16.1.tgz",
+ "integrity": "sha512-2wdwmgTFcVy14ZLbRNJ8Q6dCCBLekkJ8Znnok68gKRLDcwpPT3UjSraoU+DGjOA5BMfPppZBU8Yb5GqdIfd48g==",
+ "requires": {
+ "@fluentui/keyboard-keys": "^9.0.7",
+ "@fluentui/react-shared-contexts": "^9.14.0",
+ "@swc/helpers": "^0.5.1"
+ }
+ },
+ "@fluentui/react-virtualizer": {
+ "version": "9.0.0-alpha.66",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-virtualizer/-/react-virtualizer-9.0.0-alpha.66.tgz",
+ "integrity": "sha512-x/ZOAIAwctt7pvOBIzS4iZGU0ahiPhQFS7iAHksFkF9LimneaV92A/02dW0Cy4v7dv9wZNoosQwhS05Yx3DVDQ==",
+ "requires": {
+ "@fluentui/react-jsx-runtime": "^9.0.27",
+ "@fluentui/react-shared-contexts": "^9.14.0",
+ "@fluentui/react-utilities": "^9.16.1",
+ "@griffel/react": "^1.5.14",
+ "@swc/helpers": "^0.5.1"
+ }
+ },
+ "@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==",
+ "requires": {
+ "@fluentui/set-version": "^8.2.14",
+ "tslib": "^2.1.0"
+ }
+ },
+ "@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==",
+ "requires": {
+ "tslib": "^2.1.0"
+ }
+ },
+ "@fluentui/style-utilities": {
+ "version": "8.10.2",
+ "resolved": "https://registry.npmjs.org/@fluentui/style-utilities/-/style-utilities-8.10.2.tgz",
+ "integrity": "sha512-ocELtMb/85nBa3rSfiAIwYx6TydN+3rQqv1P0H/L7etYNNtxOfS86JSWfn8zAsHMejbwUKJ1ZsIKs47c598XGQ==",
+ "requires": {
+ "@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"
+ }
+ },
+ "@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==",
+ "requires": {
+ "@fluentui/merge-styles": "^8.5.15",
+ "@fluentui/set-version": "^8.2.14",
+ "@fluentui/utilities": "^8.13.24",
+ "tslib": "^2.1.0"
+ }
+ },
+ "@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==",
+ "requires": {
+ "@swc/helpers": "^0.5.1"
+ }
+ },
+ "@fluentui/utilities": {
+ "version": "8.13.24",
+ "resolved": "https://registry.npmjs.org/@fluentui/utilities/-/utilities-8.13.24.tgz",
+ "integrity": "sha512-/jo6hWCzTGCx06l2baAMwsjjBZ/dyMouls53uNaQLUGUUhUwXh/DcDDXMqLRJB3MaH9zvgfvRw61iKmm2s9fIA==",
+ "requires": {
+ "@fluentui/dom-utilities": "^2.2.14",
+ "@fluentui/merge-styles": "^8.5.15",
+ "@fluentui/set-version": "^8.2.14",
+ "tslib": "^2.1.0"
+ }
+ },
+ "@griffel/core": {
+ "version": "1.15.2",
+ "resolved": "https://registry.npmjs.org/@griffel/core/-/core-1.15.2.tgz",
+ "integrity": "sha512-RlsIXoSS3gaYykUgxFpwKAs/DV9cRUKp3CW1kt3iPAtsDTWn/o+8bT1jvBws/tMM2GBu/Uc0EkaIzUPqD7uA+Q==",
+ "requires": {
+ "@emotion/hash": "^0.9.0",
+ "@griffel/style-types": "^1.0.3",
+ "csstype": "^3.1.3",
+ "rtl-css-js": "^1.16.1",
+ "stylis": "^4.2.0",
+ "tslib": "^2.1.0"
+ }
+ },
+ "@griffel/react": {
+ "version": "1.5.20",
+ "resolved": "https://registry.npmjs.org/@griffel/react/-/react-1.5.20.tgz",
+ "integrity": "sha512-1P2yaPctENFSCwyPIYXBmgpNH68c0lc/jwSzPij1QATHDK1AASKuSeq6hW108I67RKjhRyHCcALshdZ3GcQXSg==",
+ "requires": {
+ "@griffel/core": "^1.15.2",
+ "tslib": "^2.1.0"
+ }
+ },
+ "@griffel/style-types": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/@griffel/style-types/-/style-types-1.0.3.tgz",
+ "integrity": "sha512-AzbbYV/EobNIBtfMtyu2edFin895gjVxtu1nsRhTETUAIb0/LCZoue3Jd/kFLuPwe95rv5WRUBiQpVwJsrrFcw==",
+ "requires": {
+ "csstype": "^3.1.3"
+ }
+ },
+ "@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,
+ "requires": {
+ "@jridgewell/set-array": "^1.0.1",
+ "@jridgewell/sourcemap-codec": "^1.4.10",
+ "@jridgewell/trace-mapping": "^0.3.9"
+ }
+ },
+ "@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
+ },
+ "@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
+ },
+ "@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
+ },
+ "@jridgewell/trace-mapping": {
+ "version": "0.3.21",
+ "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.21.tgz",
+ "integrity": "sha512-SRfKmRe1KvYnxjEMtxEr+J4HIeMX5YBg/qhRHpxEIGjhX1rshcHlnFUE9K0GazhVKWM7B+nARSkV8LuvJdJ5/g==",
+ "dev": true,
+ "requires": {
+ "@jridgewell/resolve-uri": "^3.1.0",
+ "@jridgewell/sourcemap-codec": "^1.4.14"
+ }
+ },
+ "@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=="
+ },
+ "@react-spring/animated": {
+ "version": "9.7.3",
+ "resolved": "https://registry.npmjs.org/@react-spring/animated/-/animated-9.7.3.tgz",
+ "integrity": "sha512-5CWeNJt9pNgyvuSzQH+uy2pvTg8Y4/OisoscZIR8/ZNLIOI+CatFBhGZpDGTF/OzdNFsAoGk3wiUYTwoJ0YIvw==",
+ "requires": {
+ "@react-spring/shared": "~9.7.3",
+ "@react-spring/types": "~9.7.3"
+ }
+ },
+ "@react-spring/core": {
+ "version": "9.7.3",
+ "resolved": "https://registry.npmjs.org/@react-spring/core/-/core-9.7.3.tgz",
+ "integrity": "sha512-IqFdPVf3ZOC1Cx7+M0cXf4odNLxDC+n7IN3MDcVCTIOSBfqEcBebSv+vlY5AhM0zw05PDbjKrNmBpzv/AqpjnQ==",
+ "requires": {
+ "@react-spring/animated": "~9.7.3",
+ "@react-spring/shared": "~9.7.3",
+ "@react-spring/types": "~9.7.3"
+ }
+ },
+ "@react-spring/shared": {
+ "version": "9.7.3",
+ "resolved": "https://registry.npmjs.org/@react-spring/shared/-/shared-9.7.3.tgz",
+ "integrity": "sha512-NEopD+9S5xYyQ0pGtioacLhL2luflh6HACSSDUZOwLHoxA5eku1UPuqcJqjwSD6luKjjLfiLOspxo43FUHKKSA==",
+ "requires": {
+ "@react-spring/types": "~9.7.3"
+ }
+ },
+ "@react-spring/types": {
+ "version": "9.7.3",
+ "resolved": "https://registry.npmjs.org/@react-spring/types/-/types-9.7.3.tgz",
+ "integrity": "sha512-Kpx/fQ/ZFX31OtlqVEFfgaD1ACzul4NksrvIgYfIFq9JpDHFwQkMVZ10tbo0FU/grje4rcL4EIrjekl3kYwgWw=="
+ },
+ "@react-spring/web": {
+ "version": "9.7.3",
+ "resolved": "https://registry.npmjs.org/@react-spring/web/-/web-9.7.3.tgz",
+ "integrity": "sha512-BXt6BpS9aJL/QdVqEIX9YoUy8CE6TJrU0mNCqSoxdXlIeNcEBWOfIyE6B14ENNsyQKS3wOWkiJfco0tCr/9tUg==",
+ "requires": {
+ "@react-spring/animated": "~9.7.3",
+ "@react-spring/core": "~9.7.3",
+ "@react-spring/shared": "~9.7.3",
+ "@react-spring/types": "~9.7.3"
+ }
+ },
+ "@remix-run/router": {
+ "version": "1.14.2",
+ "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.14.2.tgz",
+ "integrity": "sha512-ACXpdMM9hmKZww21yEqWwiLws/UPLhNKvimN8RrYSqPSvB3ov7sLvAcfvaxePeLvccTQKGdkDIhLYApZVDFuKg=="
+ },
+ "@rollup/plugin-typescript": {
+ "version": "11.1.3",
+ "resolved": "https://registry.npmjs.org/@rollup/plugin-typescript/-/plugin-typescript-11.1.3.tgz",
+ "integrity": "sha512-8o6cNgN44kQBcpsUJTbTXMTtb87oR1O0zgP3Dxm71hrNgparap3VujgofEilTYJo+ivf2ke6uy3/E5QEaiRlDA==",
+ "requires": {
+ "@rollup/pluginutils": "^5.0.1",
+ "resolve": "^1.22.1"
+ }
+ },
+ "@rollup/pluginutils": {
+ "version": "5.0.4",
+ "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.0.4.tgz",
+ "integrity": "sha512-0KJnIoRI8A+a1dqOYLxH8vBf8bphDmty5QvIm2hqm7oFCFYKCAZWWd2hXgMibaPsNDhI0AtpYfQZJG47pt/k4g==",
+ "requires": {
+ "@types/estree": "^1.0.0",
+ "estree-walker": "^2.0.2",
+ "picomatch": "^2.3.1"
+ }
+ },
+ "@swc/helpers": {
+ "version": "0.5.3",
+ "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.3.tgz",
+ "integrity": "sha512-FaruWX6KdudYloq1AHD/4nU+UsMTdNE8CKyrseXWEcgjDAbvkwJg2QGPAnfIJLIWsjZOSPLOAykK6fuYp4vp4A==",
+ "requires": {
+ "tslib": "^2.4.0"
+ }
+ },
+ "@types/babel__core": {
+ "version": "7.20.5",
+ "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz",
+ "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==",
+ "dev": true,
+ "requires": {
+ "@babel/parser": "^7.20.7",
+ "@babel/types": "^7.20.7",
+ "@types/babel__generator": "*",
+ "@types/babel__template": "*",
+ "@types/babel__traverse": "*"
+ }
+ },
+ "@types/babel__generator": {
+ "version": "7.6.8",
+ "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.8.tgz",
+ "integrity": "sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw==",
+ "dev": true,
+ "requires": {
+ "@babel/types": "^7.0.0"
+ }
+ },
+ "@types/babel__template": {
+ "version": "7.4.4",
+ "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz",
+ "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==",
+ "dev": true,
+ "requires": {
+ "@babel/parser": "^7.1.0",
+ "@babel/types": "^7.0.0"
+ }
+ },
+ "@types/babel__traverse": {
+ "version": "7.20.5",
+ "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.5.tgz",
+ "integrity": "sha512-WXCyOcRtH37HAUkpXhUduaxdm82b4GSlyTqajXviN4EfiuPgNYR109xMCKvpl6zPIpua0DGlMEDCq+g8EdoheQ==",
+ "dev": true,
+ "requires": {
+ "@babel/types": "^7.20.7"
+ }
+ },
+ "@types/dompurify": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/@types/dompurify/-/dompurify-3.0.3.tgz",
+ "integrity": "sha512-odiGr/9/qMqjcBOe5UhcNLOFHSYmKFOyr+bJ/Xu3Qp4k1pNPAlNLUVNNLcLfjQI7+W7ObX58EdD3H+3p3voOvA==",
+ "dev": true,
+ "requires": {
+ "@types/trusted-types": "*"
+ }
+ },
+ "@types/estree": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.1.tgz",
+ "integrity": "sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA=="
+ },
+ "@types/prop-types": {
+ "version": "15.7.5",
+ "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz",
+ "integrity": "sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w=="
+ },
+ "@types/react": {
+ "version": "18.2.48",
+ "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.48.tgz",
+ "integrity": "sha512-qboRCl6Ie70DQQG9hhNREz81jqC1cs9EVNcjQ1AU+jH6NFfSAhVVbrrY/+nSF+Bsk4AOwm9Qa61InvMCyV+H3w==",
+ "requires": {
+ "@types/prop-types": "*",
+ "@types/scheduler": "*",
+ "csstype": "^3.0.2"
+ }
+ },
+ "@types/react-dom": {
+ "version": "18.2.18",
+ "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.2.18.tgz",
+ "integrity": "sha512-TJxDm6OfAX2KJWJdMEVTwWke5Sc/E/RlnPGvGfS0W7+6ocy2xhDVQVh/KvC2Uf7kACs+gDytdusDSdWfWkaNzw==",
+ "requires": {
+ "@types/react": "*"
+ }
+ },
+ "@types/scheduler": {
+ "version": "0.16.2",
+ "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.2.tgz",
+ "integrity": "sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew=="
+ },
+ "@types/trusted-types": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.3.tgz",
+ "integrity": "sha512-NfQ4gyz38SL8sDNrSixxU2Os1a5xcdFxipAFxYEuLUlvU2uDwS4NUpsImcf1//SlWItCVMMLiylsxbmNMToV/g==",
+ "dev": true
+ },
+ "@vitejs/plugin-react": {
+ "version": "4.2.1",
+ "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-4.2.1.tgz",
+ "integrity": "sha512-oojO9IDc4nCUUi8qIR11KoQm0XFFLIwsRBwHRR4d/88IWghn1y6ckz/bJ8GHDCsYEJee8mDzqtJxh15/cisJNQ==",
+ "dev": true,
+ "requires": {
+ "@babel/core": "^7.23.5",
+ "@babel/plugin-transform-react-jsx-self": "^7.23.3",
+ "@babel/plugin-transform-react-jsx-source": "^7.23.3",
+ "@types/babel__core": "^7.20.5",
+ "react-refresh": "^0.14.0"
+ }
+ },
+ "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,
+ "requires": {
+ "color-convert": "^1.9.0"
+ }
+ },
+ "browserslist": {
+ "version": "4.22.2",
+ "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.22.2.tgz",
+ "integrity": "sha512-0UgcrvQmBDvZHFGdYUehrCNIazki7/lUP3kkoi/r3YB2amZbFM9J43ZRkJTXBUZK4gmx56+Sqk9+Vs9mwZx9+A==",
+ "dev": true,
+ "requires": {
+ "caniuse-lite": "^1.0.30001565",
+ "electron-to-chromium": "^1.4.601",
+ "node-releases": "^2.0.14",
+ "update-browserslist-db": "^1.0.13"
+ }
+ },
+ "caniuse-lite": {
+ "version": "1.0.30001579",
+ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001579.tgz",
+ "integrity": "sha512-u5AUVkixruKHJjw/pj9wISlcMpgFWzSrczLZbrqBSxukQixmg0SJ5sZTpvaFvxU0HoQKd4yoyAogyrAz9pzJnA==",
+ "dev": true
+ },
+ "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,
+ "requires": {
+ "ansi-styles": "^3.2.1",
+ "escape-string-regexp": "^1.0.5",
+ "supports-color": "^5.3.0"
+ }
+ },
+ "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,
+ "requires": {
+ "color-name": "1.1.3"
+ }
+ },
+ "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
+ },
+ "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
+ },
+ "csstype": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz",
+ "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw=="
+ },
+ "debug": {
+ "version": "4.3.4",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
+ "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
+ "dev": true,
+ "requires": {
+ "ms": "2.1.2"
+ }
+ },
+ "dom-helpers": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.2.1.tgz",
+ "integrity": "sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==",
+ "requires": {
+ "@babel/runtime": "^7.8.7",
+ "csstype": "^3.0.2"
+ }
+ },
+ "dompurify": {
+ "version": "3.0.6",
+ "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.0.6.tgz",
+ "integrity": "sha512-ilkD8YEnnGh1zJ240uJsW7AzE+2qpbOUYjacomn3AvJ6J4JhKGSZ2nh4wUIXPZrEPppaCLx5jFe8T89Rk8tQ7w=="
+ },
+ "electron-to-chromium": {
+ "version": "1.4.639",
+ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.639.tgz",
+ "integrity": "sha512-CkKf3ZUVZchr+zDpAlNLEEy2NJJ9T64ULWaDgy3THXXlPVPkLu3VOs9Bac44nebVtdwl2geSj6AxTtGDOxoXhg==",
+ "dev": true
+ },
+ "esbuild": {
+ "version": "0.18.11",
+ "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.11.tgz",
+ "integrity": "sha512-i8u6mQF0JKJUlGR3OdFLKldJQMMs8OqM9Cc3UCi9XXziJ9WERM5bfkHaEAy0YAvPRMgqSW55W7xYn84XtEFTtA==",
+ "dev": true,
+ "requires": {
+ "@esbuild/android-arm": "0.18.11",
+ "@esbuild/android-arm64": "0.18.11",
+ "@esbuild/android-x64": "0.18.11",
+ "@esbuild/darwin-arm64": "0.18.11",
+ "@esbuild/darwin-x64": "0.18.11",
+ "@esbuild/freebsd-arm64": "0.18.11",
+ "@esbuild/freebsd-x64": "0.18.11",
+ "@esbuild/linux-arm": "0.18.11",
+ "@esbuild/linux-arm64": "0.18.11",
+ "@esbuild/linux-ia32": "0.18.11",
+ "@esbuild/linux-loong64": "0.18.11",
+ "@esbuild/linux-mips64el": "0.18.11",
+ "@esbuild/linux-ppc64": "0.18.11",
+ "@esbuild/linux-riscv64": "0.18.11",
+ "@esbuild/linux-s390x": "0.18.11",
+ "@esbuild/linux-x64": "0.18.11",
+ "@esbuild/netbsd-x64": "0.18.11",
+ "@esbuild/openbsd-x64": "0.18.11",
+ "@esbuild/sunos-x64": "0.18.11",
+ "@esbuild/win32-arm64": "0.18.11",
+ "@esbuild/win32-ia32": "0.18.11",
+ "@esbuild/win32-x64": "0.18.11"
+ }
+ },
+ "escalade": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz",
+ "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==",
+ "dev": true
+ },
+ "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
+ },
+ "estree-walker": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz",
+ "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w=="
+ },
+ "fsevents": {
+ "version": "2.3.2",
+ "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
+ "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
+ "optional": true
+ },
+ "function-bind": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
+ "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A=="
+ },
+ "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
+ },
+ "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
+ },
+ "has": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
+ "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
+ "requires": {
+ "function-bind": "^1.1.1"
+ }
+ },
+ "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
+ },
+ "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==",
+ "requires": {
+ "has": "^1.0.3"
+ }
+ },
+ "js-tokens": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
+ "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="
+ },
+ "jsesc": {
+ "version": "2.5.2",
+ "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz",
+ "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==",
+ "dev": true
+ },
+ "json5": {
+ "version": "2.2.3",
+ "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
+ "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",
+ "dev": true
+ },
+ "keyborg": {
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/keyborg/-/keyborg-2.4.1.tgz",
+ "integrity": "sha512-B9EZwDd36WKlIq6JmimaTsTDx5E0aUqZcxtgTfK66ut1FbRXYhBmiB7Al2qKzB7CCX9C49sTBiiyVzsXCA6J4Q=="
+ },
+ "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==",
+ "requires": {
+ "js-tokens": "^3.0.0 || ^4.0.0"
+ }
+ },
+ "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,
+ "requires": {
+ "yallist": "^3.0.2"
+ }
+ },
+ "ms": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
+ "dev": true
+ },
+ "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
+ },
+ "ndjson-readablestream": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/ndjson-readablestream/-/ndjson-readablestream-1.0.7.tgz",
+ "integrity": "sha512-4DDTwYTV4yRnCoXparQTF3JeahTNkLVy7XlA0RHXzAqQ3uU8vcu97bNW8rXAQOKQVJGs2aZoX+7cbvfs0LENEA=="
+ },
+ "node-releases": {
+ "version": "2.0.14",
+ "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz",
+ "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==",
+ "dev": true
+ },
+ "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=="
+ },
+ "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=="
+ },
+ "picocolors": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
+ "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==",
+ "dev": true
+ },
+ "picomatch": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
+ "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="
+ },
+ "postcss": {
+ "version": "8.4.31",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz",
+ "integrity": "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==",
+ "dev": true,
+ "requires": {
+ "nanoid": "^3.3.6",
+ "picocolors": "^1.0.0",
+ "source-map-js": "^1.0.2"
+ }
+ },
+ "prettier": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.0.3.tgz",
+ "integrity": "sha512-L/4pUDMxcNa8R/EthV08Zt42WBO4h1rarVtK0K+QJG0X187OLo7l699jWw0GKuwzkPQ//jMFA/8Xm6Fh3J/DAg==",
+ "dev": true
+ },
+ "prop-types": {
+ "version": "15.8.1",
+ "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz",
+ "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==",
+ "requires": {
+ "loose-envify": "^1.4.0",
+ "object-assign": "^4.1.1",
+ "react-is": "^16.13.1"
+ },
+ "dependencies": {
+ "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=="
+ }
+ }
+ },
+ "react": {
+ "version": "18.2.0",
+ "resolved": "https://registry.npmjs.org/react/-/react-18.2.0.tgz",
+ "integrity": "sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==",
+ "requires": {
+ "loose-envify": "^1.1.0"
+ }
+ },
+ "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==",
+ "requires": {
+ "loose-envify": "^1.1.0",
+ "scheduler": "^0.23.0"
+ },
+ "dependencies": {
+ "scheduler": {
+ "version": "0.23.0",
+ "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz",
+ "integrity": "sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==",
+ "requires": {
+ "loose-envify": "^1.1.0"
+ }
+ }
+ }
+ },
+ "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=="
+ },
+ "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
+ },
+ "react-router": {
+ "version": "6.21.3",
+ "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.21.3.tgz",
+ "integrity": "sha512-a0H638ZXULv1OdkmiK6s6itNhoy33ywxmUFT/xtSoVyf9VnC7n7+VT4LjVzdIHSaF5TIh9ylUgxMXksHTgGrKg==",
+ "requires": {
+ "@remix-run/router": "1.14.2"
+ }
+ },
+ "react-router-dom": {
+ "version": "6.21.3",
+ "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.21.3.tgz",
+ "integrity": "sha512-kNzubk7n4YHSrErzjLK72j0B5i969GsuCGazRl3G6j1zqZBLjuSlYBdVdkDOgzGdPIffUOc9nmgiadTEVoq91g==",
+ "requires": {
+ "@remix-run/router": "1.14.2",
+ "react-router": "6.21.3"
+ }
+ },
+ "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==",
+ "requires": {
+ "@babel/runtime": "^7.5.5",
+ "dom-helpers": "^5.0.1",
+ "loose-envify": "^1.4.0",
+ "prop-types": "^15.6.2"
+ }
+ },
+ "regenerator-runtime": {
+ "version": "0.14.1",
+ "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz",
+ "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw=="
+ },
+ "resolve": {
+ "version": "1.22.4",
+ "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.4.tgz",
+ "integrity": "sha512-PXNdCiPqDqeUou+w1C2eTQbNfxKSuMxqTCuvlmmMsk1NWHL5fRrhY6Pl0qEYYc6+QqGClco1Qj8XnjPego4wfg==",
+ "requires": {
+ "is-core-module": "^2.13.0",
+ "path-parse": "^1.0.7",
+ "supports-preserve-symlinks-flag": "^1.0.0"
+ }
+ },
+ "rollup": {
+ "version": "3.29.4",
+ "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.29.4.tgz",
+ "integrity": "sha512-oWzmBZwvYrU0iJHtDmhsm662rC15FRXmcjCk1xD771dFDx5jJ02ufAQQTn0etB2emNk4J9EZg/yWKpsn9BWGRw==",
+ "requires": {
+ "fsevents": "~2.3.2"
+ }
+ },
+ "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==",
+ "requires": {
+ "@babel/runtime": "^7.1.2"
+ }
+ },
+ "scheduler": {
+ "version": "0.20.2",
+ "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.20.2.tgz",
+ "integrity": "sha512-2eWfGgAqqWFGqtdMmcL5zCMK1U8KlXv8SQFGglL3CEtd0aDVDWgeF/YoCmvln55m5zSk3J/20hTaSBeSObsQDQ==",
+ "requires": {
+ "loose-envify": "^1.1.0",
+ "object-assign": "^4.1.1"
+ }
+ },
+ "semver": {
+ "version": "6.3.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
+ "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
+ "dev": true
+ },
+ "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
+ },
+ "stylis": {
+ "version": "4.3.1",
+ "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.3.1.tgz",
+ "integrity": "sha512-EQepAV+wMsIaGVGX1RECzgrcqRRU/0sYOHkeLsZ3fzHaHXZy4DaOOX0vOlGQdlsjkh3mFHAIlVimpwAs4dslyQ=="
+ },
+ "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,
+ "requires": {
+ "has-flag": "^3.0.0"
+ }
+ },
+ "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=="
+ },
+ "tabster": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/tabster/-/tabster-5.2.0.tgz",
+ "integrity": "sha512-cSi3a0gGeM9Co/gTKHlhTFfiitwVjcA+kP9lJux0U7QaRrZox1yYrfbwZhJXM7N0fux7BgvCYaOxME5k0EQ0tA==",
+ "requires": {
+ "keyborg": "^2.2.0",
+ "tslib": "^2.3.1"
+ }
+ },
+ "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
+ },
+ "tslib": {
+ "version": "2.5.0",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.0.tgz",
+ "integrity": "sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg=="
+ },
+ "typescript": {
+ "version": "5.2.2",
+ "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz",
+ "integrity": "sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w=="
+ },
+ "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,
+ "requires": {
+ "escalade": "^3.1.1",
+ "picocolors": "^1.0.0"
+ }
+ },
+ "use-disposable": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/use-disposable/-/use-disposable-1.0.2.tgz",
+ "integrity": "sha512-UMaXVlV77dWOu4GqAFNjRzHzowYKUKbJBQfCexvahrYeIz4OkUYUjna4Tjjdf92NH8Nm8J7wEfFRgTIwYjO5jg==",
+ "requires": {}
+ },
+ "vite": {
+ "version": "4.5.3",
+ "resolved": "https://registry.npmjs.org/vite/-/vite-4.5.3.tgz",
+ "integrity": "sha512-kQL23kMeX92v3ph7IauVkXkikdDRsYMGTVl5KY2E9OY4ONLvkHf04MDTbnfo6NKxZiDLWzVpP5oTa8hQD8U3dg==",
+ "dev": true,
+ "requires": {
+ "esbuild": "^0.18.10",
+ "fsevents": "~2.3.2",
+ "postcss": "^8.4.27",
+ "rollup": "^3.27.1"
+ }
+ },
+ "yallist": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
+ "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==",
+ "dev": true
+ }
+ }
+}
diff --git a/app/frontend/package.json b/app/frontend/package.json
new file mode 100644
index 0000000..5ee802e
--- /dev/null
+++ b/app/frontend/package.json
@@ -0,0 +1,38 @@
+{
+ "name": "frontend",
+ "private": true,
+ "version": "1.0.0-alpha",
+ "type": "module",
+ "engines": {
+ "node": ">=14.0.0"
+ },
+ "scripts": {
+ "dev": "vite --port=8081",
+ "build": "tsc && vite build",
+ "preview": "vite preview"
+ },
+ "dependencies": {
+ "@azure/msal-react": "^2.0.4",
+ "@azure/msal-browser": "^3.1.0",
+ "@fluentui/react": "^8.112.5",
+ "@fluentui/react-components": "^9.37.3",
+ "@fluentui/react-icons": "^2.0.221",
+ "@react-spring/web": "^9.7.3",
+ "dompurify": "^3.0.6",
+ "react": "^18.2.0",
+ "react-dom": "^18.2.0",
+ "react-router-dom": "^6.18.0",
+ "ndjson-readablestream": "^1.0.7",
+ "scheduler": "^0.20.2"
+ },
+ "devDependencies": {
+ "@types/dompurify": "^3.0.3",
+ "@types/react": "^18.2.34",
+ "@types/react-dom": "^18.2.14",
+ "@vitejs/plugin-react": "^4.1.1",
+ "prettier": "^3.0.3",
+ "typescript": "^5.2.2",
+ "vite": "^4.5.3"
+
+ }
+}
diff --git a/app/frontend/public/favicon.ico b/app/frontend/public/favicon.ico
new file mode 100644
index 0000000..f1fe505
Binary files /dev/null and b/app/frontend/public/favicon.ico differ
diff --git a/app/frontend/src/api/api.ts b/app/frontend/src/api/api.ts
new file mode 100644
index 0000000..fb8f511
--- /dev/null
+++ b/app/frontend/src/api/api.ts
@@ -0,0 +1,51 @@
+import { ChatAppResponse, ChatAppResponseOrError, ChatAppRequest } from "./models";
+import { useLogin } from "../authConfig";
+
+const BACKEND_URI = import.meta.env.VITE_BACKEND_URI ? import.meta.env.VITE_BACKEND_URI : "";
+
+function getHeaders(idToken: string | undefined, stream:boolean): Record {
+ var headers: Record = {
+ "Content-Type": "application/json"
+ };
+ // If using login, add the id token of the logged in account as the authorization
+ if (useLogin) {
+ if (idToken) {
+ headers["Authorization"] = `Bearer ${idToken}`
+ }
+ }
+
+ if (stream) {
+ headers["Accept"] = "application/x-ndjson";
+ } else {
+ headers["Accept"] = "application/json";
+ }
+
+ return headers;
+}
+
+export async function askApi(request: ChatAppRequest, idToken: string | undefined): Promise {
+ const response = await fetch(`${BACKEND_URI}/ask`, {
+ method: "POST",
+ headers: getHeaders(idToken, request.stream || false),
+ body: JSON.stringify(request)
+ });
+
+ const parsedResponse: ChatAppResponseOrError = await response.json();
+ if (response.status > 299 || !response.ok) {
+ throw Error(parsedResponse.error || "Unknown error");
+ }
+
+ return parsedResponse as ChatAppResponse;
+}
+
+export async function chatApi(request: ChatAppRequest, idToken: string | undefined): Promise {
+ return await fetch(`${BACKEND_URI}/chat`, {
+ method: "POST",
+ headers: getHeaders(idToken, request.stream || false),
+ body: JSON.stringify(request)
+ });
+}
+
+export function getCitationFilePath(citation: string): string {
+ return `${BACKEND_URI}/content/${citation}`;
+}
diff --git a/app/frontend/src/api/index.ts b/app/frontend/src/api/index.ts
new file mode 100644
index 0000000..0475d35
--- /dev/null
+++ b/app/frontend/src/api/index.ts
@@ -0,0 +1,2 @@
+export * from "./api";
+export * from "./models";
diff --git a/app/frontend/src/api/models.ts b/app/frontend/src/api/models.ts
new file mode 100644
index 0000000..c468488
--- /dev/null
+++ b/app/frontend/src/api/models.ts
@@ -0,0 +1,70 @@
+export const enum Approaches {
+ JAVA_OPENAI_SDK = "jos",
+ JAVA_SEMANTIC_KERNEL = "jsk",
+ JAVA_SEMANTIC_KERNEL_PLANNER = "jskp"
+}
+
+export const enum RetrievalMode {
+ Hybrid = "hybrid",
+ Vectors = "vectors",
+ Text = "text"
+}
+
+export const enum SKMode {
+ Chains = "chains",
+ Planner = "planner"
+}
+
+export type ChatAppRequestOverrides = {
+ retrieval_mode?: RetrievalMode;
+ semantic_ranker?: boolean;
+ semantic_captions?: boolean;
+ exclude_category?: string;
+ top?: number;
+ temperature?: number;
+ prompt_template?: string;
+ prompt_template_prefix?: string;
+ prompt_template_suffix?: string;
+ suggest_followup_questions?: boolean;
+ use_oid_security_filter?: boolean;
+ use_groups_security_filter?: boolean;
+ semantic_kernel_mode?: SKMode;
+};
+
+export type ResponseMessage = {
+ content: string;
+ role: string;
+};
+
+export type ResponseContext = {
+ thoughts: string | null;
+ data_points: string[];
+};
+
+export type ResponseChoice = {
+ index: number;
+ message: ResponseMessage;
+ context: ResponseContext;
+ session_state: any;
+};
+
+export type ChatAppResponseOrError = {
+ choices?: ResponseChoice[];
+ error?: string;
+};
+
+export type ChatAppResponse = {
+ choices: ResponseChoice[];
+};
+
+export type ChatAppRequestContext = {
+ overrides?: ChatAppRequestOverrides;
+};
+
+export type ChatAppRequest = {
+ messages: ResponseMessage[];
+ approach: Approaches;
+ context?: ChatAppRequestContext;
+ stream?: boolean;
+ session_state: any;
+};
diff --git a/app/frontend/src/assets/github.svg b/app/frontend/src/assets/github.svg
new file mode 100644
index 0000000..d5e6491
--- /dev/null
+++ b/app/frontend/src/assets/github.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/app/frontend/src/assets/search.svg b/app/frontend/src/assets/search.svg
new file mode 100644
index 0000000..feadc50
--- /dev/null
+++ b/app/frontend/src/assets/search.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/app/frontend/src/authConfig.ts b/app/frontend/src/authConfig.ts
new file mode 100644
index 0000000..7e583ab
--- /dev/null
+++ b/app/frontend/src/authConfig.ts
@@ -0,0 +1,89 @@
+// Refactored from https://github.com/Azure-Samples/ms-identity-javascript-react-tutorial/blob/main/1-Authentication/1-sign-in/SPA/src/authConfig.js
+
+import { AuthenticationResult, IPublicClientApplication } from "@azure/msal-browser";
+
+const BACKEND_URI = import.meta.env.VITE_BACKEND_URI ? import.meta.env.VITE_BACKEND_URI : "";
+
+interface AuthSetup {
+ // Set to true if login elements should be shown in the UI
+ useLogin: boolean;
+ /**
+ * Configuration object to be passed to MSAL instance on creation.
+ * For a full list of MSAL.js configuration parameters, visit:
+ * https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-browser/docs/configuration.md
+ */
+ msalConfig: {
+ auth: {
+ clientId: string; // Client app id used for login
+ authority: string; // Directory to use for login https://learn.microsoft.com/azure/active-directory/develop/msal-client-application-configuration#authority
+ redirectUri: string; // Points to window.location.origin. You must register this URI on Azure Portal/App Registration.
+ postLogoutRedirectUri: string; // Indicates the page to navigate after logout.
+ navigateToLoginRequestUrl: boolean; // If "true", will navigate back to the original request location before processing the auth code response.
+ };
+ cache: {
+ cacheLocation: string; // Configures cache location. "sessionStorage" is more secure, but "localStorage" gives you SSO between tabs.
+ storeAuthStateInCookie: boolean; // Set this to "true" if you are having issues on IE11 or Edge
+ };
+ };
+ loginRequest: {
+ /**
+ * Scopes you add here will be prompted for user consent during sign-in.
+ * By default, MSAL.js will add OIDC scopes (openid, profile, email) to any login request.
+ * For more information about OIDC scopes, visit:
+ * https://docs.microsoft.com/azure/active-directory/develop/v2-permissions-and-consent#openid-connect-scopes
+ */
+ scopes: Array;
+ };
+ tokenRequest: {
+ scopes: Array;
+ };
+}
+
+// Fetch the auth setup JSON data from the API if not already cached
+async function fetchAuthSetup(): Promise {
+ const response = await fetch(`${BACKEND_URI}/auth_setup`);
+ if (!response.ok) {
+ throw new Error(`auth setup response was not ok: ${response.status}`);
+ }
+ return await response.json();
+}
+
+const authSetup = await fetchAuthSetup();
+
+export const useLogin = authSetup.useLogin;
+
+/**
+ * Configuration object to be passed to MSAL instance on creation.
+ * For a full list of MSAL.js configuration parameters, visit:
+ * https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-browser/docs/configuration.md
+ */
+export const msalConfig = authSetup.msalConfig;
+
+/**
+ * Scopes you add here will be prompted for user consent during sign-in.
+ * By default, MSAL.js will add OIDC scopes (openid, profile, email) to any login request.
+ * For more information about OIDC scopes, visit:
+ * https://docs.microsoft.com/en-us/azure/active-directory/develop/v2-permissions-and-consent#openid-connect-scopes
+ */
+export const loginRequest = authSetup.loginRequest;
+
+const tokenRequest = authSetup.tokenRequest;
+
+// Build an absolute redirect URI using the current window's location and the relative redirect URI from auth setup
+export const getRedirectUri = () => {
+ return window.location.origin + authSetup.msalConfig.auth.redirectUri;
+};
+
+// Get an access token for use with the API server.
+// ID token received when logging in may not be used for this purpose because it has the incorrect audience
+export const getToken = (client: IPublicClientApplication): Promise => {
+ return client
+ .acquireTokenSilent({
+ ...tokenRequest,
+ redirectUri: getRedirectUri()
+ })
+ .catch(error => {
+ console.log(error);
+ return undefined;
+ });
+};
diff --git a/app/frontend/src/components/AnalysisPanel/AnalysisPanel.module.css b/app/frontend/src/components/AnalysisPanel/AnalysisPanel.module.css
new file mode 100644
index 0000000..909ac03
--- /dev/null
+++ b/app/frontend/src/components/AnalysisPanel/AnalysisPanel.module.css
@@ -0,0 +1,6 @@
+.thoughtProcess {
+ font-family: source-code-pro, Menlo, Monaco, Consolas, "Courier New", monospace;
+ word-wrap: break-word;
+ padding-top: 12px;
+ padding-bottom: 12px;
+}
diff --git a/app/frontend/src/components/AnalysisPanel/AnalysisPanel.tsx b/app/frontend/src/components/AnalysisPanel/AnalysisPanel.tsx
new file mode 100644
index 0000000..4b99a41
--- /dev/null
+++ b/app/frontend/src/components/AnalysisPanel/AnalysisPanel.tsx
@@ -0,0 +1,57 @@
+import { Pivot, PivotItem } from "@fluentui/react";
+import DOMPurify from "dompurify";
+
+import styles from "./AnalysisPanel.module.css";
+
+import { SupportingContent } from "../SupportingContent";
+import { ChatAppResponse } from "../../api";
+import { AnalysisPanelTabs } from "./AnalysisPanelTabs";
+
+interface Props {
+ className: string;
+ activeTab: AnalysisPanelTabs;
+ onActiveTabChanged: (tab: AnalysisPanelTabs) => void;
+ activeCitation: string | undefined;
+ citationHeight: string;
+ answer: ChatAppResponse;
+}
+
+const pivotItemDisabledStyle = { disabled: true, style: { color: "grey" } };
+
+export const AnalysisPanel = ({ answer, activeTab, activeCitation, citationHeight, className, onActiveTabChanged }: Props) => {
+ const isDisabledThoughtProcessTab: boolean = !answer.choices[0].context.thoughts;
+ const isDisabledSupportingContentTab: boolean = !answer.choices[0].context.data_points.length;
+ const isDisabledCitationTab: boolean = !activeCitation;
+
+ const sanitizedThoughts = DOMPurify.sanitize(answer.choices[0].context.thoughts!);
+
+ return (
+ pivotItem && onActiveTabChanged(pivotItem.props.itemKey! as AnalysisPanelTabs)}
+ >
+
+
+
+
+
+
+
+
+
+
+ );
+};
diff --git a/app/frontend/src/components/AnalysisPanel/AnalysisPanelTabs.tsx b/app/frontend/src/components/AnalysisPanel/AnalysisPanelTabs.tsx
new file mode 100644
index 0000000..dc2e9eb
--- /dev/null
+++ b/app/frontend/src/components/AnalysisPanel/AnalysisPanelTabs.tsx
@@ -0,0 +1,5 @@
+export enum AnalysisPanelTabs {
+ ThoughtProcessTab = "thoughtProcess",
+ SupportingContentTab = "supportingContent",
+ CitationTab = "citation"
+}
diff --git a/app/frontend/src/components/AnalysisPanel/index.tsx b/app/frontend/src/components/AnalysisPanel/index.tsx
new file mode 100644
index 0000000..d2aa7d7
--- /dev/null
+++ b/app/frontend/src/components/AnalysisPanel/index.tsx
@@ -0,0 +1,2 @@
+export * from "./AnalysisPanel";
+export * from "./AnalysisPanelTabs";
diff --git a/app/frontend/src/components/Answer/Answer.module.css b/app/frontend/src/components/Answer/Answer.module.css
new file mode 100644
index 0000000..782f05d
--- /dev/null
+++ b/app/frontend/src/components/Answer/Answer.module.css
@@ -0,0 +1,137 @@
+.answerContainer {
+ padding: 20px;
+ background: rgb(249, 249, 249);
+ border-radius: 8px;
+ box-shadow:
+ 0px 2px 4px rgba(0, 0, 0, 0.14),
+ 0px 0px 2px rgba(0, 0, 0, 0.12);
+ outline: transparent solid 1px;
+}
+
+.answerLogo {
+ font-size: 28px;
+}
+
+.answerText {
+ font-size: 16px;
+ font-weight: 400;
+ line-height: 22px;
+ padding-top: 16px;
+ padding-bottom: 16px;
+ white-space: pre-line;
+}
+
+.answerText table {
+ border-collapse: collapse;
+}
+
+.answerText td,
+.answerText th {
+ border: 1px solid;
+ padding: 5px;
+}
+
+.selected {
+ outline: 2px solid rgba(115, 118, 225, 1);
+}
+
+.citationLearnMore {
+ margin-right: 5px;
+ font-weight: 600;
+ line-height: 24px;
+}
+
+.citation {
+ font-weight: 500;
+ line-height: 24px;
+ text-align: center;
+ border-radius: 4px;
+ padding: 0px 8px;
+ background: #d1dbfa;
+ color: #123bb6;
+ text-decoration: none;
+ cursor: pointer;
+}
+
+.citation:hover {
+ text-decoration: underline;
+}
+
+.followupQuestionsList {
+ margin-top: 10px;
+}
+
+.followupQuestionLearnMore {
+ margin-right: 5px;
+ font-weight: 600;
+ line-height: 24px;
+}
+
+.followupQuestion {
+ font-weight: 600;
+ line-height: 24px;
+ text-align: center;
+ border-radius: 4px;
+ padding: 0px 8px;
+ background: #e8ebfa;
+ color: black;
+ font-style: italic;
+ text-decoration: none;
+ cursor: pointer;
+}
+
+.supContainer {
+ text-decoration: none;
+ cursor: pointer;
+}
+
+.supContainer:hover {
+ text-decoration: underline;
+}
+
+sup {
+ position: relative;
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ font-size: 10px;
+ font-weight: 600;
+ vertical-align: top;
+ top: -1;
+ margin: 0px 2px;
+ min-width: 14px;
+ height: 14px;
+ border-radius: 3px;
+ background: #d1dbfa;
+ color: #123bb6;
+ text-decoration-color: transparent;
+ outline: transparent solid 1px;
+ cursor: pointer;
+}
+
+.retryButton {
+ width: fit-content;
+}
+
+@keyframes loading {
+ 0% {
+ content: "";
+ }
+ 25% {
+ content: ".";
+ }
+ 50% {
+ content: "..";
+ }
+ 75% {
+ content: "...";
+ }
+ 100% {
+ content: "";
+ }
+}
+
+.loadingdots::after {
+ content: "";
+ animation: loading 1s infinite;
+}
diff --git a/app/frontend/src/components/Answer/Answer.tsx b/app/frontend/src/components/Answer/Answer.tsx
new file mode 100644
index 0000000..b79e806
--- /dev/null
+++ b/app/frontend/src/components/Answer/Answer.tsx
@@ -0,0 +1,99 @@
+import { useMemo } from "react";
+import { Stack, IconButton } from "@fluentui/react";
+import DOMPurify from "dompurify";
+
+import styles from "./Answer.module.css";
+
+import { ChatAppResponse, getCitationFilePath } from "../../api";
+import { parseAnswerToHtml } from "./AnswerParser";
+import { AnswerIcon } from "./AnswerIcon";
+
+interface Props {
+ answer: ChatAppResponse;
+ isSelected?: boolean;
+ isStreaming: boolean;
+ onCitationClicked: (filePath: string) => void;
+ onThoughtProcessClicked: () => void;
+ onSupportingContentClicked: () => void;
+ onFollowupQuestionClicked?: (question: string) => void;
+ showFollowupQuestions?: boolean;
+}
+
+export const Answer = ({
+ answer,
+ isSelected,
+ isStreaming,
+ onCitationClicked,
+ onThoughtProcessClicked,
+ onSupportingContentClicked,
+ onFollowupQuestionClicked,
+ showFollowupQuestions
+}: Props) => {
+ const messageContent = answer.choices[0].message.content;
+ const parsedAnswer = useMemo(() => parseAnswerToHtml(messageContent, isStreaming, onCitationClicked), [answer]);
+
+ const sanitizedAnswerHtml = DOMPurify.sanitize(parsedAnswer.answerHtml);
+
+ return (
+
+
+
+
+
+ onThoughtProcessClicked()}
+ disabled={!answer.choices[0].context.thoughts?.length}
+ />
+ onSupportingContentClicked()}
+ disabled={!answer.choices[0].context.data_points?.length}
+ />
+
+
+
+
+
+
+
+
+ {!!parsedAnswer.citations.length && (
+
+
+ Citations:
+ {parsedAnswer.citations.map((x, i) => {
+ const path = getCitationFilePath(x);
+ return (
+ onCitationClicked(path)}>
+ {`${++i}. ${x}`}
+
+ );
+ })}
+
+
+ )}
+
+ {!!parsedAnswer.followupQuestions.length && showFollowupQuestions && onFollowupQuestionClicked && (
+
+
+ Follow-up questions:
+ {parsedAnswer.followupQuestions.map((x, i) => {
+ return (
+ onFollowupQuestionClicked(x)}>
+ {`${x}`}
+
+ );
+ })}
+
+
+ )}
+
+ );
+};
diff --git a/app/frontend/src/components/Answer/AnswerError.tsx b/app/frontend/src/components/Answer/AnswerError.tsx
new file mode 100644
index 0000000..49d3d2d
--- /dev/null
+++ b/app/frontend/src/components/Answer/AnswerError.tsx
@@ -0,0 +1,23 @@
+import { Stack, PrimaryButton } from "@fluentui/react";
+import { ErrorCircle24Regular } from "@fluentui/react-icons";
+
+import styles from "./Answer.module.css";
+
+interface Props {
+ error: string;
+ onRetry: () => void;
+}
+
+export const AnswerError = ({ error, onRetry }: Props) => {
+ return (
+
+
+
+
+ {error}
+
+
+
+
+ );
+};
diff --git a/app/frontend/src/components/Answer/AnswerIcon.tsx b/app/frontend/src/components/Answer/AnswerIcon.tsx
new file mode 100644
index 0000000..9ddbc48
--- /dev/null
+++ b/app/frontend/src/components/Answer/AnswerIcon.tsx
@@ -0,0 +1,5 @@
+import { Sparkle28Filled } from "@fluentui/react-icons";
+
+export const AnswerIcon = () => {
+ return ;
+};
diff --git a/app/frontend/src/components/Answer/AnswerLoading.tsx b/app/frontend/src/components/Answer/AnswerLoading.tsx
new file mode 100644
index 0000000..6df192a
--- /dev/null
+++ b/app/frontend/src/components/Answer/AnswerLoading.tsx
@@ -0,0 +1,26 @@
+import { Stack } from "@fluentui/react";
+import { animated, useSpring } from "@react-spring/web";
+
+import styles from "./Answer.module.css";
+import { AnswerIcon } from "./AnswerIcon";
+
+export const AnswerLoading = () => {
+ const animatedStyles = useSpring({
+ from: { opacity: 0 },
+ to: { opacity: 1 }
+ });
+
+ return (
+
+
+
+
+
+ Generating answer
+
+
+
+
+
+ );
+};
diff --git a/app/frontend/src/components/Answer/AnswerParser.tsx b/app/frontend/src/components/Answer/AnswerParser.tsx
new file mode 100644
index 0000000..bf09a61
--- /dev/null
+++ b/app/frontend/src/components/Answer/AnswerParser.tsx
@@ -0,0 +1,67 @@
+import { renderToStaticMarkup } from "react-dom/server";
+import { getCitationFilePath } from "../../api";
+
+type HtmlParsedAnswer = {
+ answerHtml: string;
+ citations: string[];
+ followupQuestions: string[];
+};
+
+export function parseAnswerToHtml(answer: string, isStreaming: boolean, onCitationClicked: (citationFilePath: string) => void): HtmlParsedAnswer {
+ const citations: string[] = [];
+ const followupQuestions: string[] = [];
+
+ // Extract any follow-up questions that might be in the answer
+ let parsedAnswer = answer.replace(/<<([^>>]+)>>/g, (match, content) => {
+ followupQuestions.push(content);
+ return "";
+ });
+
+ // trim any whitespace from the end of the answer after removing follow-up questions
+ parsedAnswer = parsedAnswer.trim();
+
+ // Omit a citation that is still being typed during streaming
+ if (isStreaming) {
+ let lastIndex = parsedAnswer.length;
+ for (let i = parsedAnswer.length - 1; i >= 0; i--) {
+ if (parsedAnswer[i] === "]") {
+ break;
+ } else if (parsedAnswer[i] === "[") {
+ lastIndex = i;
+ break;
+ }
+ }
+ const truncatedAnswer = parsedAnswer.substring(0, lastIndex);
+ parsedAnswer = truncatedAnswer;
+ }
+
+ const parts = parsedAnswer.split(/\[([^\]]+)\]/g);
+
+ const fragments: string[] = parts.map((part, index) => {
+ if (index % 2 === 0) {
+ return part;
+ } else {
+ let citationIndex: number;
+ if (citations.indexOf(part) !== -1) {
+ citationIndex = citations.indexOf(part) + 1;
+ } else {
+ citations.push(part);
+ citationIndex = citations.length;
+ }
+
+ const path = getCitationFilePath(part);
+
+ return renderToStaticMarkup(
+ onCitationClicked(path)}>
+ {citationIndex}
+
+ );
+ }
+ });
+
+ return {
+ answerHtml: fragments.join(""),
+ citations,
+ followupQuestions
+ };
+}
diff --git a/app/frontend/src/components/Answer/index.ts b/app/frontend/src/components/Answer/index.ts
new file mode 100644
index 0000000..bb45d5b
--- /dev/null
+++ b/app/frontend/src/components/Answer/index.ts
@@ -0,0 +1,3 @@
+export * from "./Answer";
+export * from "./AnswerLoading";
+export * from "./AnswerError";
diff --git a/app/frontend/src/components/ClearChatButton/ClearChatButton.module.css b/app/frontend/src/components/ClearChatButton/ClearChatButton.module.css
new file mode 100644
index 0000000..fb533bf
--- /dev/null
+++ b/app/frontend/src/components/ClearChatButton/ClearChatButton.module.css
@@ -0,0 +1,6 @@
+.container {
+ display: flex;
+ align-items: center;
+ gap: 6px;
+ cursor: pointer;
+}
diff --git a/app/frontend/src/components/ClearChatButton/ClearChatButton.tsx b/app/frontend/src/components/ClearChatButton/ClearChatButton.tsx
new file mode 100644
index 0000000..19a24a6
--- /dev/null
+++ b/app/frontend/src/components/ClearChatButton/ClearChatButton.tsx
@@ -0,0 +1,20 @@
+import { Delete24Regular } from "@fluentui/react-icons";
+import { Button } from "@fluentui/react-components";
+
+import styles from "./ClearChatButton.module.css";
+
+interface Props {
+ className?: string;
+ onClick: () => void;
+ disabled?: boolean;
+}
+
+export const ClearChatButton = ({ className, disabled, onClick }: Props) => {
+ return (
+
+ } disabled={disabled} onClick={onClick}>
+ {"Clear chat"}
+
+
+ );
+};
diff --git a/app/frontend/src/components/ClearChatButton/index.tsx b/app/frontend/src/components/ClearChatButton/index.tsx
new file mode 100644
index 0000000..c283e71
--- /dev/null
+++ b/app/frontend/src/components/ClearChatButton/index.tsx
@@ -0,0 +1 @@
+export * from "./ClearChatButton";
diff --git a/app/frontend/src/components/Example/Example.module.css b/app/frontend/src/components/Example/Example.module.css
new file mode 100644
index 0000000..2911450
--- /dev/null
+++ b/app/frontend/src/components/Example/Example.module.css
@@ -0,0 +1,41 @@
+.examplesNavList {
+ list-style: none;
+ padding-left: 0;
+ display: flex;
+ flex-wrap: wrap;
+ gap: 10px;
+ flex: 1;
+ justify-content: center;
+}
+
+.example {
+ word-break: break-word;
+ background: #dbdbdb;
+ border-radius: 8px;
+ display: flex;
+ flex-direction: column;
+ padding: 20px;
+ margin-bottom: 5px;
+ cursor: pointer;
+}
+
+.example:hover {
+ box-shadow:
+ 0px 8px 16px rgba(0, 0, 0, 0.14),
+ 0px 0px 2px rgba(0, 0, 0, 0.12);
+ outline: 2px solid rgba(115, 118, 225, 1);
+}
+
+.exampleText {
+ margin: 0;
+ font-size: 22px;
+ width: 280px;
+ height: 100px;
+}
+
+@media only screen and (max-height: 780px) {
+ .exampleText {
+ font-size: 20px;
+ height: 80px;
+ }
+}
diff --git a/app/frontend/src/components/Example/Example.tsx b/app/frontend/src/components/Example/Example.tsx
new file mode 100644
index 0000000..82f01d3
--- /dev/null
+++ b/app/frontend/src/components/Example/Example.tsx
@@ -0,0 +1,15 @@
+import styles from "./Example.module.css";
+
+interface Props {
+ text: string;
+ value: string;
+ onClick: (value: string) => void;
+}
+
+export const Example = ({ text, value, onClick }: Props) => {
+ return (
+ onClick(value)}>
+
{text}
+
+ );
+};
diff --git a/app/frontend/src/components/Example/ExampleList.tsx b/app/frontend/src/components/Example/ExampleList.tsx
new file mode 100644
index 0000000..c592d1d
--- /dev/null
+++ b/app/frontend/src/components/Example/ExampleList.tsx
@@ -0,0 +1,30 @@
+import { Example } from "./Example";
+
+import styles from "./Example.module.css";
+
+export type ExampleModel = {
+ text: string;
+ value: string;
+};
+
+const EXAMPLES: ExampleModel[] = [
+ { text: "I want to pay a bill", value: "I want to pay a bill"},
+ { text: "When did I last pay my plumber?", value: "When did I last pay my plumber" },
+ { text: "Pay Bill the plumber as last time", value: "Pay Bill the plumber as last time" }
+];
+
+interface Props {
+ onExampleClicked: (value: string) => void;
+}
+
+export const ExampleList = ({ onExampleClicked }: Props) => {
+ return (
+
+ {EXAMPLES.map((x, i) => (
+
+
+
+ ))}
+
+ );
+};
diff --git a/app/frontend/src/components/Example/index.tsx b/app/frontend/src/components/Example/index.tsx
new file mode 100644
index 0000000..b6ce63c
--- /dev/null
+++ b/app/frontend/src/components/Example/index.tsx
@@ -0,0 +1,2 @@
+export * from "./Example";
+export * from "./ExampleList";
diff --git a/app/frontend/src/components/LoginButton/LoginButton.module.css b/app/frontend/src/components/LoginButton/LoginButton.module.css
new file mode 100644
index 0000000..f808ac9
--- /dev/null
+++ b/app/frontend/src/components/LoginButton/LoginButton.module.css
@@ -0,0 +1,5 @@
+.loginButton {
+ border-radius: 5px;
+ padding: 30px 30px;
+ font-weight: 100;
+}
diff --git a/app/frontend/src/components/LoginButton/LoginButton.tsx b/app/frontend/src/components/LoginButton/LoginButton.tsx
new file mode 100644
index 0000000..7378ecf
--- /dev/null
+++ b/app/frontend/src/components/LoginButton/LoginButton.tsx
@@ -0,0 +1,39 @@
+import { DefaultButton } from "@fluentui/react";
+import { useMsal } from "@azure/msal-react";
+
+import styles from "./LoginButton.module.css";
+import { getRedirectUri, loginRequest } from "../../authConfig";
+
+export const LoginButton = () => {
+ const { instance } = useMsal();
+ const activeAccount = instance.getActiveAccount();
+ const handleLoginPopup = () => {
+ /**
+ * When using popup and silent APIs, we recommend setting the redirectUri to a blank page or a page
+ * that does not implement MSAL. Keep in mind that all redirect routes must be registered with the application
+ * For more information, please follow this link: https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-browser/docs/login-user.md#redirecturi-considerations
+ */
+ instance
+ .loginPopup({
+ ...loginRequest,
+ redirectUri: getRedirectUri()
+ })
+ .catch(error => console.log(error));
+ };
+ const handleLogoutPopup = () => {
+ instance
+ .logoutPopup({
+ mainWindowRedirectUri: "/", // redirects the top level app after logout
+ account: instance.getActiveAccount()
+ })
+ .catch(error => console.log(error));
+ };
+ const logoutText = `Logout\n${activeAccount?.username}`;
+ return (
+
+ );
+};
diff --git a/app/frontend/src/components/LoginButton/index.tsx b/app/frontend/src/components/LoginButton/index.tsx
new file mode 100644
index 0000000..06a844c
--- /dev/null
+++ b/app/frontend/src/components/LoginButton/index.tsx
@@ -0,0 +1 @@
+export * from "./LoginButton";
diff --git a/app/frontend/src/components/QuestionInput/QuestionInput.module.css b/app/frontend/src/components/QuestionInput/QuestionInput.module.css
new file mode 100644
index 0000000..419523e
--- /dev/null
+++ b/app/frontend/src/components/QuestionInput/QuestionInput.module.css
@@ -0,0 +1,21 @@
+.questionInputContainer {
+ border-radius: 8px;
+ box-shadow:
+ 0px 8px 16px rgba(0, 0, 0, 0.14),
+ 0px 0px 2px rgba(0, 0, 0, 0.12);
+ height: 90px;
+ width: 100%;
+ padding: 15px;
+ background: white;
+}
+
+.questionInputTextArea {
+ width: 100%;
+ line-height: 40px;
+}
+
+.questionInputButtonsContainer {
+ display: flex;
+ flex-direction: column;
+ justify-content: flex-end;
+}
diff --git a/app/frontend/src/components/QuestionInput/QuestionInput.tsx b/app/frontend/src/components/QuestionInput/QuestionInput.tsx
new file mode 100644
index 0000000..1bc69cc
--- /dev/null
+++ b/app/frontend/src/components/QuestionInput/QuestionInput.tsx
@@ -0,0 +1,66 @@
+import { useState } from "react";
+import { Stack, TextField } from "@fluentui/react";
+import { Button, Tooltip, Field, Textarea } from "@fluentui/react-components";
+import { Send28Filled } from "@fluentui/react-icons";
+
+import styles from "./QuestionInput.module.css";
+
+interface Props {
+ onSend: (question: string) => void;
+ disabled: boolean;
+ placeholder?: string;
+ clearOnSend?: boolean;
+}
+
+export const QuestionInput = ({ onSend, disabled, placeholder, clearOnSend }: Props) => {
+ const [question, setQuestion] = useState("");
+
+ const sendQuestion = () => {
+ if (disabled || !question.trim()) {
+ return;
+ }
+
+ onSend(question);
+
+ if (clearOnSend) {
+ setQuestion("");
+ }
+ };
+
+ const onEnterPress = (ev: React.KeyboardEvent) => {
+ if (ev.key === "Enter" && !ev.shiftKey) {
+ ev.preventDefault();
+ sendQuestion();
+ }
+ };
+
+ const onQuestionChange = (_ev: React.FormEvent, newValue?: string) => {
+ if (!newValue) {
+ setQuestion("");
+ } else if (newValue.length <= 1000) {
+ setQuestion(newValue);
+ }
+ };
+
+ const sendQuestionDisabled = disabled || !question.trim();
+
+ return (
+
+
+
+
+ } disabled={sendQuestionDisabled} onClick={sendQuestion} />
+
+
+
+ );
+};
diff --git a/app/frontend/src/components/QuestionInput/index.ts b/app/frontend/src/components/QuestionInput/index.ts
new file mode 100644
index 0000000..964f611
--- /dev/null
+++ b/app/frontend/src/components/QuestionInput/index.ts
@@ -0,0 +1 @@
+export * from "./QuestionInput";
diff --git a/app/frontend/src/components/SettingsButton/SettingsButton.module.css b/app/frontend/src/components/SettingsButton/SettingsButton.module.css
new file mode 100644
index 0000000..fb533bf
--- /dev/null
+++ b/app/frontend/src/components/SettingsButton/SettingsButton.module.css
@@ -0,0 +1,6 @@
+.container {
+ display: flex;
+ align-items: center;
+ gap: 6px;
+ cursor: pointer;
+}
diff --git a/app/frontend/src/components/SettingsButton/SettingsButton.tsx b/app/frontend/src/components/SettingsButton/SettingsButton.tsx
new file mode 100644
index 0000000..9dcdd5f
--- /dev/null
+++ b/app/frontend/src/components/SettingsButton/SettingsButton.tsx
@@ -0,0 +1,19 @@
+import { Settings24Regular } from "@fluentui/react-icons";
+import { Button } from "@fluentui/react-components";
+
+import styles from "./SettingsButton.module.css";
+
+interface Props {
+ className?: string;
+ onClick: () => void;
+}
+
+export const SettingsButton = ({ className, onClick }: Props) => {
+ return (
+
+ } onClick={onClick}>
+ {"Developer settings"}
+
+
+ );
+};
diff --git a/app/frontend/src/components/SettingsButton/index.tsx b/app/frontend/src/components/SettingsButton/index.tsx
new file mode 100644
index 0000000..d17253d
--- /dev/null
+++ b/app/frontend/src/components/SettingsButton/index.tsx
@@ -0,0 +1 @@
+export * from "./SettingsButton";
diff --git a/app/frontend/src/components/SupportingContent/SupportingContent.module.css b/app/frontend/src/components/SupportingContent/SupportingContent.module.css
new file mode 100644
index 0000000..b38d5d9
--- /dev/null
+++ b/app/frontend/src/components/SupportingContent/SupportingContent.module.css
@@ -0,0 +1,30 @@
+.supportingContentNavList {
+ list-style: none;
+ padding-left: 5px;
+ display: flex;
+ flex-direction: column;
+ gap: 10px;
+}
+
+.supportingContentItem {
+ word-break: break-word;
+ background: rgb(249, 249, 249);
+ border-radius: 8px;
+ box-shadow:
+ rgb(0 0 0 / 5%) 0px 0px 0px 1px,
+ rgb(0 0 0 / 10%) 0px 2px 3px 0px;
+ outline: transparent solid 1px;
+
+ display: flex;
+ flex-direction: column;
+ padding: 20px;
+}
+
+.supportingContentItemHeader {
+ margin: 0;
+}
+
+.supportingContentItemText {
+ margin-bottom: 0;
+ font-weight: 300;
+}
diff --git a/app/frontend/src/components/SupportingContent/SupportingContent.tsx b/app/frontend/src/components/SupportingContent/SupportingContent.tsx
new file mode 100644
index 0000000..da6f981
--- /dev/null
+++ b/app/frontend/src/components/SupportingContent/SupportingContent.tsx
@@ -0,0 +1,24 @@
+import { parseSupportingContentItem } from "./SupportingContentParser";
+
+import styles from "./SupportingContent.module.css";
+
+interface Props {
+ supportingContent: string[];
+}
+
+export const SupportingContent = ({ supportingContent }: Props) => {
+ return (
+
+ {supportingContent.map((x, i) => {
+ const parsed = parseSupportingContentItem(x);
+
+ return (
+
+ {parsed.title}
+ {parsed.content}
+
+ );
+ })}
+
+ );
+};
diff --git a/app/frontend/src/components/SupportingContent/SupportingContentParser.ts b/app/frontend/src/components/SupportingContent/SupportingContentParser.ts
new file mode 100644
index 0000000..239d709
--- /dev/null
+++ b/app/frontend/src/components/SupportingContent/SupportingContentParser.ts
@@ -0,0 +1,17 @@
+type ParsedSupportingContentItem = {
+ title: string;
+ content: string;
+};
+
+export function parseSupportingContentItem(item: string): ParsedSupportingContentItem {
+ // Assumes the item starts with the file name followed by : and the content.
+ // Example: "sdp_corporate.pdf: this is the content that follows".
+ const parts = item.split(": ");
+ const title = parts[0];
+ const content = parts.slice(1).join(": ");
+
+ return {
+ title,
+ content
+ };
+}
diff --git a/app/frontend/src/components/SupportingContent/index.ts b/app/frontend/src/components/SupportingContent/index.ts
new file mode 100644
index 0000000..db55f83
--- /dev/null
+++ b/app/frontend/src/components/SupportingContent/index.ts
@@ -0,0 +1 @@
+export * from "./SupportingContent";
diff --git a/app/frontend/src/components/TokenClaimsDisplay/TokenClaimsDisplay.tsx b/app/frontend/src/components/TokenClaimsDisplay/TokenClaimsDisplay.tsx
new file mode 100644
index 0000000..53035a1
--- /dev/null
+++ b/app/frontend/src/components/TokenClaimsDisplay/TokenClaimsDisplay.tsx
@@ -0,0 +1,77 @@
+import { Label } from "@fluentui/react";
+import { useMsal } from "@azure/msal-react";
+import {
+ DataGridBody,
+ DataGridRow,
+ DataGrid,
+ DataGridHeader,
+ DataGridHeaderCell,
+ DataGridCell,
+ createTableColumn,
+ TableColumnDefinition
+} from "@fluentui/react-table";
+
+type Claim = {
+ name: string;
+ value: string;
+};
+
+export const TokenClaimsDisplay = () => {
+ const { instance } = useMsal();
+ const activeAccount = instance.getActiveAccount();
+
+ const ToString = (a: string | any) => {
+ if (typeof a === "string") {
+ return a;
+ } else {
+ return JSON.stringify(a);
+ }
+ };
+
+ const items: Claim[] = activeAccount?.idTokenClaims
+ ? Object.keys(activeAccount.idTokenClaims).map((key: string) => {
+ return { name: key, value: ToString((activeAccount.idTokenClaims ?? {})[key]) };
+ })
+ : [];
+
+ const columns: TableColumnDefinition[] = [
+ createTableColumn({
+ columnId: "name",
+ compare: (a: Claim, b: Claim) => {
+ return a.name.localeCompare(b.name);
+ },
+ renderHeaderCell: () => {
+ return "Name";
+ },
+ renderCell: item => {
+ return item.name;
+ }
+ }),
+ createTableColumn({
+ columnId: "value",
+ compare: (a: Claim, b: Claim) => {
+ return a.value.localeCompare(b.value);
+ },
+ renderHeaderCell: () => {
+ return "Value";
+ },
+ renderCell: item => {
+ return item.value;
+ }
+ })
+ ];
+
+ return (
+
+ ID Token Claims
+ item.name}>
+
+ {({ renderHeaderCell }) => {renderHeaderCell()} }
+
+ >
+ {({ item, rowId }) => key={rowId}>{({ renderCell }) => {renderCell(item)} } }
+
+
+
+ );
+};
diff --git a/app/frontend/src/components/TokenClaimsDisplay/index.tsx b/app/frontend/src/components/TokenClaimsDisplay/index.tsx
new file mode 100644
index 0000000..baec9b5
--- /dev/null
+++ b/app/frontend/src/components/TokenClaimsDisplay/index.tsx
@@ -0,0 +1 @@
+export * from "./TokenClaimsDisplay";
diff --git a/app/frontend/src/components/UserChatMessage/UserChatMessage.module.css b/app/frontend/src/components/UserChatMessage/UserChatMessage.module.css
new file mode 100644
index 0000000..591f314
--- /dev/null
+++ b/app/frontend/src/components/UserChatMessage/UserChatMessage.module.css
@@ -0,0 +1,17 @@
+.container {
+ display: flex;
+ justify-content: flex-end;
+ margin-bottom: 20px;
+ max-width: 80%;
+ margin-left: auto;
+}
+
+.message {
+ padding: 20px;
+ background: #e8ebfa;
+ border-radius: 8px;
+ box-shadow:
+ 0px 2px 4px rgba(0, 0, 0, 0.14),
+ 0px 0px 2px rgba(0, 0, 0, 0.12);
+ outline: transparent solid 1px;
+}
diff --git a/app/frontend/src/components/UserChatMessage/UserChatMessage.tsx b/app/frontend/src/components/UserChatMessage/UserChatMessage.tsx
new file mode 100644
index 0000000..2f5e8d3
--- /dev/null
+++ b/app/frontend/src/components/UserChatMessage/UserChatMessage.tsx
@@ -0,0 +1,13 @@
+import styles from "./UserChatMessage.module.css";
+
+interface Props {
+ message: string;
+}
+
+export const UserChatMessage = ({ message }: Props) => {
+ return (
+
+ );
+};
diff --git a/app/frontend/src/components/UserChatMessage/index.ts b/app/frontend/src/components/UserChatMessage/index.ts
new file mode 100644
index 0000000..f2dae12
--- /dev/null
+++ b/app/frontend/src/components/UserChatMessage/index.ts
@@ -0,0 +1 @@
+export * from "./UserChatMessage";
diff --git a/app/frontend/src/index.css b/app/frontend/src/index.css
new file mode 100644
index 0000000..44e9bf2
--- /dev/null
+++ b/app/frontend/src/index.css
@@ -0,0 +1,33 @@
+* {
+ box-sizing: border-box;
+}
+
+html,
+body {
+ height: 100%;
+ margin: 0;
+ padding: 0;
+}
+
+html {
+ background: #f2f2f2;
+
+ font-family:
+ "Segoe UI",
+ -apple-system,
+ BlinkMacSystemFont,
+ "Roboto",
+ "Oxygen",
+ "Ubuntu",
+ "Cantarell",
+ "Fira Sans",
+ "Droid Sans",
+ "Helvetica Neue",
+ sans-serif;
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+}
+
+#root {
+ height: 100%;
+}
diff --git a/app/frontend/src/index.tsx b/app/frontend/src/index.tsx
new file mode 100644
index 0000000..d0c06c3
--- /dev/null
+++ b/app/frontend/src/index.tsx
@@ -0,0 +1,68 @@
+import React from "react";
+import ReactDOM from "react-dom/client";
+import { createHashRouter, RouterProvider } from "react-router-dom";
+import { initializeIcons } from "@fluentui/react";
+import { MsalProvider } from "@azure/msal-react";
+import { PublicClientApplication, EventType, AccountInfo } from "@azure/msal-browser";
+import { msalConfig, useLogin } from "./authConfig";
+
+import "./index.css";
+
+import Layout from "./pages/layout/Layout";
+import Chat from "./pages/chat/Chat";
+
+var layout;
+if (useLogin) {
+ var msalInstance = new PublicClientApplication(msalConfig);
+
+ // Default to using the first account if no account is active on page load
+ if (!msalInstance.getActiveAccount() && msalInstance.getAllAccounts().length > 0) {
+ // Account selection logic is app dependent. Adjust as needed for different use cases.
+ msalInstance.setActiveAccount(msalInstance.getActiveAccount());
+ }
+
+ // Listen for sign-in event and set active account
+ msalInstance.addEventCallback(event => {
+ if (event.eventType === EventType.LOGIN_SUCCESS && event.payload) {
+ const account = event.payload as AccountInfo;
+ msalInstance.setActiveAccount(account);
+ }
+ });
+
+ layout = (
+
+
+
+ );
+} else {
+ layout = ;
+}
+
+initializeIcons();
+
+const router = createHashRouter([
+ {
+ path: "/",
+ element: layout,
+ children: [
+ {
+ index: true,
+ element:
+ },
+ {
+ path: "qa",
+ lazy: () => import("./pages/oneshot/OneShot")
+ },
+ {
+ path: "*",
+ lazy: () => import("./pages/NoPage")
+ }
+ ]
+ }
+]);
+
+ReactDOM.createRoot(document.getElementById("root") as HTMLElement).render(
+
+
+
+);
diff --git a/app/frontend/src/pages/NoPage.tsx b/app/frontend/src/pages/NoPage.tsx
new file mode 100644
index 0000000..5931719
--- /dev/null
+++ b/app/frontend/src/pages/NoPage.tsx
@@ -0,0 +1,5 @@
+export function Component(): JSX.Element {
+ return 404 ;
+}
+
+Component.displayName = "NoPage";
diff --git a/app/frontend/src/pages/chat/Chat.module.css b/app/frontend/src/pages/chat/Chat.module.css
new file mode 100644
index 0000000..91c9818
--- /dev/null
+++ b/app/frontend/src/pages/chat/Chat.module.css
@@ -0,0 +1,115 @@
+.container {
+ flex: 1;
+ display: flex;
+ flex-direction: column;
+ margin-top: 20px;
+}
+
+.chatRoot {
+ flex: 1;
+ display: flex;
+}
+
+.chatContainer {
+ flex: 1;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ width: 100%;
+}
+
+.chatEmptyState {
+ flex-grow: 1;
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+ max-height: 1024px;
+ padding-top: 60px;
+}
+
+.chatEmptyStateTitle {
+ font-size: 4rem;
+ font-weight: 600;
+ margin-top: 0;
+ margin-bottom: 30px;
+}
+
+.chatEmptyStateSubtitle {
+ font-weight: 600;
+ margin-bottom: 10px;
+}
+
+@media only screen and (max-height: 780px) {
+ .chatEmptyState {
+ padding-top: 0;
+ }
+
+ .chatEmptyStateTitle {
+ font-size: 3rem;
+ margin-bottom: 0px;
+ }
+}
+
+.chatMessageStream {
+ flex-grow: 1;
+ max-height: 1024px;
+ max-width: 1028px;
+ width: 100%;
+ overflow-y: auto;
+ padding-left: 24px;
+ padding-right: 24px;
+ display: flex;
+ flex-direction: column;
+}
+
+.chatMessageGpt {
+ margin-bottom: 20px;
+ max-width: 80%;
+ display: flex;
+ min-width: 500px;
+}
+
+.chatMessageGptMinWidth {
+ max-width: 500px;
+ margin-bottom: 20px;
+}
+
+.chatInput {
+ position: sticky;
+ bottom: 0;
+ flex: 0 0 100px;
+ padding-top: 12px;
+ padding-bottom: 24px;
+ padding-left: 24px;
+ padding-right: 24px;
+ width: 100%;
+ max-width: 1028px;
+ background: #f2f2f2;
+}
+
+.chatAnalysisPanel {
+ flex: 1;
+ overflow-y: auto;
+ max-height: 89vh;
+ margin-left: 20px;
+ margin-right: 20px;
+}
+
+.chatSettingsSeparator {
+ margin-top: 15px;
+}
+
+.loadingLogo {
+ font-size: 28px;
+}
+
+.commandsContainer {
+ display: flex;
+ align-self: flex-end;
+}
+
+.commandButton {
+ margin-right: 20px;
+ margin-bottom: 20px;
+}
diff --git a/app/frontend/src/pages/chat/Chat.tsx b/app/frontend/src/pages/chat/Chat.tsx
new file mode 100644
index 0000000..6116c38
--- /dev/null
+++ b/app/frontend/src/pages/chat/Chat.tsx
@@ -0,0 +1,474 @@
+import { useRef, useState, useEffect } from "react";
+import { Checkbox, ChoiceGroup, Panel, DefaultButton, TextField, SpinButton, Dropdown, IDropdownOption, IChoiceGroupOption } from "@fluentui/react";
+import { SparkleFilled } from "@fluentui/react-icons";
+import readNDJSONStream from "ndjson-readablestream";
+
+import styles from "./Chat.module.css";
+
+import {
+ chatApi,
+ RetrievalMode,
+ ChatAppResponse,
+ ChatAppResponseOrError,
+ ChatAppRequest,
+ ResponseMessage,
+ Approaches,
+ SKMode
+} from "../../api";
+import { Answer, AnswerError, AnswerLoading } from "../../components/Answer";
+import { QuestionInput } from "../../components/QuestionInput";
+import { ExampleList } from "../../components/Example";
+import { UserChatMessage } from "../../components/UserChatMessage";
+import { AnalysisPanel, AnalysisPanelTabs } from "../../components/AnalysisPanel";
+import { SettingsButton } from "../../components/SettingsButton";
+import { ClearChatButton } from "../../components/ClearChatButton";
+import { useLogin, getToken } from "../../authConfig";
+import { useMsal } from "@azure/msal-react";
+import { TokenClaimsDisplay } from "../../components/TokenClaimsDisplay";
+
+const Chat = () => {
+ const [isConfigPanelOpen, setIsConfigPanelOpen] = useState(false);
+ const [approach, setApproach] = useState(Approaches.JAVA_OPENAI_SDK);
+ const [skMode, setSKMode] = useState(SKMode.Chains);
+ const [promptTemplate, setPromptTemplate] = useState("");
+ const [retrieveCount, setRetrieveCount] = useState(3);
+ const [retrievalMode, setRetrievalMode] = useState(RetrievalMode.Hybrid);
+ const [useSemanticRanker, setUseSemanticRanker] = useState(true);
+ const [shouldStream, setShouldStream] = useState(false);
+ const [streamAvailable, setStreamAvailable] = useState(true);
+ const [useSemanticCaptions, setUseSemanticCaptions] = useState(false);
+ const [excludeCategory, setExcludeCategory] = useState("");
+ const [useSuggestFollowupQuestions, setUseSuggestFollowupQuestions] = useState(false);
+ const [useOidSecurityFilter, setUseOidSecurityFilter] = useState(false);
+ const [useGroupsSecurityFilter, setUseGroupsSecurityFilter] = useState(false);
+
+ const lastQuestionRef = useRef("");
+ const chatMessageStreamEnd = useRef(null);
+
+ const [isLoading, setIsLoading] = useState(false);
+ const [isStreaming, setIsStreaming] = useState(false);
+ const [error, setError] = useState();
+
+ const [activeCitation, setActiveCitation] = useState();
+ const [activeAnalysisPanelTab, setActiveAnalysisPanelTab] = useState(undefined);
+
+ const [selectedAnswer, setSelectedAnswer] = useState(0);
+ const [answers, setAnswers] = useState<[user: string, response: ChatAppResponse][]>([]);
+ const [streamedAnswers, setStreamedAnswers] = useState<[user: string, response: ChatAppResponse][]>([]);
+
+ const handleAsyncRequest = async (question: string, answers: [string, ChatAppResponse][], setAnswers: Function, responseBody: ReadableStream) => {
+ let answer: string = "";
+ let askResponse: ChatAppResponse = {} as ChatAppResponse;
+
+ const updateState = (newContent: string) => {
+ return new Promise(resolve => {
+ setTimeout(() => {
+ answer += newContent;
+ const latestResponse: ChatAppResponse = {
+ ...askResponse,
+ choices: [{ ...askResponse.choices[0], message: { content: answer, role: askResponse.choices[0].message.role } }]
+ };
+ setStreamedAnswers([...answers, [question, latestResponse]]);
+ resolve(null);
+ }, 33);
+ });
+ };
+ try {
+ setIsStreaming(true);
+ for await (const event of readNDJSONStream(responseBody)) {
+ if (event["choices"] && event["choices"][0]["context"] && event["choices"][0]["context"]["data_points"]) {
+ event["choices"][0]["message"] = event["choices"][0]["delta"];
+ askResponse = event;
+ answer = askResponse["choices"][0]["message"]["content"];
+ } else if (event["choices"] && event["choices"][0]["delta"]["content"]) {
+ setIsLoading(false);
+ await updateState(event["choices"][0]["delta"]["content"]);
+ }
+ }
+ } finally {
+ setIsStreaming(false);
+ }
+ const fullResponse: ChatAppResponse = {
+ ...askResponse,
+ choices: [{ ...askResponse.choices[0], message: { content: answer, role: askResponse.choices[0].message.role } }]
+ };
+ return fullResponse;
+ };
+
+ const client = useLogin ? useMsal().instance : undefined;
+
+ const makeApiRequest = async (question: string) => {
+ lastQuestionRef.current = question;
+
+ error && setError(undefined);
+ setIsLoading(true);
+ setActiveCitation(undefined);
+ setActiveAnalysisPanelTab(undefined);
+
+ const token = client ? await getToken(client) : undefined;
+
+ try {
+ const messages: ResponseMessage[] = answers.flatMap(a => [
+ { content: a[0], role: "user" },
+ { content: a[1].choices[0].message.content, role: "assistant" }
+ ]);
+
+ const stream = streamAvailable && shouldStream;
+ const request: ChatAppRequest = {
+ messages: [...messages, { content: question, role: "user" }],
+ stream: stream,
+ context: {
+ overrides: {
+ prompt_template: promptTemplate.length === 0 ? undefined : promptTemplate,
+ exclude_category: excludeCategory.length === 0 ? undefined : excludeCategory,
+ top: retrieveCount,
+ retrieval_mode: retrievalMode,
+ semantic_ranker: useSemanticRanker,
+ semantic_captions: useSemanticCaptions,
+ suggest_followup_questions: useSuggestFollowupQuestions,
+ use_oid_security_filter: useOidSecurityFilter,
+ use_groups_security_filter: useGroupsSecurityFilter,
+ semantic_kernel_mode: skMode
+ }
+ },
+ approach: approach,
+ // ChatAppProtocol: Client must pass on any session state received from the server
+ session_state: answers.length ? answers[answers.length - 1][1].choices[0].session_state : null
+ };
+
+ const response = await chatApi(request, token?.accessToken);
+ if (!response.body) {
+ throw Error("No response body");
+ }
+ if (stream) {
+ const parsedResponse: ChatAppResponse = await handleAsyncRequest(question, answers, setAnswers, response.body);
+ setAnswers([...answers, [question, parsedResponse]]);
+ } else {
+ const parsedResponse: ChatAppResponseOrError = await response.json();
+ if (response.status > 299 || !response.ok) {
+ throw Error(parsedResponse.error || "Unknown error");
+ }
+ setAnswers([...answers, [question, parsedResponse as ChatAppResponse]]);
+ }
+ } catch (e) {
+ setError(e);
+ } finally {
+ setIsLoading(false);
+ }
+ };
+
+ const clearChat = () => {
+ lastQuestionRef.current = "";
+ error && setError(undefined);
+ setActiveCitation(undefined);
+ setActiveAnalysisPanelTab(undefined);
+ setAnswers([]);
+ setStreamedAnswers([]);
+ setIsLoading(false);
+ setIsStreaming(false);
+ };
+
+ useEffect(() => chatMessageStreamEnd.current?.scrollIntoView({ behavior: "smooth" }), [isLoading]);
+ useEffect(() => chatMessageStreamEnd.current?.scrollIntoView({ behavior: "auto" }), [streamedAnswers]);
+
+ const onPromptTemplateChange = (_ev?: React.FormEvent, newValue?: string) => {
+ setPromptTemplate(newValue || "");
+ };
+
+ const onRetrieveCountChange = (_ev?: React.SyntheticEvent, newValue?: string) => {
+ setRetrieveCount(parseInt(newValue || "3"));
+ };
+
+ const onRetrievalModeChange = (_ev: React.FormEvent, option?: IDropdownOption | undefined, index?: number | undefined) => {
+ setRetrievalMode(option?.data || RetrievalMode.Hybrid);
+ };
+
+ const onSKModeChange = (_ev: React.FormEvent, option?: IDropdownOption | undefined, index?: number | undefined) => {
+ setSKMode(option?.data || SKMode.Chains);
+ };
+
+ const onApproachChange = (_ev?: React.FormEvent, option?: IChoiceGroupOption) => {
+ const newApproach = (option?.key as Approaches);
+ setApproach(newApproach || Approaches.JAVA_OPENAI_SDK);
+ setStreamAvailable(newApproach === Approaches.JAVA_OPENAI_SDK);
+ };
+
+ const onUseSemanticRankerChange = (_ev?: React.FormEvent, checked?: boolean) => {
+ setUseSemanticRanker(!!checked);
+ };
+
+ const onUseSemanticCaptionsChange = (_ev?: React.FormEvent, checked?: boolean) => {
+ setUseSemanticCaptions(!!checked);
+ };
+
+ const onShouldStreamChange = (_ev?: React.FormEvent, checked?: boolean) => {
+ setShouldStream(!!checked);
+ };
+
+ const onExcludeCategoryChanged = (_ev?: React.FormEvent, newValue?: string) => {
+ setExcludeCategory(newValue || "");
+ };
+
+ const onUseSuggestFollowupQuestionsChange = (_ev?: React.FormEvent, checked?: boolean) => {
+ setUseSuggestFollowupQuestions(!!checked);
+ };
+
+ const onUseOidSecurityFilterChange = (_ev?: React.FormEvent, checked?: boolean) => {
+ setUseOidSecurityFilter(!!checked);
+ };
+
+ const onUseGroupsSecurityFilterChange = (_ev?: React.FormEvent, checked?: boolean) => {
+ setUseGroupsSecurityFilter(!!checked);
+ };
+
+ const onExampleClicked = (example: string) => {
+ makeApiRequest(example);
+ };
+
+ const onShowCitation = (citation: string, index: number) => {
+ if (activeCitation === citation && activeAnalysisPanelTab === AnalysisPanelTabs.CitationTab && selectedAnswer === index) {
+ setActiveAnalysisPanelTab(undefined);
+ } else {
+ setActiveCitation(citation);
+ setActiveAnalysisPanelTab(AnalysisPanelTabs.CitationTab);
+ }
+
+ setSelectedAnswer(index);
+ };
+
+ const onToggleTab = (tab: AnalysisPanelTabs, index: number) => {
+ if (activeAnalysisPanelTab === tab && selectedAnswer === index) {
+ setActiveAnalysisPanelTab(undefined);
+ } else {
+ setActiveAnalysisPanelTab(tab);
+ }
+
+ setSelectedAnswer(index);
+ };
+
+ const approaches: IChoiceGroupOption[] = [
+ {
+ key: Approaches.JAVA_OPENAI_SDK,
+ text: "Java Azure Open AI SDK"
+ },
+ /* Pending Semantic Kernel Memory implementation in V1.0.0
+ {
+ key: Approaches.JAVA_SEMANTIC_KERNEL,
+ text: "Java Semantic Kernel - Memory"
+ },*/
+ {
+ key: Approaches.JAVA_SEMANTIC_KERNEL_PLANNER,
+ text: "Java Semantic Kernel - Orchestration"
+ }
+ ];
+
+ return (
+
+
+
+
+
+
+
+ {!lastQuestionRef.current ? (
+
+
+
Chat with your personal assistant
+ Ask anything or try an example
+
+
+ ) : (
+
+ {isStreaming &&
+ streamedAnswers.map((streamedAnswer, index) => (
+
+
+
+
onShowCitation(c, index)}
+ onThoughtProcessClicked={() => onToggleTab(AnalysisPanelTabs.ThoughtProcessTab, index)}
+ onSupportingContentClicked={() => onToggleTab(AnalysisPanelTabs.SupportingContentTab, index)}
+ onFollowupQuestionClicked={q => makeApiRequest(q)}
+ showFollowupQuestions={useSuggestFollowupQuestions && answers.length - 1 === index}
+ />
+
+
+ ))}
+ {!isStreaming &&
+ answers.map((answer, index) => (
+
+
+
+
onShowCitation(c, index)}
+ onThoughtProcessClicked={() => onToggleTab(AnalysisPanelTabs.ThoughtProcessTab, index)}
+ onSupportingContentClicked={() => onToggleTab(AnalysisPanelTabs.SupportingContentTab, index)}
+ onFollowupQuestionClicked={q => makeApiRequest(q)}
+ showFollowupQuestions={useSuggestFollowupQuestions && answers.length - 1 === index}
+ />
+
+
+ ))}
+ {isLoading && (
+ <>
+
+
+ >
+ )}
+ {error ? (
+ <>
+
+
+
makeApiRequest(lastQuestionRef.current)} />
+
+ >
+ ) : null}
+
+
+ )}
+
+
+ makeApiRequest(question)}
+ />
+
+
+
+ {answers.length > 0 && activeAnalysisPanelTab && (
+
onToggleTab(x, selectedAnswer)}
+ citationHeight="810px"
+ answer={answers[selectedAnswer][1]}
+ activeTab={activeAnalysisPanelTab}
+ />
+ )}
+
+ setIsConfigPanelOpen(false)}
+ closeButtonAriaLabel="Close"
+ onRenderFooterContent={() => setIsConfigPanelOpen(false)}>Close }
+ isFooterAtBottom={true}
+ >
+
+
+ {(approach === Approaches.JAVA_OPENAI_SDK || approach === Approaches.JAVA_SEMANTIC_KERNEL) && (
+
+ )}
+ {(approach === Approaches.JAVA_SEMANTIC_KERNEL_PLANNER) && (
+
+ )}
+
+
+
+
+
+
+ {useLogin && (
+
+ )}
+ {useLogin && (
+
+ )}
+
+ {streamAvailable &&
+
+ }
+
+ {useLogin && }
+
+
+
+ );
+};
+
+export default Chat;
diff --git a/app/frontend/src/pages/layout/Layout.module.css b/app/frontend/src/pages/layout/Layout.module.css
new file mode 100644
index 0000000..ebb860e
--- /dev/null
+++ b/app/frontend/src/pages/layout/Layout.module.css
@@ -0,0 +1,78 @@
+.layout {
+ display: flex;
+ flex-direction: column;
+ height: 100%;
+}
+
+.header {
+ background-color: #222222;
+ color: #f2f2f2;
+}
+
+.headerContainer {
+ display: flex;
+ align-items: center;
+ justify-content: space-around;
+ margin-right: 12px;
+ margin-left: 12px;
+}
+
+.headerTitleContainer {
+ display: flex;
+ align-items: center;
+ margin-right: 40px;
+ color: #f2f2f2;
+ text-decoration: none;
+}
+
+.headerLogo {
+ height: 40px;
+}
+
+.headerTitle {
+ margin-left: 12px;
+ font-weight: 600;
+}
+
+.headerNavList {
+ display: flex;
+ list-style: none;
+ padding-left: 0;
+}
+
+.headerNavPageLink {
+ color: #f2f2f2;
+ text-decoration: none;
+ opacity: 0.75;
+
+ transition-timing-function: cubic-bezier(0.16, 1, 0.3, 1);
+ transition-duration: 500ms;
+ transition-property: opacity;
+}
+
+.headerNavPageLink:hover {
+ opacity: 1;
+}
+
+.headerNavPageLinkActive {
+ color: #f2f2f2;
+ text-decoration: none;
+}
+
+.headerNavLeftMargin {
+ margin-left: 20px;
+}
+
+.headerRightText {
+ font-weight: normal;
+ margin-left: 40px;
+}
+
+.microsoftLogo {
+ height: 23px;
+ font-weight: 600;
+}
+
+.githubLogo {
+ height: 20px;
+}
diff --git a/app/frontend/src/pages/layout/Layout.tsx b/app/frontend/src/pages/layout/Layout.tsx
new file mode 100644
index 0000000..2d1145e
--- /dev/null
+++ b/app/frontend/src/pages/layout/Layout.tsx
@@ -0,0 +1,51 @@
+import { Outlet, NavLink, Link } from "react-router-dom";
+
+import github from "../../assets/github.svg";
+
+import styles from "./Layout.module.css";
+
+import { useLogin } from "../../authConfig";
+
+import { LoginButton } from "../../components/LoginButton";
+
+const Layout = () => {
+ return (
+
+
+
+
+
GPT + Enterprise data | Java Sample
+
+
+
+
+ (isActive ? styles.headerNavPageLinkActive : styles.headerNavPageLink)}>
+ Chat
+
+
+
+
+
+
+
+
+
+
+
Azure OpenAI + Cognitive Search
+ {useLogin &&
}
+
+
+
+
+
+ );
+};
+
+export default Layout;
diff --git a/app/frontend/src/pages/oneshot/OneShot.module.css b/app/frontend/src/pages/oneshot/OneShot.module.css
new file mode 100644
index 0000000..3d46463
--- /dev/null
+++ b/app/frontend/src/pages/oneshot/OneShot.module.css
@@ -0,0 +1,66 @@
+.oneshotContainer {
+ display: flex;
+ flex: 1;
+ flex-direction: column;
+ align-items: center;
+}
+
+.oneshotTopSection {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ width: 100%;
+}
+
+.oneshotBottomSection {
+ display: flex;
+ flex: 1;
+ flex-wrap: wrap;
+ justify-content: center;
+ align-content: flex-start;
+ width: 100%;
+ margin-top: 20px;
+}
+
+.oneshotTitle {
+ font-size: 4rem;
+ font-weight: 600;
+ margin-top: 130px;
+}
+
+@media only screen and (max-width: 800px) {
+ .oneshotTitle {
+ font-size: 3rem;
+ font-weight: 600;
+ margin-top: 0;
+ }
+}
+
+.oneshotQuestionInput {
+ max-width: 800px;
+ width: 100%;
+ padding-left: 10px;
+ padding-right: 10px;
+}
+
+.oneshotAnswerContainer {
+ max-width: 800px;
+ width: 100%;
+ padding-left: 10px;
+ padding-right: 10px;
+}
+
+.oneshotAnalysisPanel {
+ width: 600px;
+ margin-left: 20px;
+}
+
+.oneshotSettingsSeparator {
+ margin-top: 15px;
+}
+
+.settingsButton {
+ align-self: flex-end;
+ margin-right: 20px;
+ margin-top: 20px;
+}
diff --git a/app/frontend/src/pages/oneshot/OneShot.tsx b/app/frontend/src/pages/oneshot/OneShot.tsx
new file mode 100644
index 0000000..203e2ca
--- /dev/null
+++ b/app/frontend/src/pages/oneshot/OneShot.tsx
@@ -0,0 +1,324 @@
+import { useRef, useState } from "react";
+import { Checkbox, ChoiceGroup, IChoiceGroupOption, Panel, DefaultButton, Spinner, TextField, SpinButton, IDropdownOption, Dropdown } from "@fluentui/react";
+
+import styles from "./OneShot.module.css";
+
+import { askApi, Approaches, ChatAppResponse, RetrievalMode, SKMode, ChatAppRequest } from "../../api";
+import { Answer, AnswerError } from "../../components/Answer";
+import { QuestionInput } from "../../components/QuestionInput";
+import { ExampleList } from "../../components/Example";
+import { AnalysisPanel, AnalysisPanelTabs } from "../../components/AnalysisPanel";
+import { SettingsButton } from "../../components/SettingsButton/SettingsButton";
+import { useLogin, getToken } from "../../authConfig";
+import { useMsal } from "@azure/msal-react";
+import { TokenClaimsDisplay } from "../../components/TokenClaimsDisplay";
+
+export function Component(): JSX.Element {
+ const [isConfigPanelOpen, setIsConfigPanelOpen] = useState(false);
+ const [approach, setApproach] = useState(Approaches.JAVA_OPENAI_SDK);
+ const [promptTemplate, setPromptTemplate] = useState("");
+ const [promptTemplatePrefix, setPromptTemplatePrefix] = useState("");
+ const [promptTemplateSuffix, setPromptTemplateSuffix] = useState("");
+ const [retrievalMode, setRetrievalMode] = useState(RetrievalMode.Hybrid);
+ const [skMode, setSKMode] = useState(SKMode.Chains);
+ const [retrieveCount, setRetrieveCount] = useState(3);
+ const [useSemanticRanker, setUseSemanticRanker] = useState(true);
+ const [useSemanticCaptions, setUseSemanticCaptions] = useState(false);
+ const [excludeCategory, setExcludeCategory] = useState("");
+ const [useOidSecurityFilter, setUseOidSecurityFilter] = useState(false);
+ const [useGroupsSecurityFilter, setUseGroupsSecurityFilter] = useState(false);
+
+ const lastQuestionRef = useRef("");
+
+ const [isLoading, setIsLoading] = useState(false);
+ const [error, setError] = useState();
+ const [answer, setAnswer] = useState();
+
+ const [activeCitation, setActiveCitation] = useState();
+ const [activeAnalysisPanelTab, setActiveAnalysisPanelTab] = useState(undefined);
+
+ const client = useLogin ? useMsal().instance : undefined;
+
+ const makeApiRequest = async (question: string) => {
+ lastQuestionRef.current = question;
+
+ error && setError(undefined);
+ setIsLoading(true);
+ setActiveCitation(undefined);
+ setActiveAnalysisPanelTab(undefined);
+
+ const token = client ? await getToken(client) : undefined;
+
+ try {
+ const request: ChatAppRequest = {
+ messages: [
+ {
+ content: question,
+ role: "user"
+ }
+ ],
+ context: {
+ overrides: {
+ prompt_template: promptTemplate.length === 0 ? undefined : promptTemplate,
+ prompt_template_prefix: promptTemplatePrefix.length === 0 ? undefined : promptTemplatePrefix,
+ prompt_template_suffix: promptTemplateSuffix.length === 0 ? undefined : promptTemplateSuffix,
+ exclude_category: excludeCategory.length === 0 ? undefined : excludeCategory,
+ top: retrieveCount,
+ retrieval_mode: retrievalMode,
+ semantic_ranker: useSemanticRanker,
+ semantic_captions: useSemanticCaptions,
+ use_oid_security_filter: useOidSecurityFilter,
+ use_groups_security_filter: useGroupsSecurityFilter,
+ semantic_kernel_mode: skMode
+ }
+ },
+ approach: approach,
+ // ChatAppProtocol: Client must pass on any session state received from the server
+ session_state: answer ? answer.choices[0].session_state : null
+ };
+ const result = await askApi(request, token?.accessToken);
+ setAnswer(result);
+ } catch (e) {
+ setError(e);
+ } finally {
+ setIsLoading(false);
+ }
+ };
+
+ const onPromptTemplateChange = (_ev?: React.FormEvent, newValue?: string) => {
+ setPromptTemplate(newValue || "");
+ };
+
+ const onPromptTemplatePrefixChange = (_ev?: React.FormEvent, newValue?: string) => {
+ setPromptTemplatePrefix(newValue || "");
+ };
+
+ const onPromptTemplateSuffixChange = (_ev?: React.FormEvent, newValue?: string) => {
+ setPromptTemplateSuffix(newValue || "");
+ };
+
+ const onRetrieveCountChange = (_ev?: React.SyntheticEvent, newValue?: string) => {
+ setRetrieveCount(parseInt(newValue || "3"));
+ };
+
+ const onRetrievalModeChange = (_ev: React.FormEvent, option?: IDropdownOption | undefined, index?: number | undefined) => {
+ setRetrievalMode(option?.data || RetrievalMode.Hybrid);
+ };
+
+ const onSKModeChange = (_ev: React.FormEvent, option?: IDropdownOption | undefined, index?: number | undefined) => {
+ setSKMode(option?.data || SKMode.Chains);
+ };
+
+ const onApproachChange = (_ev?: React.FormEvent, option?: IChoiceGroupOption) => {
+ setApproach((option?.key as Approaches) || Approaches.JAVA_OPENAI_SDK);
+ };
+
+ const onUseSemanticRankerChange = (_ev?: React.FormEvent, checked?: boolean) => {
+ setUseSemanticRanker(!!checked);
+ };
+
+ const onUseSemanticCaptionsChange = (_ev?: React.FormEvent, checked?: boolean) => {
+ setUseSemanticCaptions(!!checked);
+ };
+
+ const onExcludeCategoryChanged = (_ev?: React.FormEvent, newValue?: string) => {
+ setExcludeCategory(newValue || "");
+ };
+
+ const onExampleClicked = (example: string) => {
+ makeApiRequest(example);
+ };
+
+ const onShowCitation = (citation: string) => {
+ if (activeCitation === citation && activeAnalysisPanelTab === AnalysisPanelTabs.CitationTab) {
+ setActiveAnalysisPanelTab(undefined);
+ } else {
+ setActiveCitation(citation);
+ setActiveAnalysisPanelTab(AnalysisPanelTabs.CitationTab);
+ }
+ };
+
+ const onToggleTab = (tab: AnalysisPanelTabs) => {
+ if (activeAnalysisPanelTab === tab) {
+ setActiveAnalysisPanelTab(undefined);
+ } else {
+ setActiveAnalysisPanelTab(tab);
+ }
+ };
+
+ const onUseOidSecurityFilterChange = (_ev?: React.FormEvent, checked?: boolean) => {
+ setUseOidSecurityFilter(!!checked);
+ };
+
+ const onUseGroupsSecurityFilterChange = (_ev?: React.FormEvent, checked?: boolean) => {
+ setUseGroupsSecurityFilter(!!checked);
+ };
+
+ const approaches: IChoiceGroupOption[] = [
+ {
+ key: Approaches.JAVA_OPENAI_SDK,
+ text: "Java Azure Open AI SDK"
+ },
+ /* Pending Semantic Kernel Memory implementation in V1.0.0
+ {
+ key: Approaches.JAVA_SEMANTIC_KERNEL,
+ text: "Java Semantic Kernel - Memory"
+ },
+ */
+ {
+ key: Approaches.JAVA_SEMANTIC_KERNEL_PLANNER,
+ text: "Java Semantic Kernel - Orchestration"
+ }
+ ];
+
+ return (
+
+
+
setIsConfigPanelOpen(!isConfigPanelOpen)} />
+ Ask your data
+
+ makeApiRequest(question)}
+ />
+
+
+
+ {isLoading &&
}
+ {!lastQuestionRef.current &&
}
+ {!isLoading && answer && !error && (
+
+
onShowCitation(x)}
+ onThoughtProcessClicked={() => onToggleTab(AnalysisPanelTabs.ThoughtProcessTab)}
+ onSupportingContentClicked={() => onToggleTab(AnalysisPanelTabs.SupportingContentTab)}
+ />
+
+ )}
+ {error ? (
+
+
makeApiRequest(lastQuestionRef.current)} />
+
+ ) : null}
+ {activeAnalysisPanelTab && answer && (
+
onToggleTab(x)}
+ citationHeight="600px"
+ answer={answer}
+ activeTab={activeAnalysisPanelTab}
+ />
+ )}
+
+
+
setIsConfigPanelOpen(false)}
+ closeButtonAriaLabel="Close"
+ onRenderFooterContent={() => setIsConfigPanelOpen(false)}>Close }
+ isFooterAtBottom={true}
+ >
+
+
+ {(approach === Approaches.JAVA_SEMANTIC_KERNEL_PLANNER) && (
+
+ )}
+ {(approach === Approaches.JAVA_OPENAI_SDK || approach === Approaches.JAVA_SEMANTIC_KERNEL) && (
+
+ )}
+
+
+
+
+
+ {(approach === Approaches.JAVA_OPENAI_SDK || approach === Approaches.JAVA_SEMANTIC_KERNEL_PLANNER) && (
+
+ )}
+ {(approach === Approaches.JAVA_OPENAI_SDK || approach === Approaches.JAVA_SEMANTIC_KERNEL_PLANNER) && (
+
+ )}
+ {(approach === Approaches.JAVA_OPENAI_SDK || approach === Approaches.JAVA_SEMANTIC_KERNEL_PLANNER) && (
+
+ )}
+
+ {useLogin && (
+
+ )}
+ {useLogin && (
+
+ )}
+ {useLogin && }
+
+
+ );
+}
+
+Component.displayName = "OneShot";
diff --git a/app/frontend/src/vite-env.d.ts b/app/frontend/src/vite-env.d.ts
new file mode 100644
index 0000000..11f02fe
--- /dev/null
+++ b/app/frontend/src/vite-env.d.ts
@@ -0,0 +1 @@
+///
diff --git a/app/frontend/tsconfig.json b/app/frontend/tsconfig.json
new file mode 100644
index 0000000..39a545e
--- /dev/null
+++ b/app/frontend/tsconfig.json
@@ -0,0 +1,21 @@
+{
+ "compilerOptions": {
+ "target": "ESNext",
+ "useDefineForClassFields": true,
+ "lib": ["DOM", "DOM.Iterable", "ESNext"],
+ "allowJs": false,
+ "skipLibCheck": true,
+ "esModuleInterop": false,
+ "allowSyntheticDefaultImports": true,
+ "strict": true,
+ "forceConsistentCasingInFileNames": true,
+ "module": "ESNext",
+ "moduleResolution": "Node",
+ "resolveJsonModule": true,
+ "isolatedModules": true,
+ "noEmit": true,
+ "jsx": "react-jsx",
+ "types": ["vite/client"]
+ },
+ "include": ["src"]
+}
diff --git a/app/frontend/vite.config.ts b/app/frontend/vite.config.ts
new file mode 100644
index 0000000..f7f1899
--- /dev/null
+++ b/app/frontend/vite.config.ts
@@ -0,0 +1,46 @@
+import { defineConfig } from "vite";
+import react from "@vitejs/plugin-react";
+
+// https://vitejs.dev/config/
+export default defineConfig({
+ plugins: [react()],
+ build: {
+ outDir: "./build",
+ emptyOutDir: true,
+ sourcemap: true,
+ rollupOptions: {
+ output: {
+ manualChunks: id => {
+ if (id.includes("@fluentui/react-icons")) {
+ return "fluentui-icons";
+ } else if (id.includes("@fluentui/react")) {
+ return "fluentui-react";
+ } else if (id.includes("node_modules")) {
+ return "vendor";
+ }
+ }
+ }
+ },
+ target: "esnext"
+ },
+ server: {
+ proxy: {
+ "/api/ask": {
+ target: 'http://localhost:8080',
+ changeOrigin: true
+ },
+ "/api/chat": {
+ target: 'http://localhost:8080',
+ changeOrigin: true
+ },
+ "/api/content": {
+ target: 'http://localhost:8080',
+ changeOrigin: true
+ },
+ "/api/auth_setup": {
+ target: 'http://localhost:8080',
+ changeOrigin: true
+ }
+ }
+ }
+});
diff --git a/app/package-lock.json b/app/package-lock.json
new file mode 100644
index 0000000..4ca926f
--- /dev/null
+++ b/app/package-lock.json
@@ -0,0 +1,6 @@
+{
+ "name": "app",
+ "lockfileVersion": 3,
+ "requires": true,
+ "packages": {}
+}
diff --git a/app/start-compose.ps1 b/app/start-compose.ps1
new file mode 100644
index 0000000..e9710d5
--- /dev/null
+++ b/app/start-compose.ps1
@@ -0,0 +1,56 @@
+$output = azd -C ..\deploy\aca env get-values
+
+foreach ($line in $output) {
+ $name, $value = $line.Split("=")
+ $value = $value -replace '^\"|\"$'
+ [Environment]::SetEnvironmentVariable($name, $value)
+}
+
+Write-Host "Environment variables set."
+$roles = @(
+ "5e0bd9bd-7b93-4f28-af87-19fc36ad61bd",
+ "a97b65f3-24c7-4388-baec-2e87135dc908",
+ "2a2b9908-6ea1-4ae2-8e65-a410df84e7d1",
+ "ba92f5b4-2d11-453d-a403-e96b0029c9fe",
+ "1407120a-92aa-4202-b7e9-c0e197c71c8f",
+ "8ebe5a00-799e-43f5-93ac-243d3dce84a7",
+ "7ca78c08-252a-4471-8644-bb5ff32d4ba0",
+ "4f6d3b9b-027b-4f4c-9142-0e5a2a2247e0"
+)
+
+# Check if service principal exists
+$servicePrincipal = $(az ad sp list --display-name "azure-ai-chat-java-spi" --query [].appId --output tsv)
+
+if ([string]::IsNullOrEmpty($servicePrincipal)) {
+ Write-Host "Service principal not found. Creating service principal"
+ $servicePrincipal = $(az ad sp create-for-rbac --name "azure-ai-chat-java-spi" --role reader --scopes "/subscriptions/$($env:AZURE_SUBSCRIPTION_ID)/resourceGroups/$($env:AZURE_RESOURCE_GROUP)" --query appId --output tsv)
+ if ($LASTEXITCODE -ne 0) {
+ Write-Host "Failed to create service principal"
+ exit $LASTEXITCODE
+ }
+ $servicePrincipalObjectId = $(az ad sp show --id $servicePrincipal --query id --output tsv)
+ Write-Host "Assigning Roles to service principal azure-ai-chat-java-spi with principal id: $servicePrincipal and object id[$servicePrincipalObjectId]"
+ foreach ($role in $roles) {
+ Write-Host "Assigning Role[$role] to principal id[$servicePrincipal] for resource[/subscriptions/$($env:AZURE_SUBSCRIPTION_ID)/resourceGroups/$($env:AZURE_RESOURCE_GROUP)]"
+ az role assignment create `
+ --role $role `
+ --assignee-object-id $servicePrincipalObjectId `
+ --scope "/subscriptions/$($env:AZURE_SUBSCRIPTION_ID)/resourceGroups/$($env:AZURE_RESOURCE_GROUP)" `
+ --assignee-principal-type ServicePrincipal
+ }
+}
+
+$servicePrincipalPassword = $(az ad sp credential reset --id $servicePrincipal --query password --output tsv)
+$servicePrincipalTenant = $(az ad sp show --id $servicePrincipal --query appOwnerOrganizationId --output tsv)
+
+# Set environment variables
+[Environment]::SetEnvironmentVariable("servicePrincipal", $servicePrincipal)
+[Environment]::SetEnvironmentVariable("servicePrincipalPassword", $servicePrincipalPassword)
+[Environment]::SetEnvironmentVariable("servicePrincipalTenant", $servicePrincipalTenant)
+
+
+Write-Host ""
+Write-Host "Starting solution locally using docker compose."
+Write-Host ""
+
+docker compose -f ./compose.yaml up
\ No newline at end of file
diff --git a/app/start-compose.sh b/app/start-compose.sh
new file mode 100644
index 0000000..acca534
--- /dev/null
+++ b/app/start-compose.sh
@@ -0,0 +1,63 @@
+echo ""
+echo "Loading azd .env file from current environment"
+echo ""
+
+while IFS='=' read -r key value; do
+ value=$(echo "$value" | sed 's/^"//' | sed 's/"$//')
+ export "$key=$value"
+ echo "export $key=$value"
+done <'
+// minimumCount: 1
+// maximumCount: 3
+// }
+// ]
+
+var defaultWorkloadProfile = [
+ {
+ workloadProfileType: 'Consumption'
+ name: 'Consumption'
+ }
+]
+
+var effectiveWorkloadProfiles = workloadProfiles != [] ? concat(defaultWorkloadProfile, workloadProfiles) : defaultWorkloadProfile
+
+resource containerAppsEnvironment 'Microsoft.App/managedEnvironments@2023-04-01-preview' = {
+ name: name
+ location: location
+ tags: tags
+ properties: {
+ zoneRedundant: zoneRedundant
+ appLogsConfiguration: {
+ destination: 'log-analytics'
+ logAnalyticsConfiguration: {
+ customerId: logAnalyticsWorkspace.properties.customerId
+ sharedKey: logAnalyticsWorkspace.listKeys().primarySharedKey
+ }
+ }
+ workloadProfiles: effectiveWorkloadProfiles
+ daprAIInstrumentationKey: daprEnabled && !empty(applicationInsightsName) ? applicationInsights.properties.InstrumentationKey : ''
+ }
+}
+
+resource logAnalyticsWorkspace 'Microsoft.OperationalInsights/workspaces@2022-10-01' existing = {
+ name: logAnalyticsWorkspaceName
+}
+
+resource applicationInsights 'Microsoft.Insights/components@2020-02-02' existing = if (daprEnabled && !empty(applicationInsightsName)) {
+ name: applicationInsightsName
+}
+
+output defaultDomain string = containerAppsEnvironment.properties.defaultDomain
+output id string = containerAppsEnvironment.id
+output name string = containerAppsEnvironment.name
diff --git a/deploy/shared/host/container-apps.bicep b/deploy/shared/host/container-apps.bicep
new file mode 100644
index 0000000..f3f7dad
--- /dev/null
+++ b/deploy/shared/host/container-apps.bicep
@@ -0,0 +1,38 @@
+metadata description = 'Creates an Azure Container Registry and an Azure Container Apps environment.'
+param name string
+param location string = resourceGroup().location
+param tags object = {}
+
+param containerAppsEnvironmentName string
+param containerRegistryName string
+param containerRegistryResourceGroupName string = ''
+param logAnalyticsWorkspaceName string
+param applicationInsightsName string = ''
+
+module containerAppsEnvironment 'container-apps-environment.bicep' = {
+ name: '${name}-container-apps-environment'
+ params: {
+ name: containerAppsEnvironmentName
+ location: location
+ tags: tags
+ logAnalyticsWorkspaceName: logAnalyticsWorkspaceName
+ applicationInsightsName: applicationInsightsName
+ }
+}
+
+module containerRegistry 'container-registry.bicep' = {
+ name: '${name}-container-registry'
+ scope: !empty(containerRegistryResourceGroupName) ? resourceGroup(containerRegistryResourceGroupName) : resourceGroup()
+ params: {
+ name: containerRegistryName
+ location: location
+ tags: tags
+ }
+}
+
+output defaultDomain string = containerAppsEnvironment.outputs.defaultDomain
+output environmentName string = containerAppsEnvironment.outputs.name
+output environmentId string = containerAppsEnvironment.outputs.id
+
+output registryLoginServer string = containerRegistry.outputs.loginServer
+output registryName string = containerRegistry.outputs.name
diff --git a/deploy/shared/host/container-registry.bicep b/deploy/shared/host/container-registry.bicep
new file mode 100644
index 0000000..9c64531
--- /dev/null
+++ b/deploy/shared/host/container-registry.bicep
@@ -0,0 +1,83 @@
+metadata description = 'Creates an Azure Container Registry.'
+param name string
+param location string = resourceGroup().location
+param tags object = {}
+
+@description('Indicates whether admin user is enabled')
+param adminUserEnabled bool = false
+
+@description('Indicates whether anonymous pull is enabled')
+param anonymousPullEnabled bool = false
+
+@description('Indicates whether data endpoint is enabled')
+param dataEndpointEnabled bool = false
+
+@description('Encryption settings')
+param encryption object = {
+ status: 'disabled'
+}
+
+@description('Options for bypassing network rules')
+param networkRuleBypassOptions string = 'AzureServices'
+
+@description('Public network access setting')
+param publicNetworkAccess string = 'Enabled'
+
+@description('SKU settings')
+param sku object = {
+ name: 'Basic'
+}
+
+@description('Zone redundancy setting')
+param zoneRedundancy string = 'Disabled'
+
+@description('The log analytics workspace ID used for logging and monitoring')
+param workspaceId string = ''
+
+// 2022-02-01-preview needed for anonymousPullEnabled
+resource containerRegistry 'Microsoft.ContainerRegistry/registries@2022-02-01-preview' = {
+ name: name
+ location: location
+ tags: tags
+ sku: sku
+ properties: {
+ adminUserEnabled: adminUserEnabled
+ anonymousPullEnabled: anonymousPullEnabled
+ dataEndpointEnabled: dataEndpointEnabled
+ encryption: encryption
+ networkRuleBypassOptions: networkRuleBypassOptions
+ publicNetworkAccess: publicNetworkAccess
+ zoneRedundancy: zoneRedundancy
+ }
+}
+
+// TODO: Update diagnostics to be its own module
+// Blocking issue: https://github.com/Azure/bicep/issues/622
+// Unable to pass in a `resource` scope or unable to use string interpolation in resource types
+resource diagnostics 'Microsoft.Insights/diagnosticSettings@2021-05-01-preview' = if (!empty(workspaceId)) {
+ name: 'registry-diagnostics'
+ scope: containerRegistry
+ properties: {
+ workspaceId: workspaceId
+ logs: [
+ {
+ category: 'ContainerRegistryRepositoryEvents'
+ enabled: true
+ }
+ {
+ category: 'ContainerRegistryLoginEvents'
+ enabled: true
+ }
+ ]
+ metrics: [
+ {
+ category: 'AllMetrics'
+ enabled: true
+ timeGrain: 'PT1M'
+ }
+ ]
+ }
+}
+
+output loginServer string = containerRegistry.properties.loginServer
+output name string = containerRegistry.name
diff --git a/deploy/shared/host/functions.bicep b/deploy/shared/host/functions.bicep
new file mode 100644
index 0000000..7070a2c
--- /dev/null
+++ b/deploy/shared/host/functions.bicep
@@ -0,0 +1,86 @@
+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
diff --git a/deploy/shared/monitor/applicationinsights-dashboard.bicep b/deploy/shared/monitor/applicationinsights-dashboard.bicep
new file mode 100644
index 0000000..d082e66
--- /dev/null
+++ b/deploy/shared/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/deploy/shared/monitor/applicationinsights.bicep b/deploy/shared/monitor/applicationinsights.bicep
new file mode 100644
index 0000000..46e9455
--- /dev/null
+++ b/deploy/shared/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/deploy/shared/monitor/loganalytics.bicep b/deploy/shared/monitor/loganalytics.bicep
new file mode 100644
index 0000000..33f9dc2
--- /dev/null
+++ b/deploy/shared/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/deploy/shared/monitor/monitoring.bicep b/deploy/shared/monitor/monitoring.bicep
new file mode 100644
index 0000000..6bb05b0
--- /dev/null
+++ b/deploy/shared/monitor/monitoring.bicep
@@ -0,0 +1,32 @@
+metadata description = 'Creates an Application Insights instance and a Log Analytics workspace.'
+param logAnalyticsName string
+param applicationInsightsName string
+param applicationInsightsDashboardName string = ''
+param location string = resourceGroup().location
+param tags object = {}
+
+module logAnalytics 'loganalytics.bicep' = {
+ name: 'loganalytics'
+ params: {
+ name: logAnalyticsName
+ location: location
+ tags: tags
+ }
+}
+
+module applicationInsights 'applicationinsights.bicep' = {
+ name: 'applicationinsights'
+ params: {
+ name: applicationInsightsName
+ location: location
+ tags: tags
+ dashboardName: applicationInsightsDashboardName
+ logAnalyticsWorkspaceId: logAnalytics.outputs.id
+ }
+}
+
+output applicationInsightsConnectionString string = applicationInsights.outputs.connectionString
+output applicationInsightsInstrumentationKey string = applicationInsights.outputs.instrumentationKey
+output applicationInsightsName string = applicationInsights.outputs.name
+output logAnalyticsWorkspaceId string = logAnalytics.outputs.id
+output logAnalyticsWorkspaceName string = logAnalytics.outputs.name
diff --git a/deploy/shared/search/search-services.bicep b/deploy/shared/search/search-services.bicep
new file mode 100644
index 0000000..e7747e5
--- /dev/null
+++ b/deploy/shared/search/search-services.bicep
@@ -0,0 +1,63 @@
+metadata description = 'Creates an Azure AI Search instance.'
+param name string
+param location string = resourceGroup().location
+param tags object = {}
+
+param sku object = {
+ name: 'standard'
+}
+
+param authOptions object = {}
+param disableLocalAuth bool = false
+param disabledDataExfiltrationOptions array = []
+param encryptionWithCmk object = {
+ enforcement: 'Unspecified'
+}
+@allowed([
+ 'default'
+ 'highDensity'
+])
+param hostingMode string = 'default'
+param networkRuleSet object = {
+ bypass: 'None'
+ ipRules: []
+}
+param partitionCount int = 1
+@allowed([
+ 'enabled'
+ 'disabled'
+])
+param publicNetworkAccess string = 'enabled'
+param replicaCount int = 1
+@allowed([
+ 'disabled'
+ 'free'
+ 'standard'
+])
+param semanticSearch string = 'disabled'
+
+resource search 'Microsoft.Search/searchServices@2021-04-01-preview' = {
+ name: name
+ location: location
+ tags: tags
+ identity: {
+ type: 'SystemAssigned'
+ }
+ properties: {
+ authOptions: authOptions
+ disableLocalAuth: disableLocalAuth
+ disabledDataExfiltrationOptions: disabledDataExfiltrationOptions
+ encryptionWithCmk: encryptionWithCmk
+ hostingMode: hostingMode
+ networkRuleSet: networkRuleSet
+ partitionCount: partitionCount
+ publicNetworkAccess: publicNetworkAccess
+ replicaCount: replicaCount
+ semanticSearch: semanticSearch
+ }
+ sku: sku
+}
+
+output id string = search.id
+output endpoint string = 'https://${name}.search.windows.net/'
+output name string = search.name
diff --git a/deploy/shared/security/keyvault-access.bicep b/deploy/shared/security/keyvault-access.bicep
new file mode 100644
index 0000000..316775f
--- /dev/null
+++ b/deploy/shared/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/deploy/shared/security/keyvault-secret.bicep b/deploy/shared/security/keyvault-secret.bicep
new file mode 100644
index 0000000..7441b29
--- /dev/null
+++ b/deploy/shared/security/keyvault-secret.bicep
@@ -0,0 +1,31 @@
+metadata description = 'Creates or updates a secret in an Azure Key Vault.'
+param name string
+param tags object = {}
+param keyVaultName string
+param contentType string = 'string'
+@description('The value of the secret. Provide only derived values like blob storage access, but do not hard code any secrets in your templates')
+@secure()
+param secretValue string
+
+param enabled bool = true
+param exp int = 0
+param nbf int = 0
+
+resource keyVaultSecret 'Microsoft.KeyVault/vaults/secrets@2022-07-01' = {
+ name: name
+ tags: tags
+ parent: keyVault
+ properties: {
+ attributes: {
+ enabled: enabled
+ exp: exp
+ nbf: nbf
+ }
+ contentType: contentType
+ value: secretValue
+ }
+}
+
+resource keyVault 'Microsoft.KeyVault/vaults@2022-07-01' existing = {
+ name: keyVaultName
+}
diff --git a/deploy/shared/security/keyvault.bicep b/deploy/shared/security/keyvault.bicep
new file mode 100644
index 0000000..314a1db
--- /dev/null
+++ b/deploy/shared/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/deploy/shared/security/registry-access.bicep b/deploy/shared/security/registry-access.bicep
new file mode 100644
index 0000000..5335efa
--- /dev/null
+++ b/deploy/shared/security/registry-access.bicep
@@ -0,0 +1,19 @@
+metadata description = 'Assigns ACR Pull permissions to access an Azure Container Registry.'
+param containerRegistryName string
+param principalId string
+
+var acrPullRole = subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '7f951dda-4ed3-4680-a7ca-43fe172d538d')
+
+resource aksAcrPull 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
+ scope: containerRegistry // Use when specifying a scope that is different than the deployment scope
+ name: guid(subscription().id, resourceGroup().id, principalId, acrPullRole)
+ properties: {
+ roleDefinitionId: acrPullRole
+ principalType: 'ServicePrincipal'
+ principalId: principalId
+ }
+}
+
+resource containerRegistry 'Microsoft.ContainerRegistry/registries@2022-02-01-preview' existing = {
+ name: containerRegistryName
+}
diff --git a/deploy/shared/security/role.bicep b/deploy/shared/security/role.bicep
new file mode 100644
index 0000000..0b30cfd
--- /dev/null
+++ b/deploy/shared/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/deploy/shared/servicebus/servicebus-queue.bicep b/deploy/shared/servicebus/servicebus-queue.bicep
new file mode 100644
index 0000000..b6f5efa
--- /dev/null
+++ b/deploy/shared/servicebus/servicebus-queue.bicep
@@ -0,0 +1,44 @@
+param location string = resourceGroup().location
+param namespaceName string
+param skuName string = 'Basic'
+param queueName string
+param deadLetterQueueName string = '${queueName}-dlq'
+param tags object = {}
+
+resource serviceBusNamespace 'Microsoft.ServiceBus/namespaces@2022-10-01-preview' = {
+ name: namespaceName
+ location: location
+ tags: tags
+ sku: {
+ name: skuName
+ }
+}
+
+resource deadLetterQueue 'Microsoft.ServiceBus/namespaces/queues@2022-10-01-preview' = {
+ name: deadLetterQueueName
+ parent: serviceBusNamespace
+ properties: {
+ requiresDuplicateDetection: false
+ requiresSession: false
+ enablePartitioning: false
+ }
+}
+
+resource queues 'Microsoft.ServiceBus/namespaces/queues@2022-10-01-preview' = {
+ parent: serviceBusNamespace
+ name: queueName
+ dependsOn: [
+ deadLetterQueue
+ ]
+ properties: {
+ lockDuration: 'PT3M'
+ forwardDeadLetteredMessagesTo: deadLetterQueueName
+ }
+}
+
+output name string = serviceBusNamespace.name
+output skuName string = serviceBusNamespace.sku.name
+output queueName string = queues.name
+
+
+
diff --git a/deploy/shared/storage/storage-account.bicep b/deploy/shared/storage/storage-account.bicep
new file mode 100644
index 0000000..4b6febb
--- /dev/null
+++ b/deploy/shared/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