CVE-2023-5573 (published 2023-10-13T10:15Z)

Allocation of Resources Without Limits or Throttling in GitHub repository vriteio/vrite prior to 0.3.0.

CVSS v3 base score: 6.5, MEDIUM (CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:H)

Weakness information:
cwe_id: CWE-770
cwe_name: Allocation of Resources Without Limits or Throttling
description: The product allocates a reusable resource or group of resources on behalf of an actor without imposing any restrictions on the size or number of resources that can be allocated, in violation of the intended security policy for that actor.
extended_description: Code frequently has to work with limited resources, so programmers must be careful to ensure that resources are not consumed too quickly, or too easily.  Without use of quotas, resource limits, or other protection mechanisms, it can be easy for an attacker to consume many resources by rapidly making many requests, or causing larger resources to be used than is needed. When too many resources are allocated, or if a single resource is too large, then it can prevent the code from working correctly, possibly leading to a denial of service.
         

Fix information:
repo_url: https://github.com/vriteio/vrite
commit_details: repo_url: https://github.com/vriteio/vrite
author: Arek Nawo
author_date: 2023-10-10 16:17:42+02:00
msg: Vrite v0.3 (#45)

- Replace wrapper with element;
- Add XML-like syntax for elements;
- Redesign editor block menus;
- Add MDX extension;
- Allow CORS API access;
- Restructure @vrite/backend;
repository: repo_url: https://github.com/vriteio/vrite
repo_name: vriteio/vrite
description: Open-source developer content platform
repo_language: TypeScript
owner: vriteio
file_changes: filename: .gitignore
change_type: ModificationType.MODIFY
diff: @@ -26,6 +26,7 @@ yarn-error.log*
 .pnpm-debug.log*
 
 # local env files
+docker.env
 .env
 .env.local
 .env.development.local

programming_language: Shell
filename: api.ts
change_type: ModificationType.MODIFY
diff: @@ -4,7 +4,7 @@ import {
   createOpenApiNodeHttpHandler,
   CreateOpenApiNodeHttpHandlerOptions
 } from "trpc-openapi/dist/adapters/node-http/core";
-import corsPlugin from "@fastify/cors";
+import corsPlugin, { OriginFunction } from "@fastify/cors";
 import { OpenApiRouter } from "trpc-openapi";
 import { AnyRouter } from "@trpc/server";
 import { FastifyInstance, FastifyReply, FastifyRequest } from "fastify";
@@ -55,36 +55,38 @@ const fastifyTRPCOpenApiPlugin = <TRouter extends AnyRouter>(
   done();
 };
 const apiService = publicPlugin(async (fastify) => {
+  const originCallback: OriginFunction = (origin, callback) => {
+    if (!origin || origin === "null") {
+      callback(null, true);
+
+      return;
+    }
+
+    const { hostname } = new URL(origin);
+    const appHostname = new URL(fastify.config.PUBLIC_APP_URL).hostname;
+
+    if (
+      hostname === "localhost" ||
+      hostname.endsWith(appHostname) ||
+      (fastify.config.VRITE_CLOUD && hostname.endsWith("swagger.io"))
+    ) {
+      callback(null, true);
+
+      return;
+    }
+
+    callback(new Error("Not allowed"), false);
+  };
+
   await fastify.register(rateLimitPlugin, {
     max: 500,
     timeWindow: "1 minute",
     redis: fastify.redis
   });
   await fastify.register(corsPlugin, {
+    origin: true,
     credentials: true,
-    methods: ["GET", "DELETE", "PUT", "POST"],
-    origin(origin, callback) {
-      if (!origin || origin === "null") {
-        callback(null, true);
-
-        return;
-      }
-
-      const { hostname } = new URL(origin);
-      const appHostname = new URL(fastify.config.PUBLIC_APP_URL).hostname;
-
-      if (
-        hostname === "localhost" ||
-        hostname.endsWith(appHostname) ||
-        (fastify.config.VRITE_CLOUD && hostname.endsWith("swagger.io"))
-      ) {
-        callback(null, true);
-
-        return;
-      }
-
-      callback(new Error("Not allowed"), false);
-    }
+    methods: ["GET", "DELETE", "PUT", "POST"]
   });
   await fastify.register(fastifyTRPCOpenApiPlugin, {
     basePath: "/",

programming_language: TypeScript
filename: index.ts
change_type: ModificationType.MODIFY
diff: @@ -3,7 +3,14 @@ import { generateOpenApiDocument } from "trpc-openapi";
 import { createServer, appRouter } from "@vrite/backend";
 
 (async () => {
-  const server = await createServer();
+  const server = await createServer({
+    database: true,
+    pubSub: true,
+    auth: true,
+    email: true,
+    gitSync: true,
+    search: true
+  });
 
   await server.register(apiService);
   server.get("/swagger.json", (req, res) => {
@@ -11,7 +18,7 @@ import { createServer, appRouter } from "@vrite/backend";
       generateOpenApiDocument(appRouter, {
         baseUrl: server.config.PUBLIC_API_URL,
         title: "Vrite API",
-        version: "0.2.0"
+        version: "0.3.0"
       })
     );
   });

programming_language: TypeScript
filename: app.ts
change_type: ModificationType.MODIFY
diff: @@ -1,11 +1,10 @@
-import { appRouter, errors, publicPlugin, trpcPlugin } from "@vrite/backend";
+import { errors, publicPlugin, trpcPlugin, processAuth } from "@vrite/backend";
 import staticPlugin from "@fastify/static";
 import websocketPlugin from "@fastify/websocket";
 import axios from "axios";
 import viewPlugin from "@fastify/view";
 import handlebars from "handlebars";
 import { FastifyReply } from "fastify";
-import { processAuth } from "@vrite/backend/src/lib/auth";
 import { nanoid } from "nanoid";
 import multipartPlugin from "@fastify/multipart";
 import mime from "mime-types";
@@ -15,7 +14,7 @@ import path from "path";
 
 const appService = publicPlugin(async (fastify) => {
   const renderPage = async (reply: FastifyReply): Promise<void> => {
-    return reply.view("index.html", {
+    return reply.header("X-Frame-Options", "SAMEORIGIN").view("index.html", {
       PUBLIC_APP_URL: fastify.config.PUBLIC_APP_URL,
       PUBLIC_API_URL: fastify.config.PUBLIC_API_URL,
       PUBLIC_COLLAB_URL: fastify.config.PUBLIC_COLLAB_URL,
@@ -51,57 +50,6 @@ const appService = publicPlugin(async (fastify) => {
   fastify.setNotFoundHandler(async (_request, reply) => {
     return renderPage(reply);
   });
-  fastify.get<{ Querystring: { url: string } }>("/proxy*", async (request, reply) => {
-    const filterOutRegex =
-      /(localhost|\b(?:(?:25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(?:25[0-5]|2[0-4]\d|[01]?\d\d?)(?::\d{0,4})?\b)/;
-
-    if (request.headers.origin) {
-      reply.header("Access-Control-Allow-Origin", fastify.config.PUBLIC_APP_URL);
-      reply.header("Access-Control-Allow-Methods", "GET");
-      reply.header(
-        "Access-Control-Allow-Headers",
-        request.headers["access-control-request-headers"]
-      );
-    } else if (
-      fastify.config.NODE_ENV !== "development" &&
-      !fastify.config.PUBLIC_APP_URL.includes("localhost")
-    ) {
-      // Prevent proxy abuse in production
-      return reply.status(400).send("Invalid Origin");
-    }
-
-    if (
-      filterOutRegex.test(request.query.url) &&
-      !request.query.url.includes(fastify.config.PUBLIC_ASSETS_URL)
-    ) {
-      return reply.status(400).send("Invalid URL");
-    }
-
-    if (request.method === "OPTIONS") {
-      // CORS Preflight
-      reply.send();
-    } else {
-      const targetURL = request.query.url;
-
-      try {
-        const response = await axios.get(targetURL, {
-          responseType: "arraybuffer"
-        });
-
-        if (!`${response.headers["content-type"]}`.includes("image")) {
-          return reply.status(400).send("Invalid Content-Type");
-        }
-
-        reply.header("content-type", response.headers["content-type"]);
-        reply.send(Buffer.from(response.data, "binary"));
-      } catch (error) {
-        // eslint-disable-next-line no-console
-        console.error(error);
-
-        return reply.status(500).send("Could not fetch");
-      }
-    }
-  });
   fastify.post<{
     Body: Buffer;
   }>("/upload", async (req, res) => {

programming_language: TypeScript
filename: index.ts
change_type: ModificationType.MODIFY
diff: @@ -2,7 +2,15 @@ import { appService } from "./app";
 import { createServer } from "@vrite/backend";
 
 (async () => {
-  const server = await createServer();
+  const server = await createServer({
+    database: true,
+    pubSub: true,
+    auth: true,
+    email: true,
+    gitSync: true,
+    search: true,
+    storage: true
+  });
 
   await server.register(appService);
   server.listen({ host: server.config.HOST, port: server.config.PORT }, (err) => {

programming_language: TypeScript
filename: assets.ts
change_type: ModificationType.RENAME
diff: @@ -46,7 +46,10 @@ const assetsService = publicPlugin(async (fastify) => {
       await reply.header("Content-Type", sourceContentType).send(sourceAsset);
     };
 
-    reply.header("Access-Control-Allow-Origin", fastify.config.PUBLIC_APP_URL);
+    reply.header(
+      "Access-Control-Allow-Origin",
+      fastify.config.NODE_ENV === "development" ? "*" : fastify.config.PUBLIC_APP_URL
+    );
     reply.header("Access-Control-Allow-Methods", "GET");
 
     if (!sourceAsset) return reply.status(404).send();

programming_language: TypeScript
filename: index.ts
change_type: ModificationType.MODIFY
diff: @@ -1,8 +1,10 @@
-import { assetsService } from "./api";
+import { assetsService } from "./assets";
 import { createServer } from "@vrite/backend";
 
 (async () => {
-  const server = await createServer();
+  const server = await createServer({
+    storage: true
+  });
 
   await server.register(assetsService);
 

programming_language: TypeScript
filename: git-sync.ts
change_type: ModificationType.MODIFY
diff: @@ -1,15 +1,14 @@
 import { Extension, onChangePayload, onDisconnectPayload } from "@hocuspocus/server";
 import {
-  GitData,
-  ObjectId,
   createGenericOutputContentProcessor,
   docToJSON,
   getContentPiecesCollection,
   getGitDataCollection,
-  jsonToBuffer
+  jsonToBuffer,
+  publishGitDataEvent
 } from "@vrite/backend";
-import { createEventPublisher } from "@vrite/backend/src/lib/pub-sub";
 import { FastifyInstance } from "fastify";
+import { ObjectId } from "mongodb";
 import crypto from "node:crypto";
 
 interface Configuration {
@@ -17,11 +16,6 @@ interface Configuration {
   debounceMaxWait: number;
 }
 
-type GitDataEvent = {
-  action: "update";
-  data: Partial<GitData>;
-};
-
 class GitSync implements Extension {
   private configuration: Configuration = {
     debounce: 5000,
@@ -36,10 +30,6 @@ class GitSync implements Extension {
 
   private debounced: Map<string, { timeout: NodeJS.Timeout; start: number }> = new Map();
 
-  private publishGitDataEvent = createEventPublisher<GitDataEvent>((workspaceId) => {
-    return `gitData:${workspaceId}`;
-  });
-
   public constructor(fastify: FastifyInstance, configuration?: Partial<Configuration>) {
     this.fastify = fastify;
     this.configuration = {
@@ -121,7 +111,7 @@ class GitSync implements Extension {
         }
       }
     );
-    this.publishGitDataEvent({ fastify: this.fastify }, `${details.context.workspaceId}`, {
+    publishGitDataEvent({ fastify: this.fastify }, `${details.context.workspaceId}`, {
       action: "update",
       data: {
         records: gitData.records.map((record: any) => {

programming_language: TypeScript
filename: search-indexing.ts
change_type: ModificationType.MODIFY
diff: @@ -1,6 +1,7 @@
 import { Extension, onChangePayload, onDisconnectPayload } from "@hocuspocus/server";
-import { ObjectId, docToBuffer, getContentPiecesCollection } from "@vrite/backend";
+import { docToBuffer, getContentPiecesCollection } from "@vrite/backend";
 import { FastifyInstance } from "fastify";
+import { ObjectId } from "mongodb";
 
 interface Configuration {
   debounce: number | false | null;

programming_language: TypeScript
filename: index.ts
change_type: ModificationType.MODIFY
diff: @@ -2,7 +2,12 @@ import { writingPlugin } from "./writing";
 import { createServer } from "@vrite/backend";
 
 (async () => {
-  const server = await createServer();
+  const server = await createServer({
+    database: true,
+    auth: true,
+    pubSub: true,
+    search: true
+  });
 
   await server.register(writingPlugin);
 })();

programming_language: TypeScript
filename: writing.ts
change_type: ModificationType.MODIFY
diff: @@ -1,10 +1,14 @@
-import { publicPlugin, getContentsCollection, getContentVariantsCollection } from "@vrite/backend";
+import {
+  publicPlugin,
+  getContentsCollection,
+  getContentVariantsCollection,
+  errors,
+  SessionData
+} from "@vrite/backend";
 import { Server } from "@hocuspocus/server";
 import { Database } from "@hocuspocus/extension-database";
 import { Redis } from "@hocuspocus/extension-redis";
 import { ObjectId, Binary } from "mongodb";
-import { SessionData } from "@vrite/backend/src/lib/session";
-import { unauthorized } from "@vrite/backend/src/lib/errors";
 import { SearchIndexing } from "#extensions/search-indexing";
 import { GitSync } from "#extensions/git-sync";
 
@@ -18,13 +22,13 @@ const writingPlugin = publicPlugin(async (fastify) => {
       const cookies = fastify.parseCookie(data.requestHeaders.cookie || "");
 
       if (!cookies.accessToken) {
-        throw unauthorized();
+        throw errors.unauthorized();
       }
 
       const token = fastify.unsignCookie(cookies.accessToken || "")?.value || "";
 
       if (!token) {
-        throw unauthorized();
+        throw errors.unauthorized();
       }
 
       const { sessionId } = fastify.jwt.verify<{ sessionId: string }>(token);

programming_language: TypeScript
filename: package.json
change_type: ModificationType.MODIFY
diff: @@ -10,12 +10,34 @@
   },
   "dependencies": {
     "@fastify/cors": "^8.3.0",
+    "@prettier/sync": "^0.3.0",
     "@trpc/server": "^10.35.0",
+    "@types/hast": "^3.0.1",
+    "@types/html-to-text": "^9.0.1",
+    "@types/js-yaml": "^4.0.6",
+    "@types/mdast": "^4.0.1",
     "@vrite/backend": "workspace:*",
     "@vrite/sdk": "workspace:*",
+    "dayjs": "^1.11.9",
     "fastify": "^4.20.0",
+    "hast-util-to-html": "^9.0.0",
+    "html-to-text": "^9.0.5",
+    "js-yaml": "^4.1.0",
+    "mdast-util-from-markdown": "^2.0.0",
+    "mdast-util-frontmatter": "^2.0.1",
+    "mdast-util-gfm": "^3.0.0",
+    "mdast-util-mdx": "^3.0.0",
+    "mdast-util-to-hast": "^13.0.2",
+    "micromark-extension-frontmatter": "^2.0.0",
+    "micromark-extension-gfm": "^3.0.0",
+    "micromark-extension-mdxjs": "^2.0.0",
     "openai": "^4.0.0",
-    "trpc-openapi": "^1.2.0"
+    "prettier": "^3.0.2",
+    "remark": "^15.0.1",
+    "remark-mdx": "^2.3.0",
+    "remark-parse": "^11.0.0",
+    "trpc-openapi": "^1.2.0",
+    "unist-util-visit": "^5.0.0"
   },
   "devDependencies": {
     "@vrite/scripts": "workspace:*"

programming_language: HTML
filename: extensions.ts
change_type: ModificationType.MODIFY
diff: @@ -1,13 +1,13 @@
 import { extensionsRouter } from "./routes";
-import { publicPlugin, createContext } from "@vrite/backend";
+import { publicPlugin, createFastifyContext } from "@vrite/backend";
 import {
   createOpenApiNodeHttpHandler,
   CreateOpenApiNodeHttpHandlerOptions
 } from "trpc-openapi/dist/adapters/node-http/core";
-import corsPlugin from "@fastify/cors";
 import { OpenApiRouter } from "trpc-openapi";
 import { AnyRouter } from "@trpc/server";
 import { FastifyInstance, FastifyReply, FastifyRequest } from "fastify";
+import corsPlugin from "@fastify/cors";
 
 type CreateOpenApiFastifyPluginOptions<TRouter extends OpenApiRouter> =
   CreateOpenApiNodeHttpHandlerOptions<TRouter, any, any> & {
@@ -56,15 +56,15 @@ const fastifyTRPCOpenApiPlugin = <TRouter extends AnyRouter>(
 };
 const extensionsService = publicPlugin(async (fastify) => {
   await fastify.register(corsPlugin, {
-    credentials: true,
     methods: ["GET", "DELETE", "PUT", "POST"],
+    credentials: true,
     origin: true
   });
   await fastify.register(fastifyTRPCOpenApiPlugin, {
     basePath: "/",
     router: extensionsRouter,
     createContext({ req, res }: { req: FastifyRequest; res: FastifyReply }) {
-      return createContext({ req, res }, fastify);
+      return createFastifyContext({ req, res }, fastify);
     }
   });
 });

programming_language: TypeScript
filename: index.ts
change_type: ModificationType.MODIFY
diff: @@ -1,8 +1,8 @@
 import { extensionsService } from "./extensions";
-import { createServer, z } from "@vrite/backend";
+import { createServer } from "@vrite/backend";
 
 (async () => {
-  const server = await createServer();
+  const server = await createServer({});
 
   await server.register(extensionsService);
 

programming_language: TypeScript
filename: transformer.ts
change_type: ModificationType.MODIFY
diff: @@ -111,7 +111,7 @@ const devOutputTransformer = createOutputTransformer<string>((contentNode) => {
   };
   const transformContentNode = (
     nodeWalker: JSONContentNodeWalker<
-      JSONContentNode["listItem" | "blockquote" | "doc" | "wrapper"]
+      JSONContentNode["listItem" | "blockquote" | "doc" | "element"]
     >
   ): string => {
     return nodeWalker.children
@@ -150,9 +150,9 @@ const devOutputTransformer = createOutputTransformer<string>((contentNode) => {
             return `\n\`\`\`${child.node.attrs?.lang || ""}\n${transformTextNode(
               child as JSONContentNodeWalker<JSONContentNode["codeBlock"]>
             )}\n\`\`\`\n`;
-          case "wrapper":
+          case "element":
             return `\n${transformContentNode(
-              child as JSONContentNodeWalker<JSONContentNode["wrapper"]>
+              child as JSONContentNodeWalker<JSONContentNode["element"]>
             )}\n`;
           case "blockquote":
             return `\n${transformContentNode(

programming_language: TypeScript
filename: transformer.ts
change_type: ModificationType.MODIFY
diff: @@ -111,7 +111,7 @@ const hashnodeOutputTransformer = createOutputTransformer<string>((contentNode)
   };
   const transformContentNode = (
     nodeWalker: JSONContentNodeWalker<
-      JSONContentNode["listItem" | "blockquote" | "doc" | "wrapper"]
+      JSONContentNode["listItem" | "blockquote" | "doc" | "element"]
     >
   ): string => {
     return nodeWalker.children
@@ -150,9 +150,9 @@ const hashnodeOutputTransformer = createOutputTransformer<string>((contentNode)
             return `\n\`\`\`${child.node.attrs?.lang || ""}\n${transformTextNode(
               child as JSONContentNodeWalker<JSONContentNode["codeBlock"]>
             )}\n\`\`\`\n`;
-          case "wrapper":
+          case "element":
             return `\n${transformContentNode(
-              child as JSONContentNodeWalker<JSONContentNode["wrapper"]>
+              child as JSONContentNodeWalker<JSONContentNode["element"]>
             )}\n`;
           case "blockquote":
             return `\n${transformContentNode(

programming_language: TypeScript
filename: index.ts
change_type: ModificationType.MODIFY
diff: @@ -2,13 +2,15 @@ import { devRouter } from "./dev";
 import { hashnodeRouter } from "./hashnode";
 import { gptRouter } from "./gpt";
 import { mediumRouter } from "./medium";
+import { mdxRouter } from "./mdx";
 import { router } from "@vrite/backend";
 
 const extensionsRouter = router({
   dev: devRouter,
   hashnode: hashnodeRouter,
   medium: mediumRouter,
-  gpt: gptRouter
+  gpt: gptRouter,
+  mdx: mdxRouter
 });
 
 type Router = typeof extensionsRouter;

programming_language: TypeScript
filename: index.ts
change_type: ModificationType.ADD
diff: @@ -0,0 +1,62 @@
+import { mdxAsyncInputTransformer } from "./input-transformer";
+import { mdxAsyncOutputTransformer } from "./output-transformer";
+import { procedure, router, z } from "@vrite/backend";
+import { InputTransformer } from "@vrite/sdk/transformers";
+
+const basePath = "/mdx";
+const mdxRouter = router({
+  input: procedure
+    .meta({
+      openapi: {
+        method: "POST",
+        path: `${basePath}/input`
+      }
+    })
+    .input(z.object({ data: z.array(z.string()) }))
+    .output(
+      z.array(
+        z.object({
+          content: z.string(),
+          contentPiece: z.any()
+        })
+      )
+    )
+    .mutation(async ({ input }) => {
+      const output: Array<ReturnType<InputTransformer>> = [];
+
+      for await (const content of input.data) {
+        output.push(await mdxAsyncInputTransformer(content));
+      }
+
+      return output;
+    }),
+  output: procedure
+    .meta({
+      openapi: {
+        method: "POST",
+        path: `${basePath}/output`
+      }
+    })
+    .input(
+      z.object({
+        data: z.array(
+          z.object({
+            content: z.any(),
+            metadata: z.any()
+          })
+        )
+      })
+    )
+    .output(z.array(z.string()))
+    .mutation(async ({ ctx, input }) => {
+      const output: string[] = [];
+
+      for await (const { content, metadata } of input.data) {
+        output.push(await mdxAsyncOutputTransformer(content, metadata));
+      }
+
+      return output;
+    })
+});
+
+export { mdxRouter };

programming_language: TypeScript
filename: input-transformer.ts
change_type: ModificationType.ADD
diff: @@ -0,0 +1,201 @@
+import { InputTransformer } from "@vrite/sdk/transformers";
+import { mdxjs } from "micromark-extension-mdxjs";
+import { fromMarkdown } from "mdast-util-from-markdown";
+import { MdxJsxAttribute, MdxJsxExpressionAttribute, mdxFromMarkdown } from "mdast-util-mdx";
+import { frontmatter } from "micromark-extension-frontmatter";
+import { frontmatterFromMarkdown } from "mdast-util-frontmatter";
+import { gfmFromMarkdown } from "mdast-util-gfm";
+import { gfm } from "micromark-extension-gfm";
+import { toHtml } from "hast-util-to-html";
+import { toHast, defaultHandlers } from "mdast-util-to-hast";
+import babelPlugin from "prettier/plugins/babel";
+import estreePlugin from "prettier/plugins/estree";
+import { format } from "prettier/standalone";
+import { load } from "js-yaml";
+import dayjs from "dayjs";
+import type { Plugin } from "prettier";
+import type { RootContentMap } from "mdast";
+import type { Element, Text } from "hast";
+
+const attributeProcessingPromises: Array<Promise<any>> = [];
+const processAttribute = async (value: string): Promise<any> => {
+  try {
+    const processedValue = await format(value, {
+      parser: "json-stringify",
+      plugins: [babelPlugin, estreePlugin as Plugin]
+    });
+
+    return JSON.parse(processedValue);
+  } catch (error) {
+    try {
+      return JSON.parse(value);
+    } catch (error) {
+      return value;
+    }
+  }
+};
+const attributesToJSON = async (
+  attributes: Array<MdxJsxAttribute | MdxJsxExpressionAttribute>
+): Promise<Record<string, any>> => {
+  const output: Record<string, any> = {};
+
+  for await (const attribute of attributes) {
+    if (attribute.type === "mdxJsxAttribute") {
+      if (typeof attribute.value === "string") {
+        output[attribute.name] = attribute.value;
+      } else if (attribute.value === null) {
+        output[attribute.name] = true;
+      } else if (attribute.value?.value) {
+        const value = await processAttribute(attribute.value.value);
+
+        output[attribute.name] = value;
+      }
+    }
+  }
+
+  return output;
+};
+const mdxAsyncInputTransformer = async (input: string): Promise<ReturnType<InputTransformer>> => {
+  const mdast = fromMarkdown(input, {
+    extensions: [gfm(), frontmatter(), mdxjs()],
+    mdastExtensions: [gfmFromMarkdown(), frontmatterFromMarkdown(), mdxFromMarkdown()]
+  });
+  const hast = toHast(mdast, {
+    handlers: {
+      mdxjsEsm(state, node: RootContentMap["mdxjsEsm"]) {
+        const result: Element = {
+          tagName: "div",
+          type: "element",
+          properties: {
+            "data-element": "true",
+            "data-type": "Import"
+          },
+          children: state.all({
+            children: [{ type: "code", lang: "mdx", value: node.value.trim() }],
+            type: "root"
+          })
+        };
+
+        state.patch(node, result);
+
+        return state.applyData(node, result);
+      },
+      paragraph(state, node: RootContentMap["paragraph"]) {
+        if (node.children.length === 1 && node.children[0].type === "image") {
+          return defaultHandlers.image(state, node.children[0]);
+        } else if (node.children.length === 1 && node.children[0].type === "mdxJsxTextElement") {
+          return state.all({ type: "root", children: [node.children[0]] })[0];
+        }
+
+        return defaultHandlers.paragraph(state, node);
+      },
+      code(state, node: RootContentMap["code"]) {
+        const result = defaultHandlers.code(state, { ...node, value: node.value.trim() });
+        const meta: string[] = [];
+
+        let title = "";
+
+        (node.meta || "").split(" ").forEach((item) => {
+          if (item.startsWith("title=")) {
+            const match = item.match(/title="(.+?)"/);
+
+            if (match) {
+              title = match[1] || title;
+            }
+          } else {
+            meta.push(item);
+          }
+        });
+
+        const codeElement = result.children[0] as Element;
+        const textElement = codeElement.children[0] as Text;
+
+        result.properties["data-title"] = title;
+        result.properties["data-meta"] = meta.join(" ");
+        textElement.value = textElement.value.trim();
+
+        return result;
+      },
+      list(state, node: RootContentMap["list"]) {
+        const result = defaultHandlers.list(state, node);
+        const className = `${result.properties.className || ""}`;
+
+        if (className.includes("contains-task-list")) {
+          result.properties.className = className.replace("contains-task-list", "").trim();
+          if (!result.properties.className) delete result.properties.className;
+
+          result.properties["data-type"] = "taskList";
+        }
+
+        return result;
+      },
+      mdxFlowExpression() {
+        return undefined;
+      },
+      mdxJsxTextElement(state, node: RootContentMap["mdxJsxTextElement"], parent) {
+        if (parent?.children.length === 1) {
+          return state.all({
+            type: "root",
+            children: [
+              {
+                type: "mdxJsxFlowElement",
+                name: node.name,
+                attributes: node.attributes,
+                children: [{ type: "paragraph", children: node.children }]
+              }
+            ]
+          })[0];
+        }
+
+        return undefined;
+      },
+      mdxTextExpression() {
+        return undefined;
+      },
+      mdxJsxFlowElement(state, node: RootContentMap["mdxJsxFlowElement"]) {
+        const result: Element = {
+          tagName: "div",
+          type: "element",
+          properties: {
+            "data-element": "true",
+            "data-type": node.name
+          },
+          children: state.all(node)
+        };
+        const promise = attributesToJSON(node.attributes).then((attributes) => {
+          result.properties["data-props"] = JSON.stringify(attributes);
+        });
+
+        attributeProcessingPromises.push(promise);
+        state.patch(node, result);
+
+        return state.applyData(node, result);
+      }
+    }
+  });
+  const frontmatterYAML = mdast.children.find(
+    (child) => child.type === "yaml"
+  ) as RootContentMap["yaml"];
+  const { canonicalLink, coverUrl, description, date, slug, title, ...customData } = (
+    frontmatterYAML ? load(frontmatterYAML.value) : {}
+  ) as Record<string, any>;
+
+  await Promise.all(attributeProcessingPromises);
+
+  const content = toHtml(hast);
+
+  return {
+    content,
+    contentPiece: {
+      ...(canonicalLink && { canonicalLink }),
+      ...(coverUrl && { coverUrl }),
+      ...(description && { description: `<p>${description}</p>` }),
+      ...(date && { date: dayjs(date).toISOString() }),
+      ...(slug && { slug }),
+      ...(title && { title }),
+      customData
+    }
+  };
+};
+
+export { mdxAsyncInputTransformer };

programming_language: TypeScript
filename: output-transformer.ts
change_type: ModificationType.ADD
diff: @@ -0,0 +1,315 @@
+/* eslint-disable no-use-before-define */
+import {
+  createContentWalker,
+  JSONContentNodeWalker,
+  JSONContentNode,
+  GenericJSONContentNode
+} from "@vrite/sdk/transformers";
+import { format } from "prettier/standalone";
+import babelPlugin from "prettier/plugins/babel";
+import estreePlugin from "prettier/plugins/estree";
+import markdownPlugin from "prettier/plugins/markdown";
+import { ContentPiece } from "@vrite/sdk/api";
+import { convert as convertToText } from "html-to-text";
+import { dump } from "js-yaml";
+import dayjs from "dayjs";
+import type { Plugin } from "prettier";
+
+const processCode = async (code: string, hasContent?: boolean): Promise<string> => {
+  const codeTagClosed = code?.trim().replace(/>$/, "/>") || "";
+  const formattedCode = await format(codeTagClosed, {
+    parser: "babel-ts",
+    plugins: [babelPlugin, estreePlugin as Plugin],
+    printWidth: 60,
+    trailingComma: "none",
+    singleQuote: false
+  });
+
+  return formattedCode.replace(/ *?\/>;/gm, hasContent ? ">" : "/>").trim();
+};
+const mdxAsyncOutputTransformer = async (
+  contentNode: GenericJSONContentNode,
+  contentPiece?: Pick<
+    ContentPiece<Record<string, any>>,
+    | "date"
+    | "title"
+    | "description"
+    | "tags"
+    | "members"
+    | "slug"
+    | "filename"
+    | "coverUrl"
+    | "coverAlt"
+    | "customData"
+    | "canonicalLink"
+    | "coverWidth"
+  >
+): Promise<string> => {
+  const contentWalker = createContentWalker(contentNode);
+  const transformText = (textWalker: JSONContentNodeWalker<JSONContentNode["text"]>): string => {
+    let output = "";
+
+    if (textWalker.node.type === "text") {
+      output = textWalker.node.text;
+      textWalker.node.marks?.forEach((mark) => {
+        switch (mark.type) {
+          case "link":
+            output = `[${output}](${mark.attrs.href})`;
+            break;
+          case "bold":
+            output = `**${output}**`;
+            break;
+          case "code":
+            output = `\`${output}\``;
+            break;
+          case "italic":
+            output = `_${output}_`;
+            break;
+          case "strike":
+            output = `~~${output}~~`;
+            break;
+          default:
+            break;
+        }
+      });
+    }
+
+    return output;
+  };
+  const transformTextNode = (
+    paragraphWalker: JSONContentNodeWalker<JSONContentNode["paragraph" | "heading" | "codeBlock"]>
+  ): string => {
+    return `${paragraphWalker.children
+      .map((child) => {
+        if (child.node.type === "text") {
+          return transformText(child as JSONContentNodeWalker<JSONContentNode["text"]>);
+        }
+
+        return "\n";
+      })
+      .join("")}`;
+  };
+  const transformTable = (tableWalker: JSONContentNodeWalker<JSONContentNode["table"]>): string => {
+    let output = "";
+
+    tableWalker.children.forEach((tableRowWalker, rowIndex) => {
+      let isHeader = false;
+
+      const columns = tableRowWalker.children.map((tableCellWalker) => {
+        if (tableCellWalker.node.type === "tableHeader") {
+          isHeader = true;
+        }
+
+        return tableCellWalker.children.map(transformTextNode).join("\n");
+      });
+
+      if (rowIndex === tableWalker.children.length - 1) {
+        output += `| ${columns.map((row) => row.replace(/\n/g, " ")).join(" | ")} |`;
+      } else {
+        output += `| ${columns.map((row) => row.replace(/\n/g, " ")).join(" | ")} |\n`;
+      }
+
+      if (isHeader && rowIndex === 0) {
+        output += `| ${columns.map(() => "---").join(" | ")} |\n`;
+      }
+    });
+
+    return output;
+  };
+  const transformCodeBlock = (
+    codeBlockWalker: JSONContentNodeWalker<JSONContentNode["codeBlock"]>
+  ): string => {
+    const attrs = codeBlockWalker.node.attrs || {};
+
+    let openingTag = `${attrs?.lang || ""}`;
+
+    if (attrs?.title) {
+      openingTag += ` title="${attrs.title}"`;
+    }
+
+    if (attrs?.meta) {
+      openingTag += ` ${attrs.meta}`;
+    }
+
+    return `\`\`\`${openingTag}\n${transformTextNode(codeBlockWalker)}\n\`\`\``;
+  };
+  const transformElement = async (
+    elementWalker: JSONContentNodeWalker<JSONContentNode["element"]>
+  ): Promise<string> => {
+    const { attrs } = elementWalker.node;
+
+    if (attrs.type === "Import" && elementWalker.children[0]?.node?.type === "codeBlock") {
+      return `${transformTextNode(
+        elementWalker.children[0] as JSONContentNodeWalker<JSONContentNode["codeBlock"]>
+      ).trim()}`;
+    }
+
+    const keyValueProps = Object.entries(attrs.props).map(([key, value]) => {
+      if (value === true) return key;
+
+      const useBrackets = typeof value !== "string" || value.includes("\n") || value.includes(`"`);
+
+      return `${key}=${useBrackets ? "{" : ""}${JSON.stringify(value)}${useBrackets ? "}" : ""}`;
+    });
+    const openingTag = await processCode(
+      `<${attrs.type}${keyValueProps.length ? " " : ""}${keyValueProps.join(" ")}>`,
+      elementWalker.children.length > 0
+    );
+
+    if (elementWalker.children.length > 0) {
+      return `${openingTag}\n${(
+        await transformContentNode(
+          elementWalker as JSONContentNodeWalker<JSONContentNode["element"]>
+        )
+      )
+        .split("\n")
+        .map((line) => `  ${line}`)
+        .join("\n")}\n</${attrs.type}>`;
+    }
+
+    return openingTag;
+  };
+  const transformContentNode = async (
+    nodeWalker: JSONContentNodeWalker<
+      JSONContentNode["listItem" | "taskItem" | "blockquote" | "doc" | "element"]
+    >
+  ): Promise<string> => {
+    const output: string[] = [];
+
+    for await (const child of nodeWalker.children) {
+      const processChildNode = async (): Promise<string> => {
+        const nodeType = child.node.type;
+        const previousSibling = child.previousSibling();
+        const isPreviousSiblingList = ["bulletList", "orderedList", "taskList"].includes(
+          previousSibling?.node.type || ""
+        );
+
+        switch (nodeType) {
+          case "paragraph":
+            return `\n${transformTextNode(
+              child as JSONContentNodeWalker<JSONContentNode["paragraph"]>
+            )}\n`;
+          case "bulletList":
+          case "orderedList":
+          case "taskList":
+            return `${isPreviousSiblingList ? "\n" : ""}${await transformList(
+              child as JSONContentNodeWalker<
+                JSONContentNode["bulletList" | "orderedList" | "taskList"]
+              >
+            )}\n`;
+          case "table":
+            return `\n${transformTable(
+              child as JSONContentNodeWalker<JSONContentNode["table"]>
+            )}\n`;
+          case "horizontalRule":
+            return "\n---\n";
+          case "image":
+            return `\n![${child.node.attrs?.alt || ""}](${child.node.attrs?.src || ""})\n`;
+          case "heading":
+            return `\n${"#".repeat(child.node.attrs?.level || 1)} ${transformTextNode(
+              child as JSONContentNodeWalker<JSONContentNode["heading"]>
+            )}\n`;
+          case "codeBlock":
+            return `\n${transformCodeBlock(
+              child as JSONContentNodeWalker<JSONContentNode["codeBlock"]>
+            )}\n`;
+          case "element":
+            return `${child.node.attrs.type === "Import" ? "" : "\n"}${await transformElement(
+              child as JSONContentNodeWalker<JSONContentNode["element"]>
+            )}\n`;
+          case "blockquote":
+            return `\n${(
+              await transformContentNode(
+                child as JSONContentNodeWalker<JSONContentNode["blockquote"]>
+              )
+            )
+              .split("\n")
+              .map((line) => `> ${line}`)
+              .join("\n")}\n`;
+          default:
+            return "";
+        }
+      };
+
+      output.push(await processChildNode());
+    }
+
+    return output.join("").trim();
+  };
+  const transformList = async (
+    listWalker: JSONContentNodeWalker<JSONContentNode["bulletList" | "orderedList" | "taskList"]>
+  ): Promise<string> => {
+    const listItems: Array<{ content: string; node: JSONContentNode["listItem" | "taskItem"] }> =
+      [];
+
+    for await (const nodeWalker of listWalker.children) {
+      listItems.push({
+        content: await transformContentNode(nodeWalker),
+        node: nodeWalker.node
+      });
+    }
+
+    return listItems
+      .map(({ content, node }, index) => {
+        let prefix = "";
+        let indent = 0;
+
+        if (listWalker.node.type === "taskList" && node.type === "taskItem") {
+          prefix = `${node.attrs?.checked ? "- [x] " : "- [ ] "} `;
+          indent = 2;
+        }
+
+        if (listWalker.node.type === "orderedList") {
+          const start = listWalker.node.attrs?.start || 1;
+
+          prefix = `${start + index}. `;
+          indent = prefix.length;
+        }
+
+        if (listWalker.node.type === "bulletList") {
+          prefix = "- ";
+          indent = prefix.length;
+        }
+
+        return content
+          .split("\n")
+          .map((line, lineIndex) => {
+            if (lineIndex === 0) {
+              return `${prefix}${line}`;
+            }
+
+            return `${" ".repeat(indent)}${line}`;
+          })
+          .join("\n");
+      })
+      .join("\n");
+  };
+  const content = await transformContentNode(
+    contentWalker as JSONContentNodeWalker<JSONContentNode["doc"]>
+  );
+  const frontmatter = dump(
+    {
+      ...(contentPiece?.canonicalLink && { canonicalLink: contentPiece.canonicalLink }),
+      ...(contentPiece?.coverUrl && { coverUrl: contentPiece.coverUrl }),
+      ...(contentPiece?.description && {
+        description: convertToText(contentPiece.description, { wordwrap: false })
+      }),
+      ...(contentPiece?.date && { date: dayjs(contentPiece.date).format("YYYY-MM-DD") }),
+      ...(contentPiece?.slug && { slug: contentPiece.slug }),
+      ...(contentPiece?.title && { title: contentPiece.title }),
+      ...(contentPiece?.customData || {})
+    },
+    { skipInvalid: true, forceQuotes: true, quotingType: '"' }
+  );
+
+  return (
+    await format(
+      `${frontmatter ? "---" : ""}\n${frontmatter.trim()}\n${
+        frontmatter ? "---" : ""
+      }\n\n${content.trim()}`,
+      { plugins: [markdownPlugin], parser: "mdx" }
+    )
+  ).trim();
+};
+
+export { mdxAsyncOutputTransformer };

programming_language: TypeScript
filename: transformer.ts
change_type: ModificationType.MODIFY
diff: @@ -63,7 +63,7 @@ const mediumOutputTransformer = createOutputTransformer<string>((contentNode) =>
   };
   const transformContentNode = (
     nodeWalker: JSONContentNodeWalker<
-      JSONContentNode["listItem" | "blockquote" | "doc" | "wrapper"]
+      JSONContentNode["listItem" | "blockquote" | "doc" | "element"]
     >
   ): string => {
     return nodeWalker.children
@@ -98,9 +98,9 @@ const mediumOutputTransformer = createOutputTransformer<string>((contentNode) =>
             return `\n\`\`\`${child.node.attrs?.lang || ""}\n${transformTextNode(
               child as JSONContentNodeWalker<JSONContentNode["codeBlock"]>
             )}\n\`\`\`\n`;
-          case "wrapper":
+          case "element":
             return `\n${transformContentNode(
-              child as JSONContentNodeWalker<JSONContentNode["wrapper"]>
+              child as JSONContentNodeWalker<JSONContentNode["element"]>
             )}\n`;
           case "blockquote":
             return `\n${transformContentNode(

programming_language: TypeScript
filename: types.d.ts
change_type: ModificationType.MODIFY
diff: @@ -1,3 +1,13 @@
+declare module 'astro:content' {
+	interface Render {
+		'.mdx': Promise<{
+			Content: import('astro').MarkdownInstance<{}>['Content'];
+			headings: import('astro').MarkdownHeading[];
+			remarkPluginFrontmatter: Record<string, any>;
+		}>;
+	}
+}
+
 declare module 'astro:content' {
 	interface Render {
 		'.md': Promise<{
@@ -176,74 +186,83 @@ declare module 'astro:content' {
 		"docs": {
 "javascript-sdk/javascript-sdk.md": {
 	id: "javascript-sdk/javascript-sdk.md";
-  slug: "javascript-sdk/javascript-sdk";
+  slug: "javascript-sdk/introduction";
   body: string;
   collection: "docs";
-  data: any
+  data: InferEntrySchema<"docs">
 } & { render(): Render[".md"] };
 "self-hosting/configuration.md": {
 	id: "self-hosting/configuration.md";
   slug: "self-hosting/configuration";
   body: string;
   collection: "docs";
-  data: any
+  data: InferEntrySchema<"docs">
 } & { render(): Render[".md"] };
 "self-hosting/docker.md": {
 	id: "self-hosting/docker.md";
   slug: "self-hosting/docker";
   body: string;
   collection: "docs";
-  data: any
+  data: InferEntrySchema<"docs">
 } & { render(): Render[".md"] };
 "usage-guide/configuring-vrite.md": {
 	id: "usage-guide/configuring-vrite.md";
   slug: "usage-guide/configuring-vrite";
   body: string;
   collection: "docs";
-  data: any
+  data: InferEntrySchema<"docs">
 } & { render(): Render[".md"] };
 "usage-guide/content-editor.md": {
 	id: "usage-guide/content-editor.md";
-  slug: "usage-guide/content-editor";
+  slug: "/usage-guide/content-editor";
   body: string;
   collection: "docs";
-  data: any
+  data: InferEntrySchema<"docs">
 } & { render(): Render[".md"] };
 "usage-guide/getting-started.md": {
 	id: "usage-guide/getting-started.md";
-  slug: "usage-guide/getting-started";
+  slug: "/usage-guide/getting-started";
   body: string;
   collection: "docs";
-  data: any
+  data: InferEntrySchema<"docs">
 } & { render(): Render[".md"] };
 "usage-guide/kanban-dashboard.md": {
 	id: "usage-guide/kanban-dashboard.md";
-  slug: "usage-guide/kanban-dashboard";
+  slug: "/usage-guide/kanban-dashboard";
   body: string;
   collection: "docs";
-  data: any
+  data: InferEntrySchema<"docs">
 } & { render(): Render[".md"] };
 "usage-guide/metadata.md": {
 	id: "usage-guide/metadata.md";
-  slug: "usage-guide/metadata";
+  slug: "/usage-guide/metadata";
   body: string;
   collection: "docs";
-  data: any
+  data: InferEntrySchema<"docs">
 } & { render(): Render[".md"] };
 "usage-guide/publishing.md": {
 	id: "usage-guide/publishing.md";
-  slug: "usage-guide/publishing";
+  slug: "/usage-guide/publishing";
   body: string;
   collection: "docs";
-  data: any
+  data: InferEntrySchema<"docs">
 } & { render(): Render[".md"] };
 "usage-guide/vrite-extensions.md": {
 	id: "usage-guide/vrite-extensions.md";
-  slug: "usage-guide/vrite-extensions";
+  slug: "/usage-guide/vrite-extensions";
   body: string;
   collection: "docs";
-  data: any
+  data: InferEntrySchema<"docs">
 } & { render(): Render[".md"] };
+};
+"recipes": {
+"test.mdx": {
+	id: "test.mdx";
+  slug: "/recipes/content-pieces";
+  body: string;
+  collection: "recipes";
+  data: InferEntrySchema<"recipes">
+} & { render(): Render[".mdx"] };
 };
 
 	};

programming_language: TypeScript
filename: astro.config.mjs
change_type: ModificationType.MODIFY
diff: @@ -2,6 +2,8 @@ import { defineConfig } from "astro/config";
 import solidJs from "@astrojs/solid-js";
 import unocss from "unocss/astro";
 import robotsTxt from "astro-robots-txt";
+import mdx from "@astrojs/mdx";
+import autoImport from "astro-auto-import";
 
 export default defineConfig({
   markdown: {
@@ -10,6 +12,9 @@ export default defineConfig({
     }
   },
   integrations: [
+    autoImport({
+      imports: [{ "#components/content": ["Card", "CardGrid", "Warning", "Info"] }]
+    }),
     unocss({ injectReset: true }),
     solidJs(),
     robotsTxt({
@@ -18,7 +23,8 @@ export default defineConfig({
           userAgent: "*"
         }
       ]
-    })
+    }),
+    mdx()
   ],
   build: {
     redirects: false

programming_language: TypeScript
filename: package.json
change_type: ModificationType.MODIFY
diff: @@ -11,23 +11,31 @@
     "astro": "astro"
   },
   "dependencies": {
+    "@astrojs/mdx": "^1.1.1",
     "@astrojs/sitemap": "^3.0.0",
     "@astrojs/solid-js": "^3.0.1",
     "@mdi/js": "^7.2.96",
+    "@solid-primitives/scheduled": "^1.4.0",
     "@types/marked": "^5.0.1",
     "@unocss/reset": "^0.55.7",
     "@vrite/components": "workspace:*",
+    "@vrite/sdk": "workspace:*",
     "astro": "^3.1.0",
+    "astro-auto-import": "^0.3.1",
+    "astro-icon": "^0.8.1",
     "clsx": "^2.0.0",
     "curl-string": "^3.1.0",
     "marked": "^9.0.0",
     "mini-svg-data-uri": "^1.4.4",
     "nanoid": "^5.0.1",
     "plausible-tracker": "^0.3.8",
+    "seamless-scroll-polyfill": "^2.3.4",
     "shiki": "^0.14.4",
     "solid-js": "^1.7.11",
+    "tinykeys": "^2.1.0",
     "typescript": "^5.2.2",
     "unocss": "^0.55.7",
+    "url-slug": "^4.0.1",
     "vite": "^4.4.9"
   },
   "devDependencies": {

programming_language: TypeScript
filename: card-grid.astro
change_type: ModificationType.ADD
diff: @@ -0,0 +1,18 @@
+---
+import clsx from "clsx";
+interface Props {
+  cols?: 2 | 3 | 4;
+}
+
+const { props } = Astro;
+---
+
+<div
+  class={clsx("grid grid-reset-margin gap-2 my-4", {
+    "sm:grid-cols-2": !props.cols || props.cols === 2,
+    "sm:grid-cols-3": props.cols === 3,
+    "sm:grid-cols-4": props.cols === 4
+  })}
+>
+  <slot />
+</div>

programming_language: TypeScript
filename: card.astro
change_type: ModificationType.ADD
diff: @@ -0,0 +1,44 @@
+---
+import { Card as BaseCard, Heading, IconButton } from "#components/primitives";
+import { Icon } from "astro-icon";
+import clsx from "clsx";
+
+interface Props {
+  icon: string;
+  label: string;
+  gradient?: boolean;
+  link: string;
+}
+
+const { props } = Astro;
+---
+
+<a href={props.link} class="not-prose cursor-pointer block my-4"
+  ><BaseCard
+    class={clsx(
+      "w-full flex flex-col m-0 p-0 gap-2 items-start h-full",
+      props.gradient ? "hover:bg-gradient-to-bl" : "!hover:bg-gray-200"
+    )}
+    color={props.gradient ? "primary" : "contrast"}
+  >
+    <div class="flex justify-center items-center pl-3 pr-4 pt-3 w-full">
+      <div class="pr-1 py-1">
+        <Icon
+          name={props.icon}
+          class={clsx("h-6 w-6", props.gradient ? "fill-current" : "fill-[url(#gradient)]")}
+        />
+      </div>
+      <Heading level={2} class="pl-1 flex-1">
+        {props.label}
+      </Heading>
+    </div>
+    <div
+      class={clsx(
+        "flex flex-col justify-center items-start gap-2 w-full px-4 pb-4",
+        props.gradient ? "" : "text-gray-500 dark:text-gray-400"
+      )}
+    >
+      <slot />
+    </div>
+  </BaseCard></a
+>

programming_language: TypeScript
filename: index.ts
change_type: ModificationType.ADD
diff: @@ -0,0 +1,4 @@
+export { default as Card } from "./card.astro";
+export { default as CardGrid } from "./card-grid.astro";
+export { default as Warning } from "./warning.astro";
+export { default as Info } from "./info.astro";

programming_language: TypeScript
filename: info.astro
change_type: ModificationType.ADD
diff: @@ -0,0 +1,9 @@
+---
+import { Card, Icon } from "#components/primitives";
+import { mdiInformationSlabCircleOutline } from "@mdi/js";
+---
+
+<Card class="flex items-center justify-start mx-0 my-4" color="contrast">
+  <Icon path={mdiInformationSlabCircleOutline} class="w-6 h-6 mr-2 fill-[url(#gradient)]" />
+  <div class="flex-1 not-prose"><slot /></div>
+</Card>

programming_language: TypeScript
filename: warning.astro
change_type: ModificationType.ADD
diff: @@ -0,0 +1,9 @@
+---
+import { Card, Icon } from "#components/primitives";
+import { mdiAlertCircleOutline } from "@mdi/js";
+---
+
+<Card class="flex items-center justify-start m-0 my-4" color="primary">
+  <Icon path={mdiAlertCircleOutline} class="w-6 h-6 mr-2" />
+  <div class="flex-1 not-prose"><slot /></div>
+</Card>

programming_language: TypeScript
filename: endpoint-card-sections.tsx
change_type: ModificationType.DELETE
diff: @@ -1,35 +0,0 @@
-import { ParentComponent, createSignal } from "solid-js";
-import { Button } from "#components/primitives";
-
-interface EndpointCardSectionsProps {
-  sections: Array<{ label: string; id: string }>;
-}
-
-const EndpointCardSections: ParentComponent<EndpointCardSectionsProps> = (props) => {
-  const [activeSection, setActiveSection] = createSignal(props.sections[0].id);
-
-  return (
-    <>
-      <div class="flex w-full gap-2">
-        {props.sections.map((section) => {
-          return (
-            <Button
-              variant={section.id === activeSection() ? "solid" : "text"}
-              text={section.id === activeSection() ? "base" : "soft"}
-              color="contrast"
-              class="py-1 m-0 text-xl font-semibold"
-              onClick={() => {
-                setActiveSection(section.id);
-              }}
-            >
-              {section.label}
-            </Button>
-          );
-        })}
-      </div>
-      <div data-active-section={activeSection()}>{props.children}</div>
-    </>
-  );
-};
-
-export { EndpointCardSections };

programming_language: unknown
filename: endpoint-card.astro
change_type: ModificationType.DELETE
diff: @@ -1,125 +0,0 @@
----
-import { Code } from "astro:components";
-import { Button, Card, IconButton } from "#components/primitives";
-import curlString from "curl-string";
-import { mdiAsterisk } from "@mdi/js";
-import { EndpointCardSections } from "./endpoint-card-sections";
-
-interface Props {
-    method: string;
-    endpoint: string;
-    parameters?: Array<{
-        name: string;
-        required?: boolean;
-        description?: string;
-        example?:string;
-        schema: { type: string; default?:string };
-    }>;
-    example?: Record<string, any>;
-    requestBody?: string;
-    response?: string;
-}
-
-const body = JSON.stringify( {}, null, 2);
-const sections: Array<{ label: string; id: string }> = [];
-
-if (Astro.props.parameters && Astro.props.parameters.length) {
-    sections.push({ label: "Parameters", id: "parameters" });
-}
-
-if (Astro.props.requestBody) {
-    sections.push({ label: "Body", id: "body" });
-}
-
-sections.push({ label: "Response", id: "response" });
-
-const queryString = new URLSearchParams(
-    (Astro.props.parameters||[]).map((parameter) => {
-        return [parameter.name, parameter.example]
-    }) as string[][]
-).toString();
-const url = `https://api.vrite.io${Astro.props.endpoint}${queryString ? `?${queryString}` : ""}`;
-const parsedBody = JSON.parse(body);
-const curl = curlString(
-    `"${url}"`,
-    {
-        method: Astro.props.method,
-        headers: {
-            Authorization: `Bearer ${"<YOUR-TOKEN>"}`,
-            ...(body === "{}"
-                ? {}
-                : {
-                      "Content-Type": "application/json"
-                  }),
-            Accept: "application/json"
-        },
-        ...(body === "{}"
-            ? {}
-            : {
-                  body: parsedBody
-              })
-    },
-    { colorJson: false, jsonIndentWidth: 4 }
-);
-const code = `${curl}\n`;
----
-
-<Card class="relative p-4 m-0 gap-2 flex flex-col text-gray-700 dark:text-gray-300 my-4 bg-gray-100 dark:bg-gray-900">
-    <div class="flex">
-        <Button badge class="m-0 font-mono font-semibold" size="large" color="contrast">
-            {Astro.props.method}
-            {" "}{Astro.props.endpoint}
-        </Button>
-    </div>
-    <div class="code-block-contrast">
-        <Code code={code} lang="shell" />
-    </div>
-    <EndpointCardSections client:load sections={sections}>
-        {
-            Astro.props.parameters && Astro.props.parameters.length ? (
-                <div class="flex flex-col gap-2 parameters-section">
-                    {(Astro.props.parameters || []).map((parameter) => {
-                        return (
-                            <Card class="m-0 bg-gray-50 dark:bg-gray-800">
-                                <div class="flex items-center">
-                                    <Button badge text="soft" class="m-0 font-mono font-semibold">
-                                        {parameter.name}
-                                    </Button>
-                                    <span class="!bg-transparent text-sm font-mono px-2 flex-1">
-                                        {parameter.schema.type}
-                                    </span>
-                                    {parameter.required && (
-                                        <IconButton
-                                            class="m-0"
-                                            path={mdiAsterisk}
-                                            color="primary"
-                                            badge
-                                            label="Required"
-                                        />
-                                    )}
-                                </div>
-                                {parameter.description && (
-                                    <p class="pl-1 m-0 mt-2">{parameter.description}</p>
-                                )}
-                            </Card>
-                        );
-                    })}
-                </div>
-            ): <></>
-        }
-        {
-            Astro.props.requestBody && (
-                <div class="code-block-contrast body-section">
-                    <Code code={Astro.props.requestBody} lang="typescript"  />
-                </div>
-            )
-        }
-        {
-            Astro.props.response && (
-                <div class="code-block-contrast response-section">
-                    <Code code={Astro.props.response} lang="typescript" />
-                </div>
-            )
-        }
-    </EndpointCardSections>
-</Card>

programming_language: unknown
filename: footer.tsx
change_type: ModificationType.RENAME
diff: @@ -2,18 +2,19 @@ import { mdiChevronLeft, mdiChevronRight } from "@mdi/js";
 import { Component, Show } from "solid-js";
 import { IconButton } from "#components/primitives";
 
-interface NavigateProps {
-  nextEntry?: { label: string; link: string };
-  previousEntry?: { label: string; link: string };
+interface FooterProps {
+  nextEntry?: { label: string; link: string } | null;
+  previousEntry?: { label: string; link: string } | null;
 }
 
-const Navigation: Component<NavigateProps> = (props) => {
+const Footer: Component<FooterProps> = (props) => {
   return (
     <div class="flex flex-col lg:flex-row w-full gap-2 lg:gap-4 pt-16">
       <div class="flex-1">
         <Show when={props.previousEntry}>
           <IconButton
             label={props.previousEntry!.label}
+            text="soft"
             path={mdiChevronLeft}
             iconProps={{ class: "min-w-8" }}
             size="large"
@@ -26,6 +27,7 @@ const Navigation: Component<NavigateProps> = (props) => {
         <Show when={props.nextEntry}>
           <IconButton
             label={<span class="pr-2">{props.nextEntry!.label}</span>}
+            text="soft"
             path={mdiChevronRight}
             iconProps={{ class: "min-w-8" }}
             size="large"
@@ -38,4 +40,4 @@ const Navigation: Component<NavigateProps> = (props) => {
   );
 };
 
-export { Navigation };
+export { Footer };

programming_language: TypeScript
filename: header.tsx
change_type: ModificationType.MODIFY
diff: @@ -1,7 +1,9 @@
-import { mdiAppleKeyboardCommand, mdiMagnify } from "@mdi/js";
-import type { Component } from "solid-js";
-import { Icon, IconButton } from "#components/primitives";
-import { logoIcon } from "#assets/icons";
+import { SearchPaletteProvider, useSearchPalette } from "./search-palette";
+import { mdiAppleKeyboardCommand, mdiGithub, mdiMagnify } from "@mdi/js";
+import { For, type Component, Show } from "solid-js";
+import clsx from "clsx";
+import { Button, Icon, IconButton, Tooltip } from "#components/primitives";
+import { discordIcon, logoIcon } from "#assets/icons";
 
 const isAppleDevice = (): boolean => {
   const platform = typeof navigator === "object" ? navigator.platform : "";
@@ -9,25 +11,93 @@ const isAppleDevice = (): boolean => {
 
   return appleDeviceRegex.test(platform);
 };
+const externalLinks = [
+  {
+    label: "GitHub",
+    icon: mdiGithub,
+    href: "https://github.com/vriteio/vrite"
+  },
+  {
+    label: "Discord",
+    icon: discordIcon,
+    href: "https://discord.gg/yYqDWyKnqE"
+  }
+];
 const Header: Component = () => {
+  const { opened, setOpened } = useSearchPalette();
+
   return (
-    <div class="top-0 bg-gray-50 dark:bg-gray-800 border-b-2 border-gray-200 dark:border-gray-700 left-0 z-50 items-center justify-center w-full flex py-2 px-4 md:px-3">
+    <div
+      class={clsx(
+        "top-0 gap-2 h-12 fixed bg-gray-50 dark:bg-gray-800 border-gray-200 dark:border-gray-700 border-b-2 right-0 z-1 items-center justify-center w-full flex py-2 px-4 md:px-8",
+        "!pr-[max(1rem,calc((100%-(1536px))/2))]"
+      )}
+    >
+      <div class="flex md:hidden items-center justify-start px-1">
+        <IconButton
+          path={logoIcon}
+          color="primary"
+          link="/"
+          class="bg-gradient-to-tr from-red-500 to-orange-500 m-0 mr-1"
+        />
+        <span class="flex-1 text-2xl font-extrabold text-gray-600 dark:text-gray-200">rite</span>
+      </div>
       <div class="flex-1" />
+      <For each={externalLinks}>
+        {(link) => {
+          return (
+            <a
+              class="flex justify-start items-center group cursor-pointer"
+              target="_blank"
+              href={link.href}
+            >
+              <Tooltip text={link.label} class="mt-1">
+                <IconButton
+                  path={link.icon}
+                  class="m-0 h-8 min-w-8"
+                  iconProps={{ class: "h-5 w-5" }}
+                  text="soft"
+                />
+              </Tooltip>
+            </a>
+          );
+        }}
+      </For>
       <IconButton
         path={mdiMagnify}
         label={
-          <div class="hidden xl:flex w-full items-center min-w-48">
-            <span class="pl-1 flex-1 text-start">Search</span>
-            <kbd class="bg-gray-300 dark:bg-gray-700 group-hover:bg-gray-200 dark:group-hover:bg-gray-800 flex justify-center items-center rounded-md px-1 h-5 text-sm">
-              {isAppleDevice() ? <Icon path={mdiAppleKeyboardCommand} class="h-3 w-3" /> : "Ctrl "}K
-            </kbd>
+          <div class="hidden md:flex w-full items-center">
+            <span class="pl-1 flex-1 text-start pr-3">Search</span>
+            <Show when={typeof window === "object"}>
+              <kbd class="bg-gray-300 dark:bg-gray-700 group-hover:bg-gray-200 dark:group-hover:bg-gray-800 flex justify-center items-center rounded-md px-1 h-5 text-sm">
+                {isAppleDevice() ? (
+                  <Icon path={mdiAppleKeyboardCommand} class="h-3 w-3" />
+                ) : (
+                  "Ctrl "
+                )}
+                K
+              </kbd>
+            </Show>
           </div>
         }
         text="soft"
-        class="@xl:min-w-48 justify-start m-0 group !hidden"
+        class="lg:min-w-48 justify-start m-0 group"
+        onClick={() => {
+          setOpened(!opened());
+        }}
       />
+      <Button color="primary" class="m-0" link="https://app.vrite.io">
+        Sign in
+      </Button>
     </div>
   );
 };
+const HeaderWrapper: Component = () => {
+  return (
+    <SearchPaletteProvider>
+      <Header />
+    </SearchPaletteProvider>
+  );
+};
 
-export { Header };
+export { HeaderWrapper as Header };

programming_language: TypeScript
filename: index.ts
change_type: ModificationType.RENAME
diff: @@ -4,4 +4,6 @@ export * from "./header";
 export * from "./side-bar";
 export * from "./on-this-page";
 export * from "./svg-defs";
-export * from "./navigation";
+export * from "./footer";
+export * from "./search-palette";
+export * from "./footer";

programming_language: TypeScript
filename: on-this-page.tsx
change_type: ModificationType.MODIFY
diff: @@ -1,6 +1,15 @@
-import { Component, For, onMount, onCleanup, createSignal, createMemo } from "solid-js";
+import {
+  Component,
+  For,
+  onMount,
+  onCleanup,
+  createSignal,
+  createMemo,
+  createEffect
+} from "solid-js";
 import { mdiListBox } from "@mdi/js";
 import clsx from "clsx";
+import { scroll } from "seamless-scroll-polyfill";
 import type { MarkdownHeading } from "astro";
 import { Button, IconButton } from "#components/primitives";
 
@@ -12,14 +21,42 @@ const OnThisPage: Component<OnThisPageProps> = (props) => {
   const [activeHeading, setActiveHeading] = createSignal(props.headings[0]?.slug || "");
   const headings = createMemo(() => {
     return props.headings.filter((heading) => {
-      return heading.depth === 2;
+      return heading.depth === 2 || heading.depth === 3;
     });
   });
+  const scrollToActiveHeading = (smooth?: boolean): void => {
+    const heading = activeHeading();
+    const element = document.getElementById(heading);
+
+    if (!element) return;
+
+    const rect = element.getBoundingClientRect();
+    const y = rect.top + window.scrollY - 60;
+
+    scroll(window, {
+      top: y,
+      behavior: smooth === false ? "instant" : "smooth"
+    });
+  };
+  const handleClick = (event: MouseEvent): void => {
+    const target = event.target as HTMLElement;
+
+    if (target.matches("h2, h3")) {
+      const { id } = target;
+
+      if (id) {
+        setActiveHeading(id);
+        scrollToActiveHeading();
+        history.replaceState(null, "", `#${id}`);
+        navigator.clipboard.writeText(window.location.href);
+      }
+    }
+  };
 
   onMount(() => {
     if (!headings().length) return;
 
-    const observedElements: HTMLElement[] = [];
+    const hash = location.hash.slice(1);
     const setCurrent: IntersectionObserverCallback = (entries) => {
       for (const entry of entries) {
         if (entry.isIntersecting) {
@@ -59,17 +96,24 @@ const OnThisPage: Component<OnThisPageProps> = (props) => {
       )
       .forEach((h) => headingsObserver.observe(h));
     container?.addEventListener("scroll", handleScroll);
+    document.body.addEventListener("click", handleClick);
     onCleanup(() => {
       headingsObserver.disconnect();
       container?.removeEventListener("scroll", handleScroll);
+      document.body.removeEventListener("click", handleClick);
     });
+
+    if (hash) {
+      setActiveHeading(hash);
+      scrollToActiveHeading(false);
+    }
   });
 
   return (
     <>
       <div
         class={clsx(
-          "w-56 flex-col justify-start top-0 pt-16 fixed right-0 hidden xl:flex gap-2",
+          "w-56 flex-col justify-start top-0 pt-24 xl:fixed right-0 hidden xl:flex gap-2",
           "mr-[max(0px,calc((100%-(1536px))/2))]"
         )}
       >
@@ -89,13 +133,11 @@ const OnThisPage: Component<OnThisPageProps> = (props) => {
                 variant="text"
                 text={activeHeading() === heading.slug ? "base" : "soft"}
                 color={activeHeading() === heading.slug ? "primary" : "base"}
-                class="text-start m-0"
+                class={clsx("text-start m-0", heading.depth === 3 && "ml-6")}
+                size={heading.depth === 2 ? "medium" : "small"}
                 onClick={() => {
-                  document.getElementById(heading.slug)?.scrollIntoView({
-                    block: "start",
-                    inline: "nearest"
-                  });
                   setActiveHeading(heading.slug);
+                  scrollToActiveHeading();
                 }}
               >
                 {heading.text}

programming_language: TypeScript
filename: search-palette.tsx
change_type: ModificationType.ADD
diff: @@ -0,0 +1,502 @@
+import {
+  Accessor,
+  Component,
+  For,
+  Match,
+  ParentComponent,
+  Setter,
+  Show,
+  Switch,
+  createEffect,
+  createSignal,
+  on,
+  onCleanup,
+  useContext
+} from "solid-js";
+import {
+  mdiChevronRight,
+  mdiCreationOutline,
+  mdiFileDocumentOutline,
+  mdiHeadSnowflakeOutline,
+  mdiInformationOutline,
+  mdiKeyboardEsc,
+  mdiKeyboardReturn,
+  mdiMagnify,
+  mdiSwapVertical
+} from "@mdi/js";
+import clsx from "clsx";
+import { scrollIntoView } from "seamless-scroll-polyfill";
+import { createContext } from "solid-js";
+import { debounce } from "@solid-primitives/scheduled";
+import { convert as convertToSlug } from "url-slug";
+import { marked } from "marked";
+import { createClient, SearchResult } from "@vrite/sdk/api";
+import {
+  Button,
+  Card,
+  Icon,
+  IconButton,
+  Input,
+  Loader,
+  Overlay,
+  Tooltip
+} from "#components/primitives";
+
+interface SearchPaletteProps {
+  opened: boolean;
+  setOpened(opened: boolean): void;
+}
+interface SearchPaletteContextData {
+  opened: Accessor<boolean>;
+  setOpened: Setter<boolean>;
+}
+
+const SearchPaletteContext = createContext<SearchPaletteContextData>();
+const SearchPalette: Component<SearchPaletteProps> = (props) => {
+  const client = createClient({
+    token: import.meta.env.PUBLIC_VRITE_SEARCH_TOKEN
+  });
+  const [inputRef, setInputRef] = createSignal<HTMLInputElement | null>(null);
+  const [abortControllerRef, setAbortControllerRef] = createSignal<AbortController | null>(null);
+  const [mode, setMode] = createSignal<"search" | "ask">("search");
+  const [searchResults, setSearchResults] = createSignal<SearchResult[]>([]);
+  const [answer, setAnswer] = createSignal<string>("");
+  const [loading, setLoading] = createSignal(false);
+  const [mouseHoverEnabled, setMouseHoverEnabled] = createSignal(false);
+  const [selectedIndex, setSelectedIndex] = createSignal(0);
+  const [query, setQuery] = createSignal("");
+  const ask = async (): Promise<void> => {
+    let content = "";
+
+    client.useSignal(abortControllerRef()?.signal || null).ask({
+      query: query(),
+      onError(error) {
+        setLoading(false);
+        throw error;
+      },
+      onChunk(chunk) {
+        content += chunk;
+        setAnswer(marked.parse(content, { gfm: true }));
+      },
+      onEnd() {
+        setLoading(false);
+      }
+    });
+    setLoading(false);
+  };
+  const search = debounce(async () => {
+    setSearchResults([]);
+
+    if (abortControllerRef()) abortControllerRef()?.abort();
+
+    if (!query()) {
+      setLoading(false);
+      setSearchResults([]);
+
+      return;
+    }
+
+    setAbortControllerRef(new AbortController());
+
+    try {
+      const search = await client
+        .useSignal(abortControllerRef()?.signal || null)
+        .search({ query: query() });
+
+      setSearchResults(search);
+      setLoading(false);
+
+      return;
+    } catch (error) {
+      const trpcError = error as any;
+      const causeErrorName = trpcError.cause?.name?.toLowerCase() || "";
+
+      if (!causeErrorName.includes("aborterror") && abortControllerRef()?.signal.aborted) {
+        setLoading(false);
+      }
+    }
+  }, 150);
+  const scrollToSelectedResult = (smooth?: boolean): void => {
+    const selectedResultElement = document.querySelector("[data-selected=true]");
+
+    if (selectedResultElement) {
+      scrollIntoView(selectedResultElement, {
+        behavior: smooth ? "smooth" : "instant",
+        block: "center"
+      });
+    }
+  };
+  const goToContentPiece = (searchResult: SearchResult): void => {
+    // eslint-disable-next-line no-console
+    props.setOpened(false);
+
+    const { slug } = searchResult.contentPiece;
+    const [title, subHeading1, subHeading2] = searchResult.breadcrumb;
+
+    window.location.href = `/${slug.startsWith("/") ? slug.slice(1) : slug}#${convertToSlug(
+      subHeading2 || subHeading1
+    )}`;
+  };
+
+  createEffect(
+    on(
+      query,
+      () => {
+        if (mode() === "search") {
+          search.clear();
+          search();
+        }
+      },
+      { defer: true }
+    )
+  );
+  createEffect(
+    on(mode, () => {
+      setMouseHoverEnabled(false);
+      setSelectedIndex(0);
+      setLoading(false);
+      setAnswer("");
+      setSearchResults([]);
+      setQuery("");
+    })
+  );
+  createEffect(() => {
+    if (inputRef() && props.opened && mode()) {
+      setTimeout(() => {
+        inputRef()?.focus();
+      }, 300);
+    }
+  });
+  createEffect(() => {
+    import("tinykeys").then(({ createKeybindingsHandler }) => {
+      const keyShortcutHandler = createKeybindingsHandler({
+        "$mod+KeyK": (event) => {
+          props.setOpened(!props.opened);
+        },
+        "escape": (event) => {
+          if (!props.opened) return;
+
+          props.setOpened(false);
+        },
+        "ArrowUp": (event) => {
+          if (!props.opened) return;
+
+          setMouseHoverEnabled(false);
+          event.preventDefault();
+          event.stopPropagation();
+
+          if (selectedIndex() > 0) {
+            setSelectedIndex(selectedIndex() - 1);
+            scrollToSelectedResult();
+          } else if (mode() === "search") {
+            setSelectedIndex(searchResults().length - 1);
+            scrollToSelectedResult(true);
+          }
+        },
+        "ArrowDown": (event) => {
+          if (!props.opened) return;
+
+          setMouseHoverEnabled(false);
+          event.preventDefault();
+          event.stopPropagation();
+
+          if (mode() === "search" && selectedIndex() < searchResults().length - 1) {
+            setSelectedIndex(selectedIndex() + 1);
+            scrollToSelectedResult();
+          } else {
+            setSelectedIndex(0);
+            scrollToSelectedResult(true);
+          }
+        },
+        "Enter": (event) => {
+          if (!props.opened) return;
+
+          if (mode() === "search") {
+            goToContentPiece(searchResults()[selectedIndex()]);
+          }
+        }
+      });
+
+      window.addEventListener("keydown", keyShortcutHandler);
+      onCleanup(() => {
+        window.removeEventListener("keydown", keyShortcutHandler);
+      });
+    });
+  });
+
+  const getIcon = (): string => {
+    switch (mode()) {
+      case "search":
+        return mdiMagnify;
+      case "ask":
+        return mdiHeadSnowflakeOutline;
+    }
+  };
+  const getLabel = (): string => {
+    switch (mode()) {
+      case "ask":
+        return "Just ask";
+      case "search":
+      default:
+        return "Search";
+    }
+  };
+
+  return (
+    <Overlay
+      opened={props.opened}
+      class="items-start"
+      shadeClass="bg-opacity-50"
+      wrapperClass="mt-32"
+      onOverlayClick={() => {
+        props.setOpened(false);
+      }}
+    >
+      <Card
+        class="w-2xl max-w-[calc(100vw-2rem)] max-h-[calc(100vh-16rem)] flex flex-col p-0 overflow-hidden shadow-xl"
+        color="base"
+        onPointerMove={() => {
+          setMouseHoverEnabled(true);
+        }}
+      >
+        <div class="flex w-full justify-center items-center p-2 border-b-2 dark:border-gray-700">
+          <IconButton path={getIcon()} text="soft" variant="text" badge hover={false} class="m-0" />
+          <Input
+            value={query()}
+            setValue={(value) => {
+              if (mode() === "search") {
+                setLoading(true);
+              }
+
+              setQuery(value);
+            }}
+            ref={setInputRef}
+            tabIndex={0}
+            placeholder={getLabel()}
+            wrapperClass="flex-1 m-0"
+            class="m-0 bg-transparent"
+            onEnter={() => {
+              if (mode() === "ask") {
+                setLoading(true);
+                setAnswer("");
+                ask();
+              }
+            }}
+            onKeyDown={(event) => {
+              if (event.key === "Backspace" && !query()) {
+                setMode("search");
+              }
+            }}
+            adornment={() => (
+              <Show when={mode() === "search" || mode() === "ask"}>
+                <Tooltip text="Ask" side="left" class="-ml-1">
+                  <IconButton
+                    path={mdiCreationOutline}
+                    class="m-0"
+                    text={mode() === "ask" ? "base" : "soft"}
+                    color={mode() === "ask" ? "primary" : "base"}
+                    onClick={() => {
+                      setMode((mode) => (mode === "ask" ? "search" : "ask"));
+                    }}
+                    variant="text"
+                  />
+                </Tooltip>
+              </Show>
+            )}
+          />
+        </div>
+        <div class="relative overflow-hidden">
+          <div class="flex-1 flex flex-col overflow-auto  max-h-[calc(100vh-21.5rem)] scrollbar-sm">
+            <Switch>
+              <Match when={mode() === "search"}>
+                <Show
+                  when={!loading()}
+                  fallback={
+                    <div class="flex justify-center items-center p-4">
+                      <Loader />
+                    </div>
+                  }
+                >
+                  <For
+                    each={searchResults()}
+                    fallback={
+                      <span class="p-4 text-center text-gray-500 dark:text-gray-400">
+                        <Show when={query()} fallback="Type to search">
+                          No results
+                        </Show>
+                      </span>
+                    }
+                  >
+                    {(result, index) => {
+                      return (
+                        <Card
+                          class={clsx(
+                            "flex justify-start items-center py-2 px-3 m-0 rounded-none border-none",
+                            index() === selectedIndex() &&
+                              "bg-gray-300 dark:bg-gray-700 cursor-pointer",
+                            index() !== selectedIndex() && "bg-transparent"
+                          )}
+                          color="base"
+                          onClick={() => {
+                            goToContentPiece(result);
+                          }}
+                          onPointerEnter={() => {
+                            if (!mouseHoverEnabled()) return;
+
+                            setSelectedIndex(index());
+                          }}
+                        >
+                          <div class="flex w-full">
+                            <Icon
+                              path={mdiFileDocumentOutline}
+                              class="h-6 w-6 mr-2 justify-start items-center"
+                            />
+                            <div class="flex flex-col justify-start flex-1">
+                              <p class="flex items-center justify-start flex-wrap font-semibold">
+                                <For each={result.breadcrumb}>
+                                  {(breadcrumb, index) => {
+                                    return (
+                                      <>
+                                        <Show when={index()}>
+                                          <Icon
+                                            path={mdiChevronRight}
+                                            class="flex-inline h-5 w-5 text-gray-500 dark:text-gray-400"
+                                          />
+                                        </Show>
+                                        {breadcrumb}
+                                      </>
+                                    );
+                                  }}
+                                </For>
+                              </p>
+                              <p class="prose flex-1 text-sm clamp-2 whitespace-pre-wrap text-gray-500 dark:text-gray-400">
+                                {result.content}
+                              </p>
+                            </div>
+                          </div>
+                        </Card>
+                      );
+                    }}
+                  </For>
+                </Show>
+              </Match>
+              <Match when={mode() === "ask"}>
+                <Show
+                  when={answer()}
+                  fallback={
+                    <Show
+                      when={!loading()}
+                      fallback={
+                        <div class="flex justify-center items-center p-4">
+                          <Loader />
+                        </div>
+                      }
+                    >
+                      <span class="p-4 text-center text-gray-500 dark:text-gray-400">
+                        What do you want to know?
+                      </span>
+                    </Show>
+                  }
+                >
+                  <Card
+                    class={clsx(
+                      "flex flex-col items-center py-2 px-3 m-0 rounded-none border-none"
+                    )}
+                    color="base"
+                  >
+                    <div
+                      class="flex flex-col w-full prose whitespace-pre-wrap"
+                      innerHTML={answer()}
+                    />
+                    <Show when={!loading()}>
+                      <IconButton
+                        color="contrast"
+                        text="soft"
+                        size="small"
+                        badge
+                        class="mt-4"
+                        path={mdiInformationOutline}
+                        label="The information produced may be inaccurate."
+                      />
+                    </Show>
+                  </Card>
+                </Show>
+              </Match>
+            </Switch>
+          </div>
+        </div>
+        <div class="border-t-2 dark:border-gray-700 px-2 py-1 flex gap-2 bg-gray-100 dark:bg-gray-800">
+          <div class="hidden md:flex gap-2">
+            <IconButton
+              path={mdiSwapVertical}
+              hover={false}
+              badge
+              label="Select"
+              size="small"
+              variant="text"
+              text="soft"
+            />
+            <IconButton
+              path={mdiKeyboardReturn}
+              hover={false}
+              badge
+              label="Open"
+              size="small"
+              variant="text"
+              text="soft"
+            />
+            <IconButton
+              path={mdiKeyboardEsc}
+              hover={false}
+              badge
+              label="Close"
+              size="small"
+              variant="text"
+              text="soft"
+            />
+          </div>
+          <div class="flex-1" />
+          <Button
+            size="small"
+            variant="text"
+            color={mode() === "ask" ? "primary" : "base"}
+            text={mode() === "ask" ? "base" : "soft"}
+            onClick={() => {
+              setMode((mode) => (mode === "search" ? "ask" : "search"));
+            }}
+          >
+            Ask a question
+          </Button>
+        </div>
+      </Card>
+    </Overlay>
+  );
+};
+const SearchPaletteProvider: ParentComponent = (props) => {
+  const [opened, setOpened] = createSignal(false);
+
+  createEffect(() => {
+    if (opened()) {
+      document.body.style.overflow = "hidden";
+    } else {
+      document.body.style.overflow = "auto";
+    }
+  });
+
+  return (
+    <SearchPaletteContext.Provider
+      value={{
+        opened,
+        setOpened
+      }}
+    >
+      {props.children}
+      <SearchPalette opened={opened()} setOpened={setOpened} />
+    </SearchPaletteContext.Provider>
+  );
+};
+const useSearchPalette = (): SearchPaletteContextData => {
+  return useContext(SearchPaletteContext)!;
+};
+
+export { SearchPaletteProvider, useSearchPalette };

programming_language: TypeScript
filename: side-bar.tsx
change_type: ModificationType.MODIFY
diff: @@ -1,50 +1,40 @@
-import { mdiMenu, mdiClose, mdiGithub, mdiChevronDown, mdiCodeJson } from "@mdi/js";
+import { mdiMenu, mdiClose, mdiChevronDown } from "@mdi/js";
 import clsx from "clsx";
-import { Component, For, JSX, createSignal } from "solid-js";
+import { Component, For, JSX, createEffect, createSignal } from "solid-js";
 import { menuOpened, setMenuOpened } from "#lib/state";
 import { Card, Button, IconButton } from "#components/primitives";
-import { discordIcon } from "#assets/icons";
 import { logoIcon } from "#assets/icons/logo";
 
 interface SideBarProps {
-  menu: Array<{
+  currentSection: string;
+  sections: Array<{
     label: string;
-    menu: Array<{ label: string; link: string }>;
+    icon: string;
+    link: string;
+    id: string;
   }>;
+  menu: Record<
+    string,
+    Array<{
+      label: string;
+      menu: Array<{ label: string; link?: string; menu?: Array<{ label: string; link: string }> }>;
+    }>
+  >;
   currentPath: string;
 }
-
-const externalLinks = [
-  {
-    label: "GitHub",
-    icon: mdiGithub,
-    href: "https://github.com/vriteio/vrite"
-  },
-  {
-    label: "Discord",
-    icon: discordIcon,
-    href: "https://discord.gg/yYqDWyKnqE"
-  },
-  {
-    label: "Vrite Cloud",
-    icon: logoIcon,
-    href: "https://app.vrite.io"
-  },
-  {
-    label: "API Reference",
-    icon: mdiCodeJson,
-    href: "https://generator.swagger.io/?url=https://api.vrite.io/swagger.json#"
-  }
-];
-const SideBarNestedMenu: Component<{
-  menu: Array<{ label: string; link: string; menu?: Array<{ label: string; link: string }> }>;
+interface SideBarNestedMenuProps {
+  menu: Array<{ label: string; link?: string; menu?: Array<{ label: string; link: string }> }>;
   currentPath: string;
   children: JSX.Element;
-}> = (props) => {
+  openedByDefault?: boolean;
+}
+
+const SideBarNestedMenu: Component<SideBarNestedMenuProps> = (props) => {
   const [opened, setOpened] = createSignal(
-    props.menu.filter((item) => {
-      return props.currentPath.includes(item.link);
-    }).length > 0
+    props.openedByDefault ||
+      props.menu.filter((item) => {
+        return item.link && props.currentPath.includes(item.link);
+      }).length > 0
   );
 
   return (
@@ -87,7 +77,7 @@ const SideBarNestedMenu: Component<{
               }
 
               const active = (): boolean => {
-                return props.currentPath.includes(item.link);
+                return Boolean(item.link && props.currentPath.includes(item.link));
               };
 
               return (
@@ -109,6 +99,14 @@ const SideBarNestedMenu: Component<{
   );
 };
 const SideBar: Component<SideBarProps> = (props) => {
+  createEffect(() => {
+    if (menuOpened()) {
+      document.body.style.overflow = "hidden";
+    } else {
+      document.body.style.overflow = "auto";
+    }
+  });
+
   return (
     <>
       <div class={clsx("h-full fixed top-0 left-0 z-1", "pl-[max(0px,calc((100%-1536px)/2))]")}>
@@ -117,7 +115,7 @@ const SideBar: Component<SideBarProps> = (props) => {
             "top-0 h-full z-50 min-w-80 w-full md:max-w-80 m-0 bg-gray-100 dark:bg-gray-900",
             "flex-col gap-2 justify-start items-start border-0 md:border-r-2 rounded-none flex fixed md:relative",
             "transform md:transition-transform duration-300 ease-in-out scrollbar-sm-contrast overflow-auto",
-            menuOpened() ? "" : "translate-y-full md:translate-y-0"
+            menuOpened() ? "" : "translate-y-[100vh] md:translate-y-0"
           )}
         >
           <div class="flex items-center justify-start px-1 pb-4 pt-2">
@@ -135,31 +133,35 @@ const SideBar: Component<SideBarProps> = (props) => {
             </span>
           </div>
           <div class="flex flex-col gap-2 pl-1 w-full py-4">
-            <For each={externalLinks}>
-              {(link) => {
+            <For each={props.sections}>
+              {(section) => {
                 return (
                   <a
                     class="flex justify-start items-center group w-full cursor-pointer"
-                    target="_blank"
-                    href={link.href}
+                    target={section.link.startsWith("http") ? "_blank" : "_self"}
+                    href={section.link}
                   >
                     <IconButton
-                      path={link.icon}
+                      path={section.icon}
                       class="m-0 group-hover:bg-gray-300 dark:group-hover:bg-gray-700 h-8 w-8"
                       iconProps={{ class: "h-5 w-5" }}
-                      color="contrast"
-                      text="soft"
+                      color={section.id === props.currentSection ? "primary" : "contrast"}
+                      text={section.id === props.currentSection ? "primary" : "soft"}
                     />
-                    <span class=" ml-2 text-gray-500 dark:text-gray-400">{link.label}</span>
+                    <span class=" ml-2 text-gray-500 dark:text-gray-400">{section.label}</span>
                   </a>
                 );
               }}
             </For>
           </div>
-          <For each={props.menu}>
+          <For each={props.menu[props.currentSection]}>
             {(menuItem) => {
               return (
-                <SideBarNestedMenu currentPath={props.currentPath} menu={menuItem.menu}>
+                <SideBarNestedMenu
+                  currentPath={props.currentPath}
+                  menu={menuItem.menu}
+                  openedByDefault
+                >
                   <Button
                     variant="text"
                     class="justify-start w-full font-bold m-0"

programming_language: TypeScript
filename: default.astro
change_type: ModificationType.MODIFY
diff: @@ -1,35 +1,107 @@
 ---
-import { Header, BaseHead, SideBar, SVGDefs, OnThisPage } from "#components/fragments";
+import { Header, BaseHead, SideBar, SVGDefs, OnThisPage, Footer } from "#components/fragments";
 import type { MarkdownHeading } from "astro";
 import menu from "./menu.json";
+import { Button } from "#components/primitives";
+import { mdiBookOpenBlankVariant, mdiConsoleLine, mdiTextBoxMultiple } from "@mdi/js";
 
 const image = "https://docs.vrite.io/meta-image.png";
 const title = "Vrite － developer content platform";
 const description =
   "Open-Source, collaborative developer content platform for documentation, technical blogs, and more.";
+const flattenMenu = (
+  menu: Array<{
+    label: string;
+    link?: string;
+    menu?: Array<{ label: string; link: string }>;
+  }>,
+  section: string,
+  labels: string[]
+): Array<{ label: string; link: string; section: string; labels: string[] }> => {
+  return menu.flatMap((item) => {
+    if (item.link) {
+      return [{ label: item.label, link: item.link, section, labels: [...labels, item.label] }];
+    }
+    if (item.menu) {
+      return flattenMenu(item.menu, section, [...labels, item.label]);
+    }
+    return [];
+  });
+};
+const sections = [
+  {
+    label: "Documentation",
+    link: "/usage-guide/getting-started",
+    icon: mdiBookOpenBlankVariant,
+    id: "docs"
+  },
+  {
+    label: "API reference",
+    link: "https://generator.swagger.io/?url=https://api.vrite.io/swagger.json",
+    icon: mdiConsoleLine,
+    id: "api"
+  }
+  /*{
+    label: "Recipes",
+    link: "/self-hosting/docker",
+    icon: mdiTextBoxMultiple,
+    id: "recipes"
+  }*/
+];
+const flatMenu = [
+  ...flattenMenu(menu.docs, "docs", []),
+  ...flattenMenu(menu.recipes, "recipes", [])
+];
+const currentEntry = flatMenu.find((item) => item.link === Astro.url.pathname);
+const nextEntry = currentEntry ? flatMenu[flatMenu.indexOf(currentEntry) + 1] : null;
+const prevEntry = currentEntry ? flatMenu[flatMenu.indexOf(currentEntry) - 1] : null;
 
 type Props = {
   headings: MarkdownHeading[];
   title: string;
+  description?: string;
 };
 ---
 
 <!DOCTYPE html>
 <html lang="en">
   <head>
-    <BaseHead description={description} title={title} image={image} />
+    <BaseHead
+      description={Astro.props.description || description}
+      title={Astro.props.title ? `${Astro.props.title} | Vrite Documentation` : title}
+      image={image}
+    />
   </head>
   <body class="overflow-x-hidden overscroll-none">
     <SVGDefs />
     <main class="flex flex-col items-center justify-center bg-gray-50 dark:bg-gray-800">
       <div class="flex-1 flex justify-center items-center flex-1 w-full max-w-screen-2xl relative">
-        <SideBar menu={menu} currentPath={Astro.url.pathname} client:load />
-        <div class="flex overflow-hidden w-full relative h-full">
-          <div class="flex-1 flex overflow-y-auto overflow-x-hidden justify-center" id="container">
+        <Header client:load />
+        <SideBar
+          menu={menu}
+          sections={sections}
+          currentSection={currentEntry?.section || "docs"}
+          currentPath={Astro.url.pathname}
+          client:load
+        />
+        <div class="flex overflow-hidden w-full relative h-full pt-12">
+          <div
+            class="flex-1 flex overflow-y-auto overflow-x-hidden justify-center min-h-[calc(100vh-3rem)]"
+            id="container"
+          >
             <div
-              class="flex-1 prose max-w-screen-md w-full text-lg px-4 pt-4 pb-24 h-fit xl:w-[calc(100%-15rem)]"
+              class="flex-1 prose max-w-screen-md w-full text-lg px-4 md:px-8 pt-4 pb-24 h-fit xl:w-[calc(100%-15rem)]"
             >
+              {
+                (currentEntry?.labels.length || 0) > 1 && (
+                  <Button badge color="primary" variant="text" class="m-0 pl-1 py-0" hover={false}>
+                    {currentEntry?.labels.at(-2)}
+                  </Button>
+                )
+              }
+              <h1>{Astro.props.title}</h1>
               <slot />
+              <Footer nextEntry={nextEntry} previousEntry={prevEntry} />
             </div>
             <OnThisPage headings={Astro.props.headings} client:load />
           </div>

programming_language: TypeScript
filename: menu.json
change_type: ModificationType.MODIFY
diff: @@ -1,53 +1,60 @@
-[
-  {
-    "label": "Usage Guide",
-    "menu": [
-      {
-        "label": "Getting Started",
-        "link": "/usage-guide/getting-started"
-      },
-      {
-        "label": "Managing Content with Kanban",
-        "link": "/usage-guide/kanban-dashboard"
-      },
-      {
-        "label": "Managing metadata",
-        "link": "/usage-guide/metadata"
-      },
-      {
-        "label": "Writing in the Vrite Editor",
-        "link": "/usage-guide/content-editor"
-      },
-      {
-        "label": "Configuring Vrite",
-        "link": "/usage-guide/configuring-vrite"
-      },
-      {
-        "label": "Publishing content",
-        "link": "/usage-guide/publishing"
-      }
-    ]
-  },
-  {
-    "label": "JavaScript SDK",
-    "menu": [
-      {
-        "label": "Introduction",
-        "link": "/javascript-sdk/javascript-sdk"
-      }
-    ]
-  },
-  {
-    "label": "Self-Hosting",
-    "menu": [
-      {
-        "label": "Docker",
-        "link": "/self-hosting/docker"
-      },
-      {
-        "label": "Configuration",
-        "link": "/self-hosting/configuration"
-      }
-    ]
-  }
-]
+{
+  "docs": [
+    {
+      "label": "Usage Guide",
+      "menu": [
+        {
+          "label": "Getting Started",
+          "link": "/usage-guide/getting-started"
+        },
+        {
+          "label": "Managing Content with Kanban",
+          "link": "/usage-guide/kanban-dashboard"
+        },
+        {
+          "label": "Managing metadata",
+          "link": "/usage-guide/metadata"
+        },
+        {
+          "label": "Writing in the Vrite Editor",
+          "link": "/usage-guide/content-editor"
+        },
+        {
+          "label": "Configuring Vrite",
+          "link": "/usage-guide/configuring-vrite"
+        },
+        {
+          "label": "Publishing content",
+          "link": "/usage-guide/publishing"
+        },
+        {
+          "label": "Vrite Extensions",
+          "link": "/usage-guide/vrite-extensions"
+        }
+      ]
+    },
+    {
+      "label": "JavaScript SDK",
+      "menu": [
+        {
+          "label": "Introduction",
+          "link": "/javascript-sdk/introduction"
+        }
+      ]
+    },
+    {
+      "label": "Self-Hosting",
+      "menu": [
+        {
+          "label": "Docker",
+          "link": "/self-hosting/docker"
+        },
+        {
+          "label": "Configuration",
+          "link": "/self-hosting/configuration"
+        }
+      ]
+    }
+  ],
+  "recipes": []
+}

programming_language: TypeScript
filename: config.ts
change_type: ModificationType.MODIFY
diff: @@ -1,10 +1,22 @@
 import { z, defineCollection } from "astro:content";
 
 const docsCollection = defineCollection({
-  type: "content"
+  type: "content",
+  schema: z.object({
+    title: z.string().optional(),
+    description: z.string().optional()
+  })
+});
+const recipesCollection = defineCollection({
+  type: "content",
+  schema: z.object({
+    title: z.string().optional(),
+    description: z.string().optional()
+  })
 });
 const collections = {
-  docs: docsCollection
+  docs: docsCollection,
+  recipes: recipesCollection
 };
 
 export { collections };

programming_language: JavaScript
filename: javascript-sdk.md
change_type: ModificationType.MODIFY
diff: @@ -1,3 +1,8 @@
+---
+title: "Introduction"
+slug: "javascript-sdk/introduction"
+---
+
 [Vrite JavaScript SDK](https://github.com/vriteio/vrite/tree/main/packages/sdk/javascript) is a one-stop-shop when building any kind of Vrite-powered website or web app.
 
 Currently it includes the following parts:

programming_language: Markdown
filename: configuration.md
change_type: ModificationType.MODIFY
diff: @@ -1,3 +1,8 @@
+---
+title: "Configuring Self-Hosted Vrite"
+slug: "self-hosting/configuration"
+---
+
 To properly host Vrite, you first have to configure a couple of environment variables. This guide aims to give you an overview of the available options.
 
 ## Security

programming_language: Markdown
filename: docker.md
change_type: ModificationType.MODIFY
diff: @@ -1,3 +1,8 @@
+---
+title: "Self-Hosting Vrite with Docker"
+slug: "self-hosting/docker"
+---
+
 Vrite aims to provide the best and most accessible technical writing experience. To do so, we provide both a ready, [easy-to-use “Vrite Cloud” instance](https://app.vrite.io/), as well as an option for you to **self-host Vrite** on your own servers.
 
 The recommended way to self-host Vrite is with [Docker](https://docs.docker.com/engine/install/) and [Docker Compose](https://docs.docker.com/compose/install/) - both of which you need to have installed on your machine.

programming_language: Markdown
filename: configuring-vrite.md
change_type: ModificationType.MODIFY
diff: @@ -1,3 +1,8 @@
+---
+title: "Configuring Vrite"
+slug: "usage-guide/configuring-vrite"
+---
+
 Everything related to configuring Vrite can be done from the settings side panel. From managing API tokens to customizing the editing experience — all can be managed in the settings.
 
 It’s worth noting that there are 2 categories of settings in Vrite:

programming_language: Markdown
filename: content-editor.md
change_type: ModificationType.MODIFY
diff: @@ -1,3 +1,8 @@
+---
+title: "Writing in Vrite Editor"
+slug: "/usage-guide/content-editor"
+---
+
 The content editor is the core part of Vrite — this is where you can create your next technical masterpiece. And, thanks to all the features, formatting options, and content blocks Vrite supports - it should be a breeze!
 
 ## Editing Menus

programming_language: Markdown
filename: getting-started.md
change_type: ModificationType.MODIFY
diff: @@ -1,3 +1,8 @@
+---
+title: "Getting Started"
+slug: "/usage-guide/getting-started"
+---
+
 **Vrite** (Public Beta) is a headless CMS, made with technical, programming-related content in mind. Combining great project management frameworks like Kanban with a state-of-the-art WYSIWYG editor and support for real-time collaboration, Vrite is a CMS unlike any other.
 
 ## Vrite’s Features

programming_language: Markdown
filename: kanban-dashboard.md
change_type: ModificationType.MODIFY
diff: @@ -1,3 +1,8 @@
+---
+title: "Managing Content in Kanban"
+slug: "/usage-guide/kanban-dashboard"
+---
+
 Managing content using traditional CMS tools is hard. Basic lists or tables just don’t cut it. It's especially difficult when working in teams or depending on a complex content production pipeline. You end up using many different tools, switching and copy-pasting between them, experiencing degraded UX, and losing time.
 
 That's why Vrite approaches content management differently — by implementing a **Kanban dashboard** many developers and project managers are familiar with and enjoy using.

programming_language: Markdown
filename: metadata.md
change_type: ModificationType.MODIFY
diff: @@ -1,3 +1,8 @@
+---
+title: "Managing Metadata"
+slug: "/usage-guide/metadata"
+---
+
 After the actual content, **metadata** is probably some of the most important information you have to manage in your CMS. In Vrite, metadata — part of a content piece — can be managed from the **metadata side panel**.
 
 ## Metadata Side Panel

programming_language: Markdown
filename: publishing.md
change_type: ModificationType.MODIFY
diff: @@ -1,3 +1,8 @@
+---
+title: "Publishing Content"
+slug: "/usage-guide/publishing"
+---
+
 With Vrite’s unique features like Kanban-based content management, the actual publishing flow is quite unique. All you have to do to publish a piece can be just drag and drop.
 
 ## Dedicated Content Group

programming_language: Markdown
filename: vrite-extensions.md
change_type: ModificationType.MODIFY
diff: @@ -1,3 +1,8 @@
+---
+title: "Vrite Extensions"
+slug: "/usage-guide/vrite-extensions"
+---
+
 Vrite Extensions are meant to make Vrite both more customizable and easier to use. With direct access to Vrite API and the ability to extend Vrite’s UI, they have the ability to vastly improve your experience with Vrite.
 
 The Extensions specification and related APIs are in the early stages and we continue to stabilize and improve them. The goal is to create a platform that all users can build on. However, for now, only first-party extensions are available, which include:

programming_language: Markdown
filename: test.mdx
change_type: ModificationType.ADD
diff: @@ -0,0 +1,6 @@
+---
+title: "Content Pieces API"
+slug: "/recipes/content-pieces"
+---
+
+Content

programming_language: Markdown
filename: env.d.ts
change_type: ModificationType.MODIFY
diff: @@ -1,2 +1,9 @@
 /// <reference path="../.astro/types.d.ts" />
 /// <reference types="astro/client" />
+interface ImportMetaEnv {
+  readonly PUBLIC_VRITE_SEARCH_TOKEN: string;
+}
+
+interface ImportMeta {
+  readonly env: ImportMetaEnv;
+}

programming_language: TypeScript
filename: [...slug].astro
change_type: ModificationType.MODIFY
diff: @@ -13,14 +13,21 @@ const { Content, headings } = await entry.render();
 
 export const prerender = true;
 export async function getStaticPaths() {
-  const blogEntries = await getCollection("docs");
-  return blogEntries.map((entry) => ({
-    params: { slug: entry.slug },
-    props: { entry }
-  }));
+  const docsEntries = await getCollection("docs");
+  const recipesEntries = await getCollection("recipes");
+  return [
+    ...docsEntries.map((entry) => ({
+      params: { slug: entry.slug },
+      props: { entry }
+    })),
+    ...recipesEntries.map((entry) => ({
+      params: { slug: entry.slug },
+      props: { entry }
+    }))
+  ];
 }
 ---
 
-<DefaultLayout headings={headings} title={entry.data.title}>
+<DefaultLayout headings={headings} title={entry.data.title} description={entry.data.description}>
   <Content />
 </DefaultLayout>

programming_language: TypeScript
filename: base.css
change_type: ModificationType.MODIFY
diff: @@ -176,3 +176,31 @@ h2 {
     scrollbar-color: #1e293b #0f172a;
   }
 }
+
+.clamp-1 {
+  overflow: hidden;
+  text-overflow: ellipsis;
+  display: -webkit-box;
+  overflow-wrap: break-word;
+  -webkit-line-clamp: 1;
+  line-clamp: 1;
+  -webkit-box-orient: vertical;
+}
+.clamp-2 {
+  overflow: hidden;
+  text-overflow: ellipsis;
+  display: -webkit-box;
+  overflow-wrap: break-word;
+  -webkit-line-clamp: 2;
+  line-clamp: 2;
+  -webkit-box-orient: vertical;
+}
+.clamp-3 {
+  overflow: hidden;
+  text-overflow: ellipsis;
+  display: -webkit-box;
+  overflow-wrap: break-word;
+  -webkit-line-clamp: 3;
+  line-clamp: 3;
+  -webkit-box-orient: vertical;
+}

programming_language: CSS
filename: styles.scss
change_type: ModificationType.MODIFY
diff: @@ -6,14 +6,23 @@
     @apply border-transparent dark:border-transparent;
   }
 }
-
+.font-jetbrains {
+  font-family: "JetBrainsMonoVariable", monospace;
+}
 kbd {
   font-family: "JetBrainsMonoVariable", monospace;
 }
 #side-panel > div {
   height: 100%;
 }
-
+svg > path {
+  fill: inherit;
+}
+.grid-reset-margin {
+  & > * {
+    margin: 0;
+  }
+}
 .resize-cursor {
   cursor: ew-resize;
   cursor: col-resize;
@@ -101,64 +110,23 @@ kbd {
 
   font-kerning: none;
   :where(h1, h2, h3, h4, h5, h6):not(:where(.not-prose, .not-prose *)) {
-    &::before,
-    &::before,
-    &::before,
-    &::before,
-    &::before,
-    &::before,
-    .open-slash-menu > button {
-      @apply font-bold dark:bg-gray-900 dark:border-gray-700;
-      position: absolute;
-      left: -2.5rem;
-      background: #f9fafb;
-      height: 2rem;
-      width: 2rem;
-      justify-content: center;
-      display: flex;
-      align-items: center;
-      color: #6b7280;
-      border-radius: 25%;
-      font-size: 1rem;
-      line-height: 1rem;
-      text-align: center;
-      top: 50%;
-      transform: translateY(-50%);
-      //border: 2px solid #e5e7eb;
-      @apply border-2;
-      opacity: 1;
-    }
+    @apply relative;
+    margin: 0 !important;
   }
-
-  h1,
-  h2,
-  h3,
-  h4,
-  h5,
-  h6,
-  .open-slash-menu {
-    @apply m-0 relative;
-    & > button {
-      @apply mt-4;
+  :where(h2, h3):not(:where(.not-prose, .not-prose *)) {
+    @apply hover:cursor-pointer;
+    &::before {
+      @apply hidden md:block absolute pr-6 -left-6 transform scale-90 text-gray-500 dark:text-gray-400 opacity-0;
+      content: "#";
     }
-  }
-  .open-slash-menu {
-    button {
-      font-size: 1.25em;
-      line-height: 1.25em;
-      font-weight: 600;
+    &:hover::before {
+      @apply opacity-100;
     }
   }
-  :where(h4):not(:where(.not-prose, .not-prose *)) {
-    line-height: 2.1rem;
-  }
-  :where(h5):not(:where(.not-prose, .not-prose *)) {
-    line-height: 2.1rem;
-  }
-  :where(h6):not(:where(.not-prose, .not-prose *)) {
-    font-size: 0.875em;
-    line-height: 2.1rem;
+  h3:not(:where(.not-prose, .not-prose *))::before {
+    @apply pr-5 -left-5;
   }
+
   :where(ul p, ol p):not(:where(.not-prose, .not-prose *)) {
     @apply m-0;
   }

programming_language: CSS
filename: package.json
change_type: ModificationType.MODIFY
diff: @@ -58,7 +58,7 @@
     "dompurify": "^3.0.5",
     "marked": "^5.1.2",
     "minisearch": "^6.1.0",
-    "monaco-editor": "^0.40.0",
+    "monaco-editor": "^0.43.0",
     "nanoevents": "^8.0.0",
     "nanoid": "^4.0.2",
     "prettier": "^3.0.2",

programming_language: HTML
filename: sandbox.js
change_type: ModificationType.MODIFY
diff: @@ -143,8 +143,8 @@
           var string = "";
           var bitsNeeded = this.bitsNeeded;
           var codePoint = this.codePoint;
-          for (var i2 = 0; i2 < octets.length; i2 += 1) {
-            var octet = octets[i2];
+          for (var i = 0; i < octets.length; i += 1) {
+            var octet = octets[i];
             if (bitsNeeded !== 0) {
               if (octet < 128 || octet > 191 || !valid(codePoint << 6 | octet & 63, bitsNeeded - 6, octetsCount(bitsNeeded, codePoint))) {
                 bitsNeeded = 0;
@@ -417,8 +417,8 @@
         function HeadersPolyfill(all) {
           var map = /* @__PURE__ */ Object.create(null);
           var array = all.split("\r\n");
-          for (var i2 = 0; i2 < array.length; i2 += 1) {
-            var line = array[i2];
+          for (var i = 0; i < array.length; i += 1) {
+            var line = array[i];
             var parts = line.split(": ");
             var name = parts.shift();
             var value = parts.join(": ");
@@ -539,8 +539,8 @@
           var typeListeners = this._listeners[event.type];
           if (typeListeners != void 0) {
             var length = typeListeners.length;
-            for (var i2 = 0; i2 < length; i2 += 1) {
-              var listener = typeListeners[i2];
+            for (var i = 0; i < length; i += 1) {
+              var listener = typeListeners[i];
               try {
                 if (typeof listener.handleEvent === "function") {
                   listener.handleEvent(event);
@@ -562,8 +562,8 @@
             listeners[type] = typeListeners;
           }
           var found = false;
-          for (var i2 = 0; i2 < typeListeners.length; i2 += 1) {
-            if (typeListeners[i2] === listener) {
+          for (var i = 0; i < typeListeners.length; i += 1) {
+            if (typeListeners[i] === listener) {
               found = true;
             }
           }
@@ -577,9 +577,9 @@
           var typeListeners = listeners[type];
           if (typeListeners != void 0) {
             var filtered = [];
-            for (var i2 = 0; i2 < typeListeners.length; i2 += 1) {
-              if (typeListeners[i2] !== listener) {
-                filtered.push(typeListeners[i2]);
+            for (var i = 0; i < typeListeners.length; i += 1) {
+              if (typeListeners[i] !== listener) {
+                filtered.push(typeListeners[i]);
               }
             }
             if (filtered.length === 0) {
@@ -722,10 +722,10 @@
           var onProgress = function(textChunk) {
             if (currentState === OPEN) {
               var n = -1;
-              for (var i2 = 0; i2 < textChunk.length; i2 += 1) {
-                var c = textChunk.charCodeAt(i2);
+              for (var i = 0; i < textChunk.length; i += 1) {
+                var c = textChunk.charCodeAt(i);
                 if (c === "\n".charCodeAt(0) || c === "\r".charCodeAt(0)) {
-                  n = i2;
+                  n = i;
                 }
               }
               var chunk = (n !== -1 ? textBuffer : "") + textChunk.slice(0, n + 1);
@@ -879,8 +879,8 @@
             var requestURL = url;
             if (url.slice(0, 5) !== "data:" && url.slice(0, 5) !== "blob:") {
               if (lastEventId !== "") {
-                var i2 = url.indexOf("?");
-                requestURL = i2 === -1 ? url : url.slice(0, i2 + 1) + url.slice(i2 + 1).replace(/(?:^|&)([^=&]*)(?:=[^&]*)?/g, function(p, paramName) {
+                var i = url.indexOf("?");
+                requestURL = i === -1 ? url : url.slice(0, i + 1) + url.slice(i + 1).replace(/(?:^|&)([^=&]*)(?:=[^&]*)?/g, function(p, paramName) {
                   return paramName === lastEventIdQueryParameterName ? "" : p;
                 });
                 requestURL += (url.indexOf("?") === -1 ? "?" : "&") + lastEventIdQueryParameterName + "=" + encodeURIComponent(lastEventId);
@@ -957,7 +957,7 @@
     "../../node_modules/.pnpm/unfetch@4.2.0/node_modules/unfetch/dist/unfetch.js"(exports, module) {
       module.exports = function(e, n) {
         return n = n || {}, new Promise(function(t, r) {
-          var s = new XMLHttpRequest(), o = [], u2 = [], i2 = {}, a = function() {
+          var s = new XMLHttpRequest(), o = [], u2 = [], i = {}, a = function() {
             return { ok: 2 == (s.status / 100 | 0), statusText: s.statusText, status: s.status, url: s.responseURL, text: function() {
               return Promise.resolve(s.responseText);
             }, json: function() {
@@ -969,14 +969,14 @@
             }, entries: function() {
               return u2;
             }, get: function(e2) {
-              return i2[e2.toLowerCase()];
+              return i[e2.toLowerCase()];
             }, has: function(e2) {
-              return e2.toLowerCase() in i2;
+              return e2.toLowerCase() in i;
             } } };
           };
           for (var l2 in s.open(n.method || "get", e, true), s.onload = function() {
             s.getAllResponseHeaders().replace(/^(.*?):[^\S\n]*([\s\S]*?)$/gm, function(e2, n2, t2) {
-              o.push(n2 = n2.toLowerCase()), u2.push([n2, t2]), i2[n2] = i2[n2] ? i2[n2] + "," + t2 : t2;
+              o.push(n2 = n2.toLowerCase()), u2.push([n2, t2]), i[n2] = i[n2] ? i[n2] + "," + t2 : t2;
             }), t(a());
           }, s.onerror = r, s.withCredentials = "include" == n.credentials, n.headers)
             s.setRequestHeader(l2, n.headers[l2]);
@@ -996,74 +996,83 @@
   // ../../packages/sdk/javascript/dist/api.mjs
   var api_exports = {};
   __export(api_exports, {
-    createClient: () => B
+    createClient: () => M
   });
-  var import_eventsource, i, w, $, U, f, g, L, d, S, D, O, E, R, C, x, m, I, h, j, v, k, q, l, A, u, z, B;
+  var import_eventsource, l, U, E, S, f, h, L, m, D, O, R, T, x, C, I, u, v, k, j, q, G, A, b, z, y, B, M;
   var init_api = __esm({
     "../../packages/sdk/javascript/dist/api.mjs"() {
       import_eventsource = __toESM(require_browser(), 1);
-      i = "/content-groups";
-      w = (t) => ({ get: (e) => t("GET", `${i}`, { params: e }), list: (e) => t("GET", `${i}/list`, { params: e }), create: (e) => t("POST", `${i}`, { body: e }), update: (e) => t("PUT", `${i}`, { body: e }), delete: (e) => t("DELETE", `${i}`, { params: e }) });
-      $ = "/content-pieces";
-      U = (t) => ({ get: (e) => t("GET", `${$}`, { params: e }), create: (e) => t("POST", `${$}`, { body: e }), update: (e) => t("PUT", `${$}`, { body: e }), delete: (e) => t("DELETE", `${$}`, { params: e }), list: (e) => t("GET", `${$}/list`, { params: e }) });
+      l = "/content-groups";
+      U = (t) => ({ get: (e) => t("GET", `${l}`, { params: e }), list: (e) => t("GET", `${l}/list`, { params: e }), create: (e) => t("POST", `${l}`, { body: e }), update: (e) => t("PUT", `${l}`, { body: e }), delete: (e) => t("DELETE", `${l}`, { params: e }) });
+      E = "/content-pieces";
+      S = (t) => ({ get: (e) => t("GET", `${E}`, { params: e }), create: (e) => t("POST", `${E}`, { body: e }), update: (e) => t("PUT", `${E}`, { body: e }), delete: (e) => t("DELETE", `${E}`, { params: e }), list: (e) => t("GET", `${E}/list`, { params: e }) });
       f = (t) => {
-        let e = t.baseURL || "https://api.vrite.io", n = t.extensionId || "", c = t.headers || {}, { token: s } = t;
-        return { sendRequest: async (a, p, r) => {
+        let e = t.baseURL || "https://api.vrite.io", c = t.extensionId || "", i = t.headers || {}, $ = null, { token: p } = t;
+        return { sendRequest: async (s, a, n) => {
           try {
-            const { default: o } = await Promise.resolve().then(() => __toESM(require_browser2(), 1)), y = await o(`${e}${p}/?${encodeURI(Object.entries(r?.params || {}).filter(([, b]) => b).map(([b, G]) => `${b}=${G}`).join("&"))}`, { headers: { Authorization: `Bearer ${s}`, Accept: "application/json", ...r?.body ? { "Content-Type": "application/json" } : {}, ...n ? { "X-Vrite-Extension-ID": n } : {}, ...c }, body: r?.body ? JSON.stringify(r.body) : null, method: a });
-            let T = null;
+            const { default: o } = await Promise.resolve().then(() => __toESM(require_browser2(), 1)), d = await o(`${e}${a}/?${encodeURI(Object.entries(n?.params || {}).filter(([, g]) => g).map(([g, w]) => `${g}=${w}`).join("&"))}`, { headers: { Authorization: `Bearer ${p}`, Accept: "application/json", ...n?.body ? { "Content-Type": "application/json" } : {}, ...c ? { "X-Vrite-Extension-ID": c } : {}, ...i }, body: n?.body ? JSON.stringify(n.body) : null, signal: $, method: s });
+            $ = null;
+            let r = null;
             try {
-              if (T = await y.json(), !T)
+              if (r = await d.json(), !r)
                 return;
             } catch {
               return;
             }
-            if (!y.ok)
-              throw T;
-            return T;
+            if (!d.ok)
+              throw r;
+            return r;
           } catch (o) {
             throw console.error(o), o;
           }
-        }, reconfigure: (a) => {
-          e = a.baseURL || e, s = a.token || s, n = a.extensionId || n, c = a.headers || c;
-        }, getConfig: () => ({ baseURL: e, token: s, extensionId: n, headers: c }) };
+        }, reconfigure: (s) => {
+          e = s.baseURL || e, p = s.token || p, c = s.extensionId || c, i = s.headers || i;
+        }, useSignal: (s) => {
+          $ = s;
+        }, getConfig: () => ({ baseURL: e, token: p, extensionId: c, headers: i }), getSignal: () => $ };
       };
-      g = "/user-settings";
-      L = (t) => ({ get: () => t("GET", `${g}`), update: (e) => t("PUT", `${g}`, { body: e }) });
-      d = "/tags";
-      S = (t) => ({ get: (e) => t("GET", `${d}`, { params: e }), update: (e) => t("PUT", `${d}`, { body: e }), create: (e) => t("PUT", `${d}`, { body: e }), delete: (e) => t("DELETE", `${d}`, { params: e }), list: (e) => t("GET", `${d}/list`, { params: e }) });
-      D = "/profile";
-      O = (t) => ({ get: () => t("GET", `${D}`) });
-      E = "/webhooks";
-      R = (t) => ({ get: (e) => t("GET", `${E}`, { params: e }), create: (e) => t("POST", `${E}`, { body: e }), update: (e) => t("PUT", `${E}`, { body: e }), delete: (e) => t("DELETE", `${E}`, { params: e }), list: (e) => t("GET", `${E}/list`, { params: e }) });
+      h = "/user-settings";
+      L = (t) => ({ get: () => t("GET", `${h}`), update: (e) => t("PUT", `${h}`, { body: e }) });
+      m = "/tags";
+      D = (t) => ({ get: (e) => t("GET", `${m}`, { params: e }), update: (e) => t("PUT", `${m}`, { body: e }), create: (e) => t("PUT", `${m}`, { body: e }), delete: (e) => t("DELETE", `${m}`, { params: e }), list: (e) => t("GET", `${m}/list`, { params: e }) });
+      O = "/profile";
+      R = (t) => ({ get: () => t("GET", `${O}`) });
+      T = "/webhooks";
+      x = (t) => ({ get: (e) => t("GET", `${T}`, { params: e }), create: (e) => t("POST", `${T}`, { body: e }), update: (e) => t("PUT", `${T}`, { body: e }), delete: (e) => t("DELETE", `${T}`, { params: e }), list: (e) => t("GET", `${T}/list`, { params: e }) });
       C = "/workspace";
-      x = (t) => ({ get: () => t("GET", `${C}`) });
-      m = "/roles";
-      I = (t) => ({ get: (e) => t("GET", `${m}`, { params: e }), create: (e) => t("POST", `${m}`, { body: e }), update: (e) => t("PUT", `${m}`, { body: e }), delete: (e) => t("DELETE", `${m}`, { params: e }), list: (e) => t("GET", `${m}/list`, { params: e }) });
-      h = "/workspace-settings";
-      j = (t) => ({ get: () => t("GET", `${h}`), update: (e) => t("PUT", `${h}`, { body: e }) });
-      v = (t) => ({ listMembers: (e) => t("GET", "/workspace-memberships/list-members", { params: e }), listWorkspaces: (e) => t("GET", "/workspace-memberships/list-workspaces", { params: e }), create: (e) => t("POST", "/workspace-memberships", { body: e }), update: (e) => t("PUT", "/workspace-memberships", { body: e }), delete: (e) => t("DELETE", "/workspace-memberships", { params: e }) });
-      k = "/extension";
-      q = (t) => ({ get: () => t("GET", `${k}`), updateContentPieceData: (e) => t("POST", `${k}/content-piece-data`, { body: e }) });
-      l = "/variants";
-      A = (t) => ({ create: (e) => t("POST", `${l}`, { body: e }), update: (e) => t("PUT", `${l}`, { body: e }), delete: (e) => t("DELETE", `${l}`, { params: e }), list: () => t("GET", `${l}/list`) });
-      u = "/transformers";
-      z = (t) => ({ create: (e) => t("POST", `${u}`, { body: e }), delete: (e) => t("DELETE", `${u}`, { params: e }), list: () => t("GET", `${u}/list`) });
-      B = (t) => {
-        const { sendRequest: e, reconfigure: n, getConfig: c } = f(t);
-        return { contentGroups: w(e), contentPieces: U(e), tags: S(e), profile: O(e), userSettings: L(e), webhooks: R(e), workspace: x(e), roles: I(e), workspaceSettings: j(e), workspaceMemberships: v(e), extension: q(e), variants: A(e), transformers: z(e), search(s) {
-          return e("GET", "/search", { params: s });
-        }, async ask(s) {
-          let a = "";
-          const p = new import_eventsource.default(`${c().baseURL}/search/ask?query=${encodeURIComponent(s.query)}`, { headers: { Authorization: `Bearer ${c().token}` } });
-          p.addEventListener("error", (r) => {
-            const o = r;
-            return o.message ? s.onError?.(o.message) : (p.close(), s.onEnd?.(a));
-          }), p.addEventListener("message", (r) => {
-            const o = decodeURIComponent(r.data);
-            a += o, s.onChunk?.(o, a);
-          });
-        }, reconfigure: n };
+      I = (t) => ({ get: () => t("GET", `${C}`) });
+      u = "/roles";
+      v = (t) => ({ get: (e) => t("GET", `${u}`, { params: e }), create: (e) => t("POST", `${u}`, { body: e }), update: (e) => t("PUT", `${u}`, { body: e }), delete: (e) => t("DELETE", `${u}`, { params: e }), list: (e) => t("GET", `${u}/list`, { params: e }) });
+      k = "/workspace-settings";
+      j = (t) => ({ get: () => t("GET", `${k}`), update: (e) => t("PUT", `${k}`, { body: e }) });
+      q = (t) => ({ listMembers: (e) => t("GET", "/workspace-memberships/list-members", { params: e }), listWorkspaces: (e) => t("GET", "/workspace-memberships/list-workspaces", { params: e }), create: (e) => t("POST", "/workspace-memberships", { body: e }), update: (e) => t("PUT", "/workspace-memberships", { body: e }), delete: (e) => t("DELETE", "/workspace-memberships", { params: e }) });
+      G = "/extension";
+      A = (t) => ({ get: () => t("GET", `${G}`), updateContentPieceData: (e) => t("POST", `${G}/content-piece-data`, { body: e }) });
+      b = "/variants";
+      z = (t) => ({ create: (e) => t("POST", `${b}`, { body: e }), update: (e) => t("PUT", `${b}`, { body: e }), delete: (e) => t("DELETE", `${b}`, { params: e }), list: () => t("GET", `${b}/list`) });
+      y = "/transformers";
+      B = (t) => ({ create: (e) => t("POST", `${y}`, { body: e }), delete: (e) => t("DELETE", `${y}`, { params: e }), list: () => t("GET", `${y}/list`) });
+      M = (t) => {
+        const { sendRequest: e, reconfigure: c, getConfig: i, getSignal: $, useSignal: p } = f(t), s = { contentGroups: U(e), contentPieces: S(e), tags: D(e), profile: R(e), userSettings: L(e), webhooks: x(e), workspace: I(e), roles: v(e), workspaceSettings: j(e), workspaceMemberships: q(e), extension: A(e), variants: z(e), transformers: B(e), search(a) {
+          return e("GET", "/search", { params: a });
+        }, async ask(a) {
+          let n = "";
+          const o = new import_eventsource.default(`${i().baseURL}/search/ask?query=${encodeURIComponent(a.query)}`, { headers: { Authorization: `Bearer ${i().token}` } });
+          o.addEventListener("error", (d) => {
+            const r = d;
+            return r.message ? a.onError?.(r.message) : (o.close(), a.onEnd?.(n));
+          }), o.addEventListener("message", (d) => {
+            const r = decodeURIComponent(d.data);
+            n += r, a.onChunk?.(r, n);
+          }), $()?.addEventListener("abort", () => {
+            o.close();
+          }), p(null);
+        }, useSignal(a) {
+          return p(a), s;
+        }, reconfigure(a) {
+          return c(a), s;
+        } };
+        return s;
       };
     }
   });

programming_language: JavaScript
filename: light-theme.json
change_type: ModificationType.MODIFY
diff: @@ -1,469 +1,37 @@
 {
-  "inherit": false,
-  "base": "vs-dark",
-  "colors": {
-    "focusBorder": "#2188ff",
-    "foreground": "#444d56",
-    "descriptionForeground": "#6a737d",
-    "errorForeground": "#cb2431",
-    "textLink.foreground": "#0366d6",
-    "textLink.activeForeground": "#005cc5",
-    "textBlockQuote.background": "#fafbfc",
-    "textBlockQuote.border": "#e1e4e8",
-    "textCodeBlock.background": "#f6f8fa",
-    "textPreformat.foreground": "#586069",
-    "textSeparator.foreground": "#d1d5da",
-    "button.background": "#159739",
-    "button.foreground": "#ffffff",
-    "button.hoverBackground": "#138934",
-    "checkbox.background": "#fafbfc",
-    "checkbox.border": "#d1d5da",
-    "dropdown.background": "#fafbfc",
-    "dropdown.border": "#e1e4e8",
-    "dropdown.foreground": "#2f363d",
-    "dropdown.listBackground": "#ffffff",
-    "input.background": "#fafbfc",
-    "input.border": "#e1e4e8",
-    "input.foreground": "#2f363d",
-    "input.placeholderForeground": "#959da5",
-    "badge.foreground": "#005cc5",
-    "badge.background": "#dbedff",
-    "progressBar.background": "#2188ff",
-    "titleBar.activeForeground": "#2f363d",
-    "titleBar.activeBackground": "#ffffff",
-    "titleBar.inactiveForeground": "#6a737d",
-    "titleBar.inactiveBackground": "#f6f8fa",
-    "titleBar.border": "#e1e4e8",
-    "activityBar.foreground": "#2f363d",
-    "activityBar.inactiveForeground": "#959da5",
-    "activityBar.background": "#ffffff",
-    "activityBarBadge.foreground": "#ffffff",
-    "activityBarBadge.background": "#2188ff",
-    "activityBar.activeBorder": "#f9826c",
-    "activityBar.border": "#e1e4e8",
-    "sideBar.foreground": "#586069",
-    "sideBar.background": "#f6f8fa",
-    "sideBar.border": "#e1e4e8",
-    "sideBarTitle.foreground": "#2f363d",
-    "sideBarSectionHeader.foreground": "#2f363d",
-    "sideBarSectionHeader.background": "#f6f8fa",
-    "sideBarSectionHeader.border": "#e1e4e8",
-    "list.hoverForeground": "#2f363d",
-    "list.inactiveSelectionForeground": "#2f363d",
-    "list.activeSelectionForeground": "#2f363d",
-    "list.hoverBackground": "#ebf0f4",
-    "list.inactiveSelectionBackground": "#e8eaed",
-    "list.activeSelectionBackground": "#e2e5e9",
-    "list.inactiveFocusBackground": "#dbedff",
-    "list.focusBackground": "#cce5ff",
-    "tree.indentGuidesStroke": "#e1e4e8",
-    "notificationCenterHeader.foreground": "#6a737d",
-    "notificationCenterHeader.background": "#e1e4e8",
-    "notifications.foreground": "#2f363d",
-    "notifications.background": "#fafbfc",
-    "notifications.border": "#e1e4e8",
-    "notificationsErrorIcon.foreground": "#d73a49",
-    "notificationsWarningIcon.foreground": "#e36209",
-    "notificationsInfoIcon.foreground": "#005cc5",
-    "pickerGroup.border": "#e1e4e8",
-    "pickerGroup.foreground": "#2f363d",
-    "quickInput.background": "#fafbfc",
-    "quickInput.foreground": "#2f363d",
-    "statusBar.foreground": "#586069",
-    "statusBar.background": "#ffffff",
-    "statusBar.border": "#e1e4e8",
-    "statusBar.noFolderBackground": "#ffffff",
-    "statusBar.debuggingBackground": "#f9826c",
-    "statusBar.debuggingForeground": "#ffffff",
-    "editorGroupHeader.tabsBackground": "#f6f8fa",
-    "editorGroupHeader.tabsBorder": "#e1e4e8",
-    "editorGroup.border": "#e1e4e8",
-    "tab.activeForeground": "#2f363d",
-    "tab.inactiveForeground": "#6a737d",
-    "tab.inactiveBackground": "#f6f8fa",
-    "tab.activeBackground": "#ffffff",
-    "tab.hoverBackground": "#ffffff",
-    "tab.unfocusedHoverBackground": "#ffffff",
-    "tab.border": "#e1e4e8",
-    "tab.unfocusedActiveBorderTop": "#e1e4e8",
-    "tab.activeBorder": "#ffffff",
-    "tab.unfocusedActiveBorder": "#ffffff",
-    "tab.activeBorderTop": "#f9826c",
-    "breadcrumb.foreground": "#6a737d",
-    "breadcrumb.focusForeground": "#2f363d",
-    "breadcrumb.activeSelectionForeground": "#586069",
-    "breadcrumbPicker.background": "#fafbfc",
-    "editor.foreground": "#24292e",
-    "editor.background": "#f9fafb",
-    "editorWidget.background": "#f3f4f6",
-    "editorWidget.border": "#e5e7eb",
-    "editor.foldBackground": "#fafbfc",
-    "editor.lineHighlightBackground": "#f6f8fa",
-    "editorLineNumber.foreground": "#1b1f234d",
-    "editorLineNumber.activeForeground": "#24292e",
-    "editorIndentGuide.background": "#eff2f6",
-    "editorIndentGuide.activeBackground": "#d7dbe0",
-    "editorWhitespace.foreground": "#d1d5da",
-    "editorCursor.foreground": "#044289",
-    "editor.findMatchBackground": "#ffdf5d",
-    "editor.findMatchHighlightBackground": "#ffdf5d66",
-    "editor.inactiveSelectionBackground": "#0366d611",
-    "editor.selectionBackground": "#0366d625",
-    "editor.selectionHighlightBackground": "#34d05840",
-    "editor.selectionHighlightBorder": "#34d05800",
-    "editor.wordHighlightBackground": "#34d05800",
-    "editor.wordHighlightStrongBackground": "#34d05800",
-    "editor.wordHighlightBorder": "#24943e99",
-    "editor.wordHighlightStrongBorder": "#24943e50",
-    "editorBracketMatch.background": "#34d05840",
-    "editorBracketMatch.border": "#34d05800",
-    "editorGutter.modifiedBackground": "#2188ff",
-    "editorGutter.addedBackground": "#28a745",
-    "editorGutter.deletedBackground": "#d73a49",
-    "diffEditor.insertedTextBackground": "#34d05822",
-    "diffEditor.removedTextBackground": "#d73a4922",
-    "scrollbar.shadow": "#6a737d33",
-    "scrollbarSlider.background": "#959da533",
-    "scrollbarSlider.hoverBackground": "#959da544",
-    "scrollbarSlider.activeBackground": "#959da588",
-    "editorOverviewRuler.border": "#ffffff",
-    "panel.background": "#f6f8fa",
-    "panel.border": "#e1e4e8",
-    "panelTitle.activeBorder": "#f9826c",
-    "panelTitle.activeForeground": "#2f363d",
-    "panelTitle.inactiveForeground": "#6a737d",
-    "panelInput.border": "#e1e4e8",
-    "terminal.foreground": "#586069",
-    "gitDecoration.addedResourceForeground": "#28a745",
-    "gitDecoration.modifiedResourceForeground": "#005cc5",
-    "gitDecoration.deletedResourceForeground": "#d73a49",
-    "gitDecoration.untrackedResourceForeground": "#28a745",
-    "gitDecoration.ignoredResourceForeground": "#959da5",
-    "gitDecoration.conflictingResourceForeground": "#e36209",
-    "gitDecoration.submoduleResourceForeground": "#959da5",
-    "debugToolBar.background": "#ffffff",
-    "editor.stackFrameHighlightBackground": "#fffbdd",
-    "editor.focusedStackFrameHighlightBackground": "#fff5b1",
-    "settings.headerForeground": "#2f363d",
-    "settings.modifiedItemIndicator": "#2188ff",
-    "welcomePage.buttonBackground": "#f6f8fa",
-    "welcomePage.buttonHoverBackground": "#e1e4e8"
-  },
+  "base": "vs",
+  "inherit": true,
   "rules": [
     {
-      "foreground": "#6a737d",
-      "token": "comment"
-    },
-    {
-      "foreground": "#6a737d",
-      "token": "punctuation.definition.comment"
-    },
-    {
-      "foreground": "#6a737d",
-      "token": "string.comment"
-    },
-    {
-      "foreground": "#005cc5",
-      "token": "constant"
-    },
-    {
-      "foreground": "#005cc5",
-      "token": "entity.name.constant"
-    },
-    {
-      "foreground": "#005cc5",
-      "token": "variable.other.constant"
-    },
-    {
-      "foreground": "#005cc5",
-      "token": "variable.language"
-    },
-    {
-      "foreground": "#6f42c1",
-      "token": "entity"
-    },
-    {
-      "foreground": "#6f42c1",
-      "token": "entity.name"
-    },
-    {
-      "foreground": "#24292e",
-      "token": "variable.parameter.function"
-    },
-    {
-      "foreground": "#22863a",
-      "token": "entity.name.tag"
-    },
-    {
-      "foreground": "#d73a49",
-      "token": "keyword"
-    },
-    {
-      "foreground": "#d73a49",
-      "token": "storage"
-    },
-    {
-      "foreground": "#d73a49",
-      "token": "storage.type"
-    },
-    {
-      "foreground": "#24292e",
-      "token": "storage.modifier.package"
-    },
-    {
-      "foreground": "#24292e",
-      "token": "storage.modifier.import"
-    },
-    {
-      "foreground": "#24292e",
-      "token": "storage.type.java"
-    },
-    {
-      "foreground": "#032f62",
-      "token": "string"
-    },
-    {
-      "foreground": "#032f62",
-      "token": "punctuation.definition.string"
-    },
-    {
-      "foreground": "#032f62",
-      "token": "string punctuation.section.embedded source"
-    },
-    {
-      "foreground": "#005cc5",
-      "token": "support"
-    },
-    {
-      "foreground": "#005cc5",
-      "token": "meta.property-name"
-    },
-    {
-      "foreground": "#e36209",
-      "token": "variable"
-    },
-    {
-      "foreground": "#24292e",
-      "token": "variable.other"
-    },
-    {
-      "fontStyle": "italic",
-      "foreground": "#b31d28",
-      "token": "invalid.broken"
-    },
-    {
-      "fontStyle": "italic",
-      "foreground": "#b31d28",
-      "token": "invalid.deprecated"
-    },
-    {
-      "fontStyle": "italic",
-      "foreground": "#b31d28",
-      "token": "invalid.illegal"
-    },
-    {
-      "fontStyle": "italic",
-      "foreground": "#b31d28",
-      "token": "invalid.unimplemented"
-    },
-    {
-      "fontStyle": "italic underline",
-      "background": "#d73a49",
-      "foreground": "#fafbfc",
-      "content": "^M",
-      "token": "carriage-return"
-    },
-    {
-      "foreground": "#b31d28",
-      "token": "message.error"
-    },
-    {
-      "foreground": "#24292e",
-      "token": "string source"
-    },
-    {
-      "foreground": "#005cc5",
-      "token": "string variable"
-    },
-    {
-      "foreground": "#032f62",
-      "token": "source.regexp"
-    },
-    {
-      "foreground": "#032f62",
-      "token": "string.regexp"
-    },
-    {
-      "foreground": "#032f62",
-      "token": "string.regexp.character-class"
-    },
-    {
-      "foreground": "#032f62",
-      "token": "string.regexp constant.character.escape"
-    },
-    {
-      "foreground": "#032f62",
-      "token": "string.regexp source.ruby.embedded"
-    },
-    {
-      "foreground": "#032f62",
-      "token": "string.regexp string.regexp.arbitrary-repitition"
-    },
-    {
-      "fontStyle": "bold",
-      "foreground": "#22863a",
-      "token": "string.regexp constant.character.escape"
-    },
-    {
-      "foreground": "#005cc5",
-      "token": "support.constant"
-    },
-    {
-      "foreground": "#005cc5",
-      "token": "support.variable"
-    },
-    {
-      "foreground": "#005cc5",
-      "token": "meta.module-reference"
-    },
-    {
-      "foreground": "#e36209",
-      "token": "punctuation.definition.list.begin.markdown"
-    },
-    {
-      "fontStyle": "bold",
-      "foreground": "#005cc5",
-      "token": "markup.heading"
-    },
-    {
-      "fontStyle": "bold",
-      "foreground": "#005cc5",
-      "token": "markup.heading entity.name"
-    },
-    {
-      "foreground": "#22863a",
-      "token": "markup.quote"
-    },
-    {
-      "fontStyle": "italic",
-      "foreground": "#24292e",
-      "token": "markup.italic"
-    },
-    {
-      "fontStyle": "bold",
-      "foreground": "#24292e",
-      "token": "markup.bold"
-    },
-    {
-      "foreground": "#005cc5",
-      "token": "markup.raw"
-    },
-    {
-      "background": "#ffeef0",
-      "foreground": "#b31d28",
-      "token": "markup.deleted"
-    },
-    {
-      "background": "#ffeef0",
-      "foreground": "#b31d28",
-      "token": "meta.diff.header.from-file"
-    },
-    {
-      "background": "#ffeef0",
-      "foreground": "#b31d28",
-      "token": "punctuation.definition.deleted"
-    },
-    {
-      "background": "#f0fff4",
-      "foreground": "#22863a",
-      "token": "markup.inserted"
-    },
-    {
-      "background": "#f0fff4",
-      "foreground": "#22863a",
-      "token": "meta.diff.header.to-file"
-    },
-    {
-      "background": "#f0fff4",
-      "foreground": "#22863a",
-      "token": "punctuation.definition.inserted"
-    },
-    {
-      "background": "#ffebda",
-      "foreground": "#e36209",
-      "token": "markup.changed"
-    },
-    {
-      "background": "#ffebda",
-      "foreground": "#e36209",
-      "token": "punctuation.definition.changed"
-    },
-    {
-      "foreground": "#f6f8fa",
-      "background": "#005cc5",
-      "token": "markup.ignored"
-    },
-    {
-      "foreground": "#f6f8fa",
-      "background": "#005cc5",
-      "token": "markup.untracked"
-    },
-    {
-      "foreground": "#6f42c1",
-      "fontStyle": "bold",
-      "token": "meta.diff.range"
-    },
-    {
-      "foreground": "#005cc5",
-      "token": "meta.diff.header"
-    },
-    {
-      "fontStyle": "bold",
-      "foreground": "#005cc5",
-      "token": "meta.separator"
-    },
-    {
-      "foreground": "#005cc5",
-      "token": "meta.output"
-    },
-    {
-      "foreground": "#586069",
-      "token": "brackethighlighter.tag"
-    },
-    {
-      "foreground": "#586069",
-      "token": "brackethighlighter.curly"
-    },
-    {
-      "foreground": "#586069",
-      "token": "brackethighlighter.round"
-    },
-    {
-      "foreground": "#586069",
-      "token": "brackethighlighter.square"
-    },
-    {
-      "foreground": "#586069",
-      "token": "brackethighlighter.angle"
-    },
-    {
-      "foreground": "#586069",
-      "token": "brackethighlighter.quote"
-    },
-    {
-      "foreground": "#b31d28",
-      "token": "brackethighlighter.unmatched"
-    },
-    {
-      "foreground": "#032f62",
-      "fontStyle": "underline",
-      "token": "constant.other.reference.link"
-    },
-    {
-      "foreground": "#032f62",
-      "fontStyle": "underline",
-      "token": "string.other.link"
+      "token": "",
+      "settings": {
+        "foreground": "#000000",
+        "background": "#FFFFFF"
+      }
     }
   ],
-  "encodedTokensColors": []
+  "colors": {
+    "editor.background": "#f9fafb",
+    "editorWidget.background": "#f3f4f6",
+    "editor.foreground": "#000000",
+    "editor.inactiveSelectionBackground": "#E5EBF1",
+    "editorIndentGuide.background": "#D3D3D3",
+    "editorIndentGuide.activeBackground": "#939393",
+    "editor.selectionHighlightBackground": "#ADD6FF80",
+    "editorSuggestWidget.background": "#F3F3F3",
+    "activityBarBadge.background": "#007ACC",
+    "sideBarTitle.foreground": "#6F6F6F",
+    "list.hoverBackground": "#E8E8E8",
+    "input.placeholderForeground": "#767676",
+    "searchEditor.textInputBorder": "#CECECE",
+    "settings.textInputBorder": "#CECECE",
+    "settings.numberInputBorder": "#CECECE",
+    "statusBarItem.remoteForeground": "#FFF",
+    "statusBarItem.remoteBackground": "#16825D",
+    "sideBarSectionHeader.background": "#0000",
+    "sideBarSectionHeader.border": "#61616130",
+    "tab.lastPinnedBorder": "#61616130",
+    "notebook.cellBorderColor": "#E8E8E8",
+    "statusBarItem.errorBackground": "#c72e0f"
+  }
 }

programming_language: CoffeeScript
filename: mini-code-editor.tsx
change_type: ModificationType.MODIFY
diff: @@ -81,7 +81,6 @@ const MiniCodeEditor: Component<MiniCodeEditorProps> = (props) => {
         model: null,
         wordWrap: props.wrap ? "on" : "off",
         readOnly: typeof props.readOnly === "boolean" ? props.readOnly : false,
-        theme: "dark-contrast",
         scrollbar: {
           alwaysConsumeMouseWheel: false
         }
@@ -140,11 +139,6 @@ const MiniCodeEditor: Component<MiniCodeEditorProps> = (props) => {
           }
         )
       );
-      createEffect(() => {
-        props.monaco.editor.setTheme(
-          `${codeEditorTheme()}${props.color === "contrast" ? "-contrast" : ""}`
-        );
-      });
       onCleanup(() => {
         codeEditor.getModel()?.dispose();
         codeEditor.dispose();
@@ -157,7 +151,8 @@ const MiniCodeEditor: Component<MiniCodeEditorProps> = (props) => {
       <div
         ref={setEditorContainerRef}
         class={clsx(
-          "w-full bg-gray-100 border-2 not-prose dark:bg-gray-900 rounded-2xl dark:border-gray-700 rounded",
+          "w-full bg-gray-100 border-2 not-prose dark:bg-gray-900 rounded-2xl dark:border-gray-700 rounded-editor-2xl customized-editor box-content",
+          props.color === "contrast" && "customized-editor-contrast",
           props.class
         )}
       ></div>

programming_language: TypeScript
filename: appearance.tsx
change_type: ModificationType.MODIFY
diff: @@ -13,7 +13,7 @@ interface AppearanceContextData {
 const AppearanceContext = createContext<AppearanceContextData>();
 const AppearanceProvider: ParentComponent = (props) => {
   const {
-    userSettings = () => ({ accentColor: "energy", codeEditorTheme: "dark", uiTheme: "auto" })
+    userSettings = () => ({ accentColor: "energy", codeEditorTheme: "auto", uiTheme: "auto" })
   } = useAuthenticatedUserData() || {};
   const prefersDark = createPrefersDark();
   const uiTheme = (): BaseTheme => {

programming_language: TypeScript
filename: authenticated-user-data.tsx
change_type: ModificationType.MODIFY
diff: @@ -184,32 +184,6 @@ const AuthenticatedUserDataProvider: ParentComponent = (props) => {
               ...workspaceSettings!,
               ...data
             }));
-          } else if (action === "createWrapper") {
-            setWorkspaceSettings((workspaceSettings) => ({
-              ...workspaceSettings!,
-              wrappers: [...(workspaceSettings?.wrappers || []), data]
-            }));
-          } else if (action === "deleteWrapper") {
-            setWorkspaceSettings((workspaceSettings) => ({
-              ...workspaceSettings!,
-              wrappers: (workspaceSettings?.wrappers || []).filter(
-                (wrapper) => wrapper.key !== data.key
-              )
-            }));
-          } else if (action === "updateWrapper") {
-            setWorkspaceSettings((workspaceSettings) => ({
-              ...workspaceSettings!,
-              wrappers: (workspaceSettings?.wrappers || []).map((wrapper) => {
-                if (wrapper.key === data.key) {
-                  return {
-                    ...wrapper,
-                    ...data
-                  };
-                }
-
-                return wrapper;
-              })
-            }));
           }
         }
       });

programming_language: TypeScript
filename: client.tsx
change_type: ModificationType.MODIFY
diff: @@ -61,7 +61,7 @@ const refreshTokenLink = (closeConnection: () => void): TRPCLink<App.Router> =>
                 return;
               }
 
-              if (error.data?.code === "UNAUTHORIZED") {
+              if (error.data?.code === "UNAUTHORIZED" && window.location.pathname !== "/auth") {
                 attempt();
               } else {
                 observer.error(error);

programming_language: TypeScript
filename: extensions.tsx
change_type: ModificationType.MODIFY
diff: @@ -36,7 +36,8 @@ const officialExtensions = {
   "dev": () => import("@vrite/extensions/dev.json"),
   "hashnode": () => import("@vrite/extensions/hashnode.json"),
   "medium": () => import("@vrite/extensions/medium.json"),
-  "gpt-3.5": () => import("@vrite/extensions/gpt-3.5.json")
+  "gpt-3.5": () => import("@vrite/extensions/gpt-3.5.json"),
+  "mdx": () => import("@vrite/extensions/mdx.json")
 };
 const isOfficialExtension = (id: string): boolean => {
   return id in officialExtensions;

programming_language: TypeScript
filename: index.tsx
change_type: ModificationType.MODIFY
diff: @@ -435,7 +435,7 @@ const Toolbar: Component<{ class?: string }> = (props) => {
   return (
     <div
       class={clsx(
-        ":base-2: p-1 w-full flex items-center border-b-2 absolute h-12 border-gray-200 dark:border-gray-700 justify-end @container z-1",
+        ":base-2: p-1 w-full flex items-center border-b-2 absolute h-12 border-gray-200 dark:border-gray-700 justify-end @container z-10",
         props.class
       )}
     >

programming_language: TypeScript
filename: format.ts
change_type: ModificationType.MODIFY
diff: @@ -4,7 +4,7 @@ import type { Options, Plugin } from "prettier";
 const languageParserMap = {
   javascript: "babel",
   typescript: "babel-ts",
-  json: "yaml",
+  json: "json-stringify",
   graphql: "graphql",
   html: "html",
   vue: "vue",
@@ -12,7 +12,8 @@ const languageParserMap = {
   yaml: "yaml",
   css: "css",
   less: "less",
-  scss: "scss"
+  scss: "scss",
+  mdx: "mdx"
 } as const;
 
 type SupportedLanguages = keyof typeof languageParserMap;
@@ -24,6 +25,7 @@ const loadParserPlugins = async (language: string): Promise<Plugin[] | null> =>
   switch (language as SupportedLanguages) {
     case "javascript":
     case "typescript":
+    case "json":
       return [
         await import("prettier/plugins/babel"),
         (await import("prettier/plugins/estree")) as Plugin
@@ -34,9 +36,9 @@ const loadParserPlugins = async (language: string): Promise<Plugin[] | null> =>
     case "vue":
       return [await import("prettier/plugins/html")];
     case "markdown":
+    case "mdx":
       return [await import("prettier/plugins/markdown")];
     case "yaml":
-    case "json":
       return [await import("prettier/plugins/yaml")];
     case "css":
     case "less":
@@ -54,11 +56,7 @@ const formatCode = async (code: string, language: string, options?: Options): Pr
     return format(code, {
       ...(options || {}),
       parser,
-      plugins: parserPlugins,
-      ...(language === "json" && {
-        trailingComma: "none",
-        singleQuote: false
-      })
+      plugins: parserPlugins
     });
   }
 

programming_language: TypeScript
filename: suggest-language.ts
change_type: ModificationType.MODIFY
diff: @@ -14,10 +14,7 @@ const getLanguageIds = (
       return { id: language.id };
     });
 };
-const useSuggestLanguage = (
-  languages: monaco.languages.ILanguageExtensionPoint[]
-): ((query: string) => string[]) => {
-  const languageIds = getLanguageIds(languages);
+const useSuggestLanguage = (): ((query: string) => string[]) => {
   const engine =
     searchEngine() ||
     new MiniSearch({
@@ -28,7 +25,11 @@ const useSuggestLanguage = (
     });
 
   if (!searchEngine()) {
-    engine.addAll(languageIds);
+    import("#lib/monaco").then(({ monaco }) => {
+      const languageIds = getLanguageIds(monaco.languages.getLanguages());
+
+      engine.addAll(languageIds);
+    });
     setSearchEngine(engine);
   }
 

programming_language: TypeScript
filename: editing.ts
change_type: ModificationType.MODIFY
diff: @@ -1,4 +1,4 @@
-import { CodeBlock, Embed, Image, Wrapper } from "./extensions";
+import { CodeBlock, Embed, Image, Element } from "./extensions";
 import { SlashMenuItem } from "./extensions/slash-menu/component";
 import { Editor, Node as NodeExtension, Mark as MarkExtension } from "@tiptap/core";
 import { DOMOutputSpec, DOMSerializer, Mark, Node } from "@tiptap/pm/model";
@@ -118,7 +118,7 @@ const createExtensions = (
     codeBlock: CodeBlock.configure({ provider }),
     horizontalRule: HorizontalRule,
     image: Image,
-    wrapper: Wrapper,
+    element: Element,
     table: [Table, TableCell, TableHeader, TableRow]
   };
   const getHeadingLevels = (settings: App.WorkspaceSettings): Level[] => {
@@ -285,13 +285,13 @@ const createBlockMenuOptions = (settings?: App.WorkspaceSettings): SlashMenuItem
       }
     },
     {
-      label: "Wrapper",
+      label: "Element",
       group: "Blocks",
-      block: "wrapper",
+      block: "element",
       icon: mdiCubeOutline,
       ref: createRef<HTMLElement | null>(null),
       command({ editor, range }) {
-        return editor.chain().focus().deleteRange(range).setWrapper().run();
+        return editor.chain().focus().deleteRange(range).setElement().run();
       }
     },
     {

programming_language: TypeScript
filename: component.tsx
change_type: ModificationType.MODIFY
diff: @@ -125,7 +125,7 @@ const BlockActionMenu: Component<BlockActionMenuProps> = (props) => {
               class={clsx(
                 blockAction.blocks.length !== 0 &&
                   !blockAction.blocks.some((block) => {
-                    return node()?.hasMarkup(props.state.editor.schema.nodes[block]);
+                    return node()?.type.name === props.state.editor.schema.nodes[block].name;
                   }) &&
                   "hidden"
               )}

programming_language: TypeScript
filename: plugin.tsx
change_type: ModificationType.MODIFY
diff: @@ -111,7 +111,7 @@ const BlockActionMenuPlugin = Extension.create({
 
         rangeFrom = p.start - 1;
         rangeTo = p.start + p.node.nodeSize - 1;
-      } catch (e) {
+      } catch (error) {
         box.style.display = "none";
       }
     }

programming_language: TypeScript
filename: menu.tsx
change_type: ModificationType.MODIFY
diff: @@ -1,57 +1,129 @@
 import { CodeBlockAttributes } from "./node";
-import { useSolidNodeView } from "@vrite/tiptap-solid";
-import { mdiCodeTagsCheck } from "@mdi/js";
+import { SolidNodeViewProps } from "@vrite/tiptap-solid";
+import { mdiCodeTags, mdiCodeTagsCheck, mdiFileOutline } from "@mdi/js";
 import { Component, createEffect, createMemo, createSignal, on, Show } from "solid-js";
-import type { monaco } from "#lib/monaco";
-import { IconButton, Input, Tooltip } from "#components/primitives";
+import { debounce } from "@solid-primitives/scheduled";
+import { Card, IconButton, Input, Tooltip } from "#components/primitives";
 import { useSuggestLanguage, isFormattable } from "#lib/code-editor";
+import { createRef } from "#lib/utils";
 
 interface CodeBlockMenuProps {
-  monaco: typeof monaco;
+  state: SolidNodeViewProps<CodeBlockAttributes>;
+  changeLanguage(lang: string | null): void;
   format(): void;
-  changeLanguage(languageId: string | null): void;
 }
 
 const CodeBlockMenu: Component<CodeBlockMenuProps> = (props) => {
-  const { state } = useSolidNodeView();
-  const attrs = (): CodeBlockAttributes => state().node.attrs;
+  const [mode, setMode] = createSignal<"title" | "lang">("lang");
+  const [menuRef, setMenuRef] = createRef<HTMLElement | null>(null);
+  const [left, setLeft] = createSignal(0);
   const [suggestions, setSuggestions] = createSignal<string[]>([]);
-  const suggestLanguage = useSuggestLanguage(props.monaco.languages.getLanguages());
-  const formattingAvailable = createMemo(() => {
-    return isFormattable(attrs().lang || "");
-  });
+  const attrs = (): CodeBlockAttributes => props.state.node.attrs;
+  const suggestLanguage = useSuggestLanguage();
+  const formattingAvailable = createMemo(() => isFormattable(attrs().lang?.split(" ")?.[0] || ""));
+  const updateAttribute = debounce((attributes: CodeBlockAttributes) => {
+    return props.state.updateAttributes(attributes);
+  }, 200);
+  const currentValue = (): string => {
+    if (mode() === "lang") {
+      return [attrs().lang, attrs().meta].filter(Boolean).join(" ");
+    }
+
+    return attrs().title || "";
+  };
 
   createEffect(
-    on(attrs, () => {
-      setSuggestions(suggestLanguage(attrs().lang || ""));
-      props.changeLanguage(attrs().lang || null);
+    on(attrs, (attrs) => {
+      setSuggestions(suggestLanguage(attrs.lang || ""));
+      props.changeLanguage(attrs.lang?.split(" ")?.[0] || null);
     })
   );
+  createEffect(
+    on(
+      () => props.state.selected,
+      () => {
+        const element = menuRef();
+
+        if (!element || !element.parentElement) return;
+
+        const { left, width } = element.parentElement.getBoundingClientRect();
+        const right = window.innerWidth - left - width;
+
+        setLeft(-Math.abs((right - left) / 2));
+      }
+    )
+  );
 
   return (
-    <div class="flex p-0 transition-shadow duration-200 border-0 rounded-xl">
-      <Input
-        wrapperClass="flex-1 max-w-full"
-        placeholder="Language"
-        value={attrs().lang || ""}
-        suggestions={suggestions()}
-        color="contrast"
-        disabled={!state().editor.isEditable}
-        setValue={(value) => {
-          state().updateAttributes({ lang: value });
-        }}
-      />
-      <Show when={state().editor.isEditable}>
-        <Tooltip text={formattingAvailable() ? "Format" : "Formatting unavailable"}>
+    <div
+      class="pointer-events-auto flex bg-gray-50 dark:bg-gray-900 !md:bg-transparent border-gray-200 dark:border-gray-700 border-y-2 md:border-0 backdrop-blur-sm md:gap-2 w-screen md:w-auto !md:left-unset relative md:rounded-2xl"
+      style={{ left: `${left()}px` }}
+      ref={setMenuRef}
+    >
+      <Card class="flex py-0 m-0 border-0 md:border-2 px-1 gap-1">
+        <Tooltip text="Title">
           <IconButton
-            path={mdiCodeTagsCheck}
-            color="contrast"
-            text="soft"
-            disabled={!formattingAvailable()}
-            onClick={props.format}
+            path={mdiFileOutline}
+            color={mode() === "title" ? "primary" : "contrast"}
+            text={mode() === "title" ? "primary" : "soft"}
+            variant={mode() === "title" ? "solid" : "text"}
+            class="m-0"
+            onClick={() => {
+              setMode("title");
+            }}
           ></IconButton>
         </Tooltip>
-      </Show>
+        <Tooltip text="Language">
+          <IconButton
+            path={mdiCodeTags}
+            color={mode() === "lang" ? "primary" : "contrast"}
+            text={mode() === "lang" ? "primary" : "soft"}
+            variant={mode() === "lang" ? "solid" : "text"}
+            class="m-0"
+            onClick={() => {
+              setMode("lang");
+            }}
+          ></IconButton>
+        </Tooltip>
+      </Card>
+      <Card class="flex m-0 border-0 md:border-2 p-1 gap-1 flex-1">
+        <Input
+          wrapperClass="flex-1 max-w-full md:w-72"
+          placeholder={mode() === "title" ? "Snippet title" : "Language meta"}
+          value={currentValue()}
+          suggestions={mode() === "lang" ? suggestions() : []}
+          suggestionsBoxClass="mt-3 mx-0 mb-0"
+          class="m-0 !bg-transparent text-lg"
+          color="contrast"
+          disabled={!props.state.editor.isEditable}
+          setValue={(value) => {
+            updateAttribute.clear();
+
+            if (mode() === "lang") {
+              const [lang, ...meta] = value.split(" ");
+
+              updateAttribute({ meta: meta.join(" "), lang });
+            } else {
+              updateAttribute({ title: value });
+            }
+          }}
+        />
+      </Card>
+      <Card class="flex m-0 border-0 md:border-2 p-1">
+        <Show when={props.state.editor.isEditable}>
+          <Tooltip text={formattingAvailable() ? "Format" : "Formatting unavailable"} class="mt-1">
+            <IconButton
+              path={mdiCodeTagsCheck}
+              color="contrast"
+              text="soft"
+              variant="text"
+              class="m-0"
+              disabled={!formattingAvailable()}
+              onClick={props.format}
+            ></IconButton>
+          </Tooltip>
+        </Show>
+      </Card>
     </div>
   );
 };

programming_language: TypeScript
filename: node.tsx
change_type: ModificationType.MODIFY
diff: @@ -75,7 +75,7 @@ const CodeBlock = BaseCodeBlock.extend<CodeBlockOptions>({
         });
 
         return (
-          <NodeViewWrapper class="my-5">
+          <NodeViewWrapper>
             <Show when={!loading()}>
               <CodeBlockView
                 monaco={monacoRef()!}

programming_language: TypeScript
filename: view.tsx
change_type: ModificationType.MODIFY
diff: @@ -2,18 +2,12 @@ import { CodeBlockAttributes, CodeBlockOptions } from "./node";
 import { CodeBlockMenu } from "./menu";
 import { useSolidNodeView } from "@vrite/tiptap-solid";
 import clsx from "clsx";
-import { Component, createEffect, createSignal, onMount } from "solid-js";
+import { Component, createEffect, createSignal, on, onMount } from "solid-js";
 import { nanoid } from "nanoid";
 import type { monaco } from "#lib/monaco";
 import { formatCode } from "#lib/code-editor";
-import { Card } from "#components/primitives";
 import { createRef, selectionClasses } from "#lib/utils";
-import {
-  useAppearance,
-  useAuthenticatedUserData,
-  useNotifications,
-  useLocalStorage
-} from "#context";
+import { useAppearance, useAuthenticatedUserData, useNotifications } from "#context";
 
 interface CodeBlockViewProps {
   monaco: typeof monaco;
@@ -51,6 +45,7 @@ const CodeBlockView: Component<CodeBlockViewProps> = (props) => {
   const [codeEditor, setCodeEditor] = createSignal<monaco.editor.IStandaloneCodeEditor | null>(
     null
   );
+  const [codeEditorActive, setCodeEditorActive] = createSignal(false);
   const [currentModelValue, setCurrentModelValue] = createRef("");
   const selected = (): boolean => {
     return state().selected;
@@ -65,7 +60,7 @@ const CodeBlockView: Component<CodeBlockViewProps> = (props) => {
 
       notify({ text: "Formatting code", type: "loading", promise: formattingCode });
 
-      const formattedCode = await formattingCode;
+      const formattedCode = (await formattingCode).trim();
 
       props.setUpdatingRef(true);
 
@@ -106,7 +101,7 @@ const CodeBlockView: Component<CodeBlockViewProps> = (props) => {
   };
   const updateEditorHeight = (monacoEditor: monaco.editor.IStandaloneCodeEditor): void => {
     const container = monacoEditor.getContainerDomNode();
-    const contentHeight = Math.max(200, monacoEditor.getContentHeight());
+    const contentHeight = Math.max(20, monacoEditor.getContentHeight());
     const editorContainer = editorContainerRef();
 
     if (editorContainer) {
@@ -129,7 +124,6 @@ const CodeBlockView: Component<CodeBlockViewProps> = (props) => {
         model: null,
         fontSize: 13,
         fontFamily: "JetBrainsMonoVariable",
-        theme: "dark",
         tabSize: 2,
         insertSpaces: true,
         readOnly: !state().editor.isEditable,
@@ -193,6 +187,10 @@ const CodeBlockView: Component<CodeBlockViewProps> = (props) => {
       codeEditor.onDidContentSizeChange(() => updateEditorHeight(codeEditor));
       codeEditor.onDidBlurEditorText(() => {
         options().provider?.awareness?.setLocalStateField("vscSelection", null);
+        setCodeEditorActive(false);
+      });
+      codeEditor.onDidFocusEditorText(() => {
+        setCodeEditorActive(true);
       });
       codeEditor.onDidChangeCursorSelection(() => {
         const model = codeEditor.getModel();
@@ -277,11 +275,18 @@ const CodeBlockView: Component<CodeBlockViewProps> = (props) => {
       });
     }
   });
+  createEffect(
+    on(codeEditorActive, (active) => {
+      if (active) {
+        state().editor.commands.setNodeSelection(state().getPos());
+      }
+    })
+  );
 
   return (
     <div
       class={clsx(
-        "relative rounded-2xl not-prose text-base leading-4",
+        "relative rounded-2xl text-base leading-4 not-prose",
         selected() && "ring ring-primary ring-2"
       )}
       contentEditable={selected() ? false : undefined}
@@ -291,20 +296,18 @@ const CodeBlockView: Component<CodeBlockViewProps> = (props) => {
         ref={setEditorContainerRef}
         spellcheck={false}
         class={clsx(
-          "w-full bg-gray-50 dark:bg-gray-900 h-72 not-prose rounded-t-2xl rounded",
-          codeEditorTheme() === "light" && "border-2 border-b-0 dark:border-0"
+          "bg-gray-50 dark:bg-gray-900 h-72 rounded-2xl rounded-editor-2xl border-2 border-gray-300 dark:border-gray-700 box-content customized-editor"
         )}
       />
-      <Card
+      <div
         class={clsx(
-          "m-0 rounded-t-none",
-          codeEditorTheme() === "dark" && "border-t-0 dark:border-0 dark:border-t-2",
-          codeEditorTheme() === "light" && "dark:border-t-0"
+          "absolute w-full justify-center items-center -bottom-14 z-1 pointer-events-none",
+          selected() ? "grid" : "hidden"
         )}
-        contentEditable={false}
       >
-        <CodeBlockMenu monaco={props.monaco} format={format} changeLanguage={changeLanguage} />
-      </Card>
+        <CodeBlockMenu changeLanguage={changeLanguage} format={format} state={state()} />
+      </div>
+      <div data-type="draggable-item" />
     </div>
   );
 };

programming_language: TypeScript
filename: collab-cursor.tsx
change_type: ModificationType.MODIFY
diff: @@ -66,16 +66,28 @@ const CollabCursor = (provider: HocuspocusProvider): Extension => {
         }>(null);
 
         onMount(() => {
-          if (container.parentElement?.classList.contains("ProseMirror")) {
+          if (
+            container.parentElement?.classList.contains("ProseMirror") ||
+            container.parentElement?.classList.contains("content") ||
+            container.parentElement?.tagName === "TH" ||
+            container.parentElement?.tagName === "TD" ||
+            container.parentElement?.tagName === "LI" ||
+            container.parentElement?.tagName === "BLOCKQUOTE"
+          ) {
             const rect = container.previousElementSibling?.getBoundingClientRect();
-            const parentPos = document.getElementById("pm-container")?.getBoundingClientRect();
+
+            let parentPos = document.getElementById("pm-container")?.getBoundingClientRect();
+
+            if (container.parentElement?.classList.contains("content")) {
+              parentPos = container.parentElement?.getBoundingClientRect();
+            }
 
             if (!parentPos || !rect) return;
 
             setBlockSelection({
               h: rect.height,
               w: rect.width,
-              top: rect.top - parentPos.top - 20
+              top: rect.top - parentPos.top
             });
           }
         });

programming_language: TypeScript
filename: component.tsx
change_type: ModificationType.ADD
diff: @@ -0,0 +1,97 @@
+import { ElementMenuEditor } from "./editor";
+import { SolidEditor } from "@vrite/tiptap-solid";
+import { Component, Show, createEffect, createSignal } from "solid-js";
+import { Node as PMNode } from "@tiptap/pm/model";
+
+interface ElementMenuProps {
+  state: {
+    pos: number;
+    node: PMNode | null;
+    container: HTMLElement | null;
+    editor: SolidEditor;
+    active: boolean;
+  };
+}
+
+const ElementMenu: Component<ElementMenuProps> = (props) => {
+  const [attributes, setAttributes] = createSignal({ type: "", props: {} as Record<string, any> });
+
+  createEffect(() => {
+    setAttributes((attributes) => {
+      if (!props.state.node) {
+        return { type: "", props: {} };
+      }
+
+      const newAttributes = props.state.node.attrs;
+
+      if (
+        newAttributes.type !== attributes.type ||
+        JSON.stringify(newAttributes.props) !== JSON.stringify(attributes.props)
+      ) {
+        return { type: newAttributes.type, props: newAttributes.props };
+      }
+
+      return attributes;
+    });
+  });
+
+  return (
+    <Show when={props.state.editor.isEditable}>
+      <div class="flex">
+        <ElementMenuEditor
+          state={{
+            editor: props.state.editor,
+            type: attributes()?.type || "",
+            props: attributes()?.props || {},
+            active: props.state.active,
+            contentSize: props.state.node?.content.size || 0,
+
+            removeElement() {
+              props.state.editor.commands.command(({ tr, dispatch }) => {
+                if (!dispatch) return false;
+
+                const lastPos = props.state.pos;
+
+                if (typeof lastPos === "number" && props.state.node) {
+                  tr.delete(lastPos, lastPos + props.state.node.nodeSize);
+
+                  return true;
+                }
+
+                return false;
+              });
+            },
+            setElement(element) {
+              props.state.editor.commands.command(({ tr, dispatch }) => {
+                if (!dispatch) return false;
+
+                const lastPos = props.state.pos;
+
+                if (lastPos !== null) {
+                  tr.setNodeAttribute(lastPos, "type", element.type);
+                  tr.setNodeAttribute(lastPos, "props", element.props);
+
+                  if (element.content && !props.state.node?.content.size) {
+                    tr.replaceWith(
+                      lastPos + 1,
+                      lastPos + props.state.node!.content.size + 1,
+                      props.state.editor.schema.node("paragraph")
+                    );
+                  } else if (!element.content && props.state.node?.content.size) {
+                    tr.delete(lastPos + 1, lastPos + props.state.node!.content.size + 1);
+                  }
+
+                  return true;
+                }
+
+                return false;
+              });
+            }
+          }}
+        />
+      </div>
+    </Show>
+  );
+};
+
+export { ElementMenu };

programming_language: TypeScript
filename: editor.tsx
change_type: ModificationType.ADD
diff: @@ -0,0 +1,303 @@
+import {
+  createEffect,
+  createMemo,
+  createRenderEffect,
+  createSignal,
+  lazy,
+  on,
+  onCleanup,
+  onMount
+} from "solid-js";
+import { createRef } from "@vrite/components/src/ref";
+import clsx from "clsx";
+import { nanoid } from "nanoid";
+import { SolidEditor } from "@vrite/tiptap-solid";
+import { scrollIntoView } from "seamless-scroll-polyfill";
+import { monaco } from "#lib/monaco";
+import { useAppearance } from "#context";
+import { formatCode } from "#lib/code-editor";
+
+interface ElementMenuEditorProps {
+  state: {
+    type: string;
+    active: boolean;
+    props: Record<string, any>;
+    editor: SolidEditor;
+    contentSize: number;
+    removeElement(): void;
+    setElement(element: { type: string; props: Record<string, any>; content: boolean }): void;
+  };
+}
+
+const codeEditorOptions: monaco.editor.IStandaloneEditorConstructionOptions = {
+  automaticLayout: true,
+  minimap: { enabled: false },
+  contextmenu: false,
+  fontSize: 17.5,
+  fontFamily: "JetBrainsMonoVariable",
+  scrollBeyondLastLine: false,
+  model: null,
+  wordWrap: "on",
+  theme: "dark",
+  suggestFontSize: 13,
+  codeLensFontSize: 13,
+  lineHeight: 26,
+  suggestLineHeight: 21,
+  overviewRulerBorder: false,
+  overviewRulerLanes: 0,
+  hideCursorInOverviewRuler: true,
+  lineNumbers: "off",
+  glyphMargin: false,
+  folding: false,
+  quickSuggestions: false,
+  lightbulb: { enabled: false },
+  hover: { enabled: false },
+  lineDecorationsWidth: 0,
+  lineNumbersMinChars: 0,
+  renderLineHighlightOnlyWhenFocus: true,
+  renderLineHighlight: "none",
+  scrollbar: {
+    vertical: "hidden",
+    horizontal: "hidden",
+    alwaysConsumeMouseWheel: false
+  }
+};
+const ElementMenuEditor = lazy(async () => {
+  const { monaco } = await import("#lib/monaco");
+
+  return {
+    default: (props: ElementMenuEditorProps) => {
+      const { codeEditorTheme = () => "dark" } = useAppearance() || {};
+      const [editorContainerRef, setEditorContainerRef] = createRef<HTMLElement | null>(null);
+      const [coords, setCoords] = createSignal({ x: 0, y: 0 });
+      const [visible, setVisible] = createSignal(true);
+      const type = createMemo(() => props.state.type);
+      const processCode = async (code: string): Promise<string> => {
+        const codeTagClosed = code?.trim().replace(/>$/, "/>") || "";
+        const formattedCode = await formatCode(codeTagClosed, "typescript", {
+          printWidth: 60,
+          trailingComma: "none",
+          singleQuote: false
+        });
+
+        return formattedCode.replace(/ *?\/>;/gm, props.state.contentSize ? ">" : "/>").trim();
+      };
+      const propsValue = createMemo((previous) => {
+        if (!previous || JSON.stringify(previous) !== JSON.stringify(props.state.props)) {
+          return props.state.props;
+        }
+
+        return previous;
+      });
+      const editorCode = createMemo(() => {
+        const keyValueProps = Object.entries(propsValue()).map(([key, value]) => {
+          if (value === true) return key;
+
+          const useBrackets =
+            typeof value !== "string" || value.includes("\n") || value.includes(`"`);
+
+          return `${key}=${useBrackets ? "{" : ""}${JSON.stringify(value)}${
+            useBrackets ? "}" : ""
+          }`;
+        });
+
+        return `<${type()}${keyValueProps.length ? " " : ""}${keyValueProps.join(" ")}>`;
+      });
+      const saveLastCoords = (event: MouseEvent): void => {
+        setCoords({ x: event.clientX, y: event.clientY });
+      };
+      const onSave = async (code: string): Promise<void> => {
+        const tagRegex = /^<(\w+?)(?:\s|\n|\/|>)/;
+        const attributeRegex =
+          /\s(\w+?)(?:=(?:(?:{((?:.|\n|\s)+?)})|(?:"((?:.|\n|\s)+?)")|(?:'((?:.|\n|\s)+?)')))?(?=(?:(?:\s|\n)+\w+=?)|(?:(?:\s|\n)*\/?>))/g;
+        const [, tag] = tagRegex.exec(code.trim()) || [];
+        const attributes: Record<string, any> = {};
+        const processAttributes = async (): Promise<void> => {
+          const match = attributeRegex.exec(code.trim());
+
+          if (!match) return;
+
+          const [, key] = match;
+          const value = (match[2] || match[3] || match[4] || "true").trim();
+
+          try {
+            const processedValue = await formatCode(value, "json", {
+              trailingComma: "none"
+            });
+
+            attributes[key] = JSON.parse(processedValue);
+          } catch (e) {
+            try {
+              attributes[key] = JSON.parse(value);
+            } catch (e) {
+              if (!props.state.props[key] || typeof props.state.props[key] === "string") {
+                attributes[key] = value;
+              } else {
+                attributes[key] = props.state.props[key];
+              }
+            }
+          }
+
+          await processAttributes();
+        };
+
+        await processAttributes();
+
+        if (tag && tag !== "undefined") {
+          props.state.setElement({
+            type: tag,
+            props: attributes,
+            content: !code.endsWith("/>")
+          });
+        } else {
+          props.state.removeElement();
+        }
+      };
+
+      onMount(() => {
+        const editorContainer = editorContainerRef()!;
+        const codeEditor = monaco.editor.create(editorContainer, codeEditorOptions);
+        const updateEditorHeight = (): void => {
+          const container = codeEditor.getContainerDomNode();
+          const contentHeight = Math.max(26, codeEditor.getContentHeight());
+
+          if (editorContainer) {
+            editorContainer.style.height = `${contentHeight}px`;
+          }
+
+          container.style.height = `${contentHeight}px`;
+          codeEditor.layout({
+            width: container.clientWidth,
+            height: contentHeight
+          });
+        };
+
+        codeEditor.onDidContentSizeChange(updateEditorHeight);
+        codeEditor.onDidChangeModelContent(() => {
+          const element = document.querySelector(".selected-element-tag") as HTMLElement;
+
+          if (element) {
+            element.textContent = codeEditor.getValue() || "";
+            element.style.height = `${codeEditor.getContentHeight()}px`;
+          }
+        });
+        codeEditor.onDidBlurEditorText(async () => {
+          const element = document.querySelector(".selected-element-tag") as HTMLElement;
+
+          if (element) {
+            element.textContent = await processCode(editorCode());
+          }
+
+          await onSave(codeEditor.getValue());
+        });
+        codeEditor.onKeyDown((event) => {
+          if (event.code === "Escape") {
+            props.state.editor.commands.focus();
+            event.preventDefault();
+            event.stopPropagation();
+          }
+        });
+        codeEditor.setModel(
+          monaco.editor.createModel(
+            editorCode(),
+            "javascript",
+            monaco.Uri.parse(`file:///${nanoid()}`)
+          )
+        );
+        createEffect(() => {
+          monaco.editor.setTheme(codeEditorTheme());
+        });
+        createEffect(
+          on(
+            () => props.state.active,
+            (active, _, prevElement) => {
+              const element: HTMLElement | null =
+                (prevElement as HTMLElement) ||
+                (document.querySelector(".selected-element-tag") as HTMLElement);
+
+              if (element) {
+                setTimeout(() => {
+                  if (active) {
+                    element.style.height = `${codeEditor.getContentHeight()}px`;
+
+                    return element;
+                  } else {
+                    element.style.height = "unset";
+
+                    return null;
+                  }
+                }, 0);
+              }
+
+              return element || null;
+            }
+          )
+        );
+        createEffect(
+          on(editorCode, async (code) => {
+            if (code === "<>") return codeEditor.setValue("");
+
+            const selection = codeEditor.getSelection();
+            const formattedCode = await processCode(code);
+
+            codeEditor.setValue(formattedCode);
+            if (selection) codeEditor.setSelection(selection);
+          })
+        );
+        createEffect(
+          on(type, (type, _previousType, handle) => {
+            if (typeof handle === "number") clearTimeout(handle);
+
+            if (type) {
+              return window.setTimeout(() => {
+                setVisible(true);
+
+                const { position } =
+                  codeEditor?.getTargetAtClientPoint(coords().x, coords().y) || {};
+
+                if (position) {
+                  codeEditor?.setSelection(monaco.Range.fromPositions(position, position));
+                }
+
+                scrollIntoView(editorContainer, { behavior: "smooth", block: "nearest" });
+                codeEditor?.focus();
+              }, 100);
+            }
+          })
+        );
+        onCleanup(() => {
+          codeEditor.getModel()?.dispose();
+          codeEditor.dispose();
+        });
+      });
+      createRenderEffect(
+        on(type, (type, previousType) => {
+          if (type !== previousType) setVisible(false);
+        })
+      );
+      window.addEventListener("pointerdown", saveLastCoords);
+      onCleanup(() => {
+        window.removeEventListener("pointerdown", saveLastCoords);
+      });
+
+      return (
+        <div
+          class={clsx(
+            "w-full flex items-center justify-start",
+            !visible() && "opacity-0 transition-opacity duration-200"
+          )}
+          contentEditable={false}
+        >
+          <div class="relative w-full">
+            <div
+              ref={setEditorContainerRef}
+              class="w-full not-prose customized-editor customized-editor-contrast customized-editor-show-keyboard-hidden"
+            ></div>
+          </div>
+        </div>
+      );
+    }
+  };
+});
+
+export { ElementMenuEditor };

programming_language: TypeScript
filename: index.ts
change_type: ModificationType.ADD
diff: @@ -0,0 +1 @@
+export * from "./plugin";

programming_language: TypeScript
filename: plugin.tsx
change_type: ModificationType.ADD
diff: @@ -0,0 +1,105 @@
+import { ElementMenu } from "./component";
+import { Extension } from "@tiptap/core";
+import { SolidEditor, SolidRenderer } from "@vrite/tiptap-solid";
+import { CellSelection } from "@tiptap/pm/tables";
+import { createNanoEvents } from "nanoevents";
+import { NodeSelection } from "@tiptap/pm/state";
+import { Node as PMNode } from "@tiptap/pm/model";
+
+const emitter = createNanoEvents();
+const generalMenuContainer = document.createElement("div");
+
+let generalMenu: SolidRenderer<{
+  editor: SolidEditor;
+  pos: number;
+  node: PMNode | null;
+  container: HTMLElement | null;
+  active: boolean;
+}> | null = null;
+
+const handleUpdate = (editor: SolidEditor): void => {
+  const { selection } = editor.state;
+  const selectedNode = selection.$from.nodeAfter;
+  const isNodeSelection = selection instanceof NodeSelection;
+
+  if (!isNodeSelection || !selectedNode || selectedNode.type.name !== "element") {
+    generalMenuContainer.style.display = "none";
+    generalMenu?.setState((state) => ({ ...state, active: false }));
+
+    return;
+  }
+
+  const { view } = editor;
+  const node = view.nodeDOM(selection.$from.pos);
+
+  if (!node) return;
+
+  const blockParent = node as HTMLElement;
+  const parentPos = document.getElementById("pm-container")?.getBoundingClientRect();
+  const childPos = blockParent?.getBoundingClientRect();
+
+  if (!parentPos || !childPos) return;
+
+  const relativePos = {
+    top: childPos.top - parentPos.top,
+    right: childPos.right - parentPos.right,
+    bottom: childPos.bottom - parentPos.bottom,
+    left: childPos.left - parentPos.left
+  };
+
+  Object.assign(generalMenuContainer.style, {
+    width: `${Math.min(childPos?.width || parentPos.width, parentPos.width)}px`,
+    top: `${relativePos.top}px`,
+    left: `${relativePos.left}px`,
+    position: "absolute",
+    display: "block"
+  });
+  generalMenu?.setState(() => ({
+    pos: selection.$from.pos,
+    node: selectedNode,
+    container: blockParent,
+    editor,
+    active: true
+  }));
+};
+const ElementMenuPlugin = Extension.create({
+  name: "elementMenu",
+  onCreate() {
+    generalMenu = new SolidRenderer(ElementMenu, {
+      editor: this.editor as SolidEditor,
+      state: {
+        pos: 0,
+        node: null as PMNode | null,
+        container: null as HTMLElement | null,
+        editor: this.editor as SolidEditor,
+        active: false as boolean
+      }
+    });
+    generalMenuContainer.appendChild(generalMenu.element);
+    document.getElementById("pm-container")?.appendChild(generalMenuContainer);
+  },
+  onBlur() {
+    const menuActive = document.activeElement?.contains(generalMenuContainer);
+
+    if (!menuActive) {
+      generalMenuContainer.style.display = "none";
+      generalMenu?.setState((state) => ({ ...state, active: false }));
+    }
+  },
+  onFocus() {
+    const isCellSelection = this.editor.state.selection instanceof CellSelection;
+
+    if (this.editor.isActive("element") && !isCellSelection) {
+      generalMenuContainer.style.display = "block";
+      generalMenu?.setState((state) => ({ ...state, active: true }));
+    }
+  },
+  onUpdate() {
+    handleUpdate(this.editor as SolidEditor);
+  },
+  onSelectionUpdate() {
+    handleUpdate(this.editor as SolidEditor);
+  }
+});
+
+export { ElementMenuPlugin, emitter };

programming_language: TypeScript
filename: node.tsx
change_type: ModificationType.ADD
diff: @@ -0,0 +1,181 @@
+import { Element as BaseElement, ElementAttributes } from "@vrite/editor";
+import { SolidEditor } from "@vrite/tiptap-solid";
+import { NodeView } from "@tiptap/core";
+import { keymap } from "@tiptap/pm/keymap";
+import { Node } from "@tiptap/pm/model";
+import { EditorState } from "@tiptap/pm/state";
+import { Node as PMNode } from "@tiptap/pm/model";
+import { formatCode } from "#lib/code-editor";
+
+const getOpeningTag = async (node: PMNode): Promise<string> => {
+  const keyValueProps = Object.entries(node.attrs.props).map(([key, value]) => {
+    if (value === true) return key;
+
+    const useBrackets = typeof value !== "string" || value.includes("\n") || value.includes(`"`);
+
+    return `${key}=${useBrackets ? "{" : ""}${JSON.stringify(value)}${useBrackets ? "}" : ""}`;
+  });
+  const c = `<${node.attrs.type}${keyValueProps.length ? " " : ""}${keyValueProps.join(" ")}>`;
+  const codeTagClosed = c.trim().replace(/>$/, "/>") || "";
+  const formattedCode = await formatCode(codeTagClosed, "typescript", {
+    printWidth: 60,
+    trailingComma: "none",
+    singleQuote: false
+  });
+
+  return formattedCode.replace(/ *?\/>;/gm, node.content.size ? ">" : "/>").trim();
+};
+const getClosingTag = (node: PMNode): string => node.attrs.type;
+const Element = BaseElement.extend({
+  addProseMirrorPlugins() {
+    const handleDeleteElement = (state: EditorState): boolean => {
+      if (this.editor.isActive("element")) {
+        const currentDepth = state.selection.$from.depth;
+
+        let node: Node | null = null;
+        let pos: number | null = null;
+
+        for (let i = currentDepth; i >= 0; i--) {
+          const currentNode = state.selection.$from.node(i);
+
+          if (currentNode.type.name === "element") {
+            node = currentNode;
+            pos = i > 0 ? state.selection.$from.before(i) : 0;
+            break;
+          }
+        }
+
+        if (
+          node &&
+          !node.textContent &&
+          node.content.childCount === 1 &&
+          node.content.firstChild?.type.name === "paragraph" &&
+          typeof pos === "number"
+        ) {
+          this.editor
+            .chain()
+            .deleteRange({
+              from: pos,
+              to: pos + node.nodeSize
+            })
+            .focus()
+            .run();
+
+          return true;
+        }
+      }
+
+      return false;
+    };
+
+    return [
+      keymap({
+        Delete: handleDeleteElement,
+        Backspace: handleDeleteElement
+      })
+    ];
+  },
+  addNodeView() {
+    return (props) => {
+      let node = props.node as Node;
+
+      const editor = this.editor as SolidEditor;
+      const referenceView = new NodeView(() => {}, props);
+      const dom = document.createElement("div");
+      const contentContainer = document.createElement("div");
+      const content = document.createElement("div");
+      const code = document.createElement("code");
+      const bottomCode = document.createElement("code");
+      const bottomCodeStart = document.createElement("span");
+      const bottomCodeKey = document.createElement("span");
+      const bottomCodeEnd = document.createElement("span");
+      const handleCodeClick = (event: MouseEvent): void => {
+        if (typeof props.getPos === "function") {
+          editor.commands.setTextSelection(props.getPos());
+          editor.commands.setNodeSelection(props.getPos());
+        }
+
+        event.preventDefault();
+        event.stopPropagation();
+      };
+
+      getOpeningTag(props.node).then((openingTag) => (code.textContent = openingTag));
+      bottomCodeKey.textContent = getClosingTag(node);
+      contentContainer.setAttribute(
+        "class",
+        "px-3 w-full border-gray-300 dark:border-gray-700 border-l-2 ml-1 py-0 content"
+      );
+      dom.setAttribute("class", "flex flex-col justify-center items-center relative");
+      dom.setAttribute("data-element", "true");
+      content.setAttribute("class", "relative content");
+      contentContainer.append(content);
+      dom.append(code, contentContainer, bottomCode);
+      code.setAttribute(
+        "class",
+        "!whitespace-pre-wrap leading-[26px] min-h-6.5 block w-full !p-0 !bg-transparent !rounded-0 !text-gray-400 !dark:text-gray-400 cursor-pointer"
+      );
+      bottomCode.setAttribute(
+        "class",
+        "block w-full !p-0 leading-[26px] min-h-6.5 !rounded-0 !bg-transparent !text-gray-400 !dark:text-gray-400 cursor-pointer"
+      );
+      code.contentEditable = "false";
+      bottomCode.contentEditable = "false";
+      bottomCode.append(bottomCodeStart, bottomCodeKey, bottomCodeEnd);
+      bottomCodeStart.textContent = "</";
+      bottomCodeEnd.textContent = ">";
+      code.addEventListener("click", handleCodeClick);
+      bottomCode.addEventListener("click", handleCodeClick);
+
+      if (!node.content.size) {
+        bottomCode.classList.add("!hidden");
+      }
+
+      return {
+        dom,
+        contentDOM: content,
+        ignoreMutation(mutation: MutationRecord | { type: "selection"; target: Element }) {
+          if (mutation.type === "selection") {
+            return true;
+          }
+
+          return referenceView.ignoreMutation(mutation);
+        },
+        selectNode() {
+          contentContainer.classList.add("!border-primary");
+          code.classList.add("selected-element-tag");
+          bottomCode.classList.remove("!text-gray-400", "!dark:text-gray-400");
+          bottomCode.classList.add("!text-[#000000]", "!dark:text-[#DCDCDC]");
+          bottomCodeKey.classList.add("!text-[#008080]", "!dark:text-[#3dc9b0]");
+        },
+        deselectNode() {
+          contentContainer.classList.remove("!border-primary");
+          code.classList.remove("selected-element-tag");
+          bottomCode.classList.add("!text-gray-400", "!dark:text-gray-400");
+          bottomCode.classList.remove("!text-[#000000]", "!dark:text-[#DCDCDC]");
+          bottomCodeKey.classList.remove("!text-[#008080]", "!dark:text-[#3dc9b0]");
+        },
+        stopEvent(event) {
+          return referenceView.stopEvent(event);
+        },
+        update(newNode) {
+          if (newNode.type.name !== "element") return false;
+
+          node = newNode as Node;
+          getOpeningTag(node).then((openingTag) => (code.textContent = openingTag));
+          bottomCodeKey.textContent = getClosingTag(node);
+
+          if (node.content.size) {
+            bottomCode.classList.remove("!hidden");
+          } else {
+            bottomCode.classList.add("!hidden");
+          }
+
+          return true;
+        }
+      };
+    };
+  }
+});
+
+export { Element };
+export type { ElementAttributes };

programming_language: TypeScript
filename: menu.tsx
change_type: ModificationType.MODIFY
diff: @@ -1,9 +1,8 @@
 import { EmbedAttributes } from "./node";
 import { SolidNodeViewProps, Attrs } from "@vrite/tiptap-solid";
-import { Component } from "solid-js";
-import { mdiDotsGrid } from "@mdi/js";
-import { IconButton, Input, Tooltip } from "#components/primitives";
-import { EmbedType, getEmbedId, getEmbedSrc } from "#lib/utils";
+import { Component, createEffect, createSignal, on } from "solid-js";
+import { Card, Input } from "#components/primitives";
+import { EmbedType, createRef, getEmbedId, getEmbedSrc } from "#lib/utils";
 
 interface ImageMenuProps {
   state: SolidNodeViewProps<Attrs>;
@@ -22,6 +21,8 @@ const getInputPlaceholder = (embedType?: EmbedType): string => {
   }
 };
 const EmbedMenu: Component<ImageMenuProps> = (props) => {
+  const [menuRef, setMenuRef] = createRef<HTMLElement | null>(null);
+  const [left, setLeft] = createSignal(0);
   const attrs = (): EmbedAttributes => props.state.node.attrs;
   const getSrc = (input: string): string => {
     return getEmbedSrc(
@@ -30,18 +31,40 @@ const EmbedMenu: Component<ImageMenuProps> = (props) => {
     );
   };
 
+  createEffect(
+    on(
+      () => props.state.selected,
+      () => {
+        const element = menuRef();
+
+        if (!element || !element.parentElement) return;
+
+        const { left, width } = element.parentElement.getBoundingClientRect();
+        const right = window.innerWidth - left - width;
+
+        setLeft(-Math.abs((right - left) / 2));
+      }
+    )
+  );
+
   return (
-    <div class="flex p-0 transition-shadow duration-200 border-0 rounded-xl">
-      <Input
-        wrapperClass="flex-1 max-w-full"
-        color="contrast"
-        placeholder={getInputPlaceholder(attrs().embed as EmbedType)}
-        value={attrs().input || ""}
-        disabled={!props.state.editor.isEditable}
-        setValue={(value) => {
-          props.state.updateAttributes({ input: value, src: getSrc(value) });
-        }}
-      />
+    <div
+      class="pointer-events-auto flex bg-gray-50 dark:bg-gray-900 !md:bg-transparent border-gray-200 dark:border-gray-700 border-y-2 md:border-0 backdrop-blur-sm md:gap-2 w-screen md:w-auto !md:left-unset relative md:rounded-2xl"
+      style={{ left: `${left()}px` }}
+      ref={setMenuRef}
+    >
+      <Card class="flex m-0 border-0 md:border-2 p-1">
+        <Input
+          wrapperClass="max-w-full min-w-unset md:w-96 flex-1"
+          class="w-full bg-transparent m-0 flex-1 text-lg"
+          placeholder={getInputPlaceholder(attrs().embed as EmbedType)}
+          value={attrs().input || ""}
+          disabled={!props.state.editor.isEditable}
+          setValue={(value) => {
+            props.state.updateAttributes({ input: value, src: getSrc(value) });
+          }}
+        />
+      </Card>
     </div>
   );
 };

programming_language: TypeScript
filename: view.tsx
change_type: ModificationType.MODIFY
diff: @@ -4,7 +4,7 @@ import { NodeViewWrapper, useSolidNodeView } from "@vrite/tiptap-solid";
 import { Component, createSignal, Show } from "solid-js";
 import clsx from "clsx";
 import { mdiCodepen, mdiYoutube } from "@mdi/js";
-import { Card, Icon } from "#components/primitives";
+import { Icon } from "#components/primitives";
 import { codeSandboxIcon } from "#assets/icons";
 import { EmbedType } from "#lib/utils";
 
@@ -31,14 +31,14 @@ const EmbedView: Component = () => {
   };
 
   return (
-    <NodeViewWrapper class="my-5">
+    <NodeViewWrapper>
       <div class={clsx("relative rounded-2xl", selected() && "ring ring-primary ring-2")}>
         <Show
           when={attrs().src}
           fallback={
             <div
               class={clsx(
-                "pt-[35%] w-full rounded-t-2xl bg-gradient-to-tr flex justify-center items-center relative"
+                "pt-[35%] w-full rounded-2xl bg-gradient-to-tr flex justify-center items-center relative border-2 border-gray-300 dark:border-gray-700"
               )}
             >
               <div class="absolute flex flex-col items-center justify-center font-bold text-white transform -translate-y-1/2 top-1/2">
@@ -55,13 +55,18 @@ const EmbedView: Component = () => {
         >
           <iframe
             src={attrs().src || ""}
-            class="object-contain w-full m-0 transition-opacity duration-300 border-2 border-gray-200 dark:border-gray-700 aspect-video min-h-96 rounded-t-2xl"
+            class="object-contain w-full m-0 transition-opacity duration-300 border-2 border-gray-300 dark:border-gray-700 aspect-video min-h-96 rounded-2xl"
           />
         </Show>
-
-        <Card class="m-0 border-t-0 rounded-t-none">
+        <div
+          class={clsx(
+            "absolute w-full justify-center items-center -bottom-14 z-1 pointer-events-none",
+            selected() ? "grid" : "hidden"
+          )}
+        >
           <EmbedMenu state={state()} />
-        </Card>
+        </div>
+        <div data-type="draggable-item" />
       </div>
     </NodeViewWrapper>
   );

programming_language: TypeScript
filename: menu.tsx
change_type: ModificationType.MODIFY
diff: @@ -1,11 +1,12 @@
 import { ImageAttributes, ImageOptions } from "./node";
 import { SolidNodeViewProps } from "@vrite/tiptap-solid";
 import { mdiLinkVariant, mdiText, mdiUpload } from "@mdi/js";
-import { Component, createSignal, Show } from "solid-js";
+import { Component, createEffect, createSignal, on, onMount } from "solid-js";
 import { nanoid } from "nanoid";
 import { debounce } from "@solid-primitives/scheduled";
-import { uploadFile as uploadFileUtil } from "#lib/utils";
-import { Button, IconButton, Input, Loader, Tooltip } from "#components/primitives";
+import clsx from "clsx";
+import { createRef, uploadFile as uploadFileUtil } from "#lib/utils";
+import { Card, IconButton, Input, Tooltip } from "#components/primitives";
 
 interface ImageMenuProps {
   state: SolidNodeViewProps<ImageAttributes>;
@@ -13,75 +14,107 @@ interface ImageMenuProps {
 
 const ImageMenu: Component<ImageMenuProps> = (props) => {
   const { storage } = props.state.extension;
+  const [menuRef, setMenuRef] = createRef<HTMLElement | null>(null);
   const [inputMode, setInputMode] = createSignal<"alt" | "src">("src");
   const [uploading, setUploading] = createSignal(false);
+  const [left, setLeft] = createSignal(0);
   const attrs = (): ImageAttributes => props.state.node.attrs;
   const options = (): ImageOptions => props.state.extension.options;
+  const placeholder = (): string => {
+    if (inputMode() === "src") {
+      return options().cover ? "Cover image URL" : "Image URL";
+    }
+
+    return options().cover ? "Cover alt description" : "Alt description";
+  };
   const updateAttribute = debounce((attribute: "src" | "alt", value: string) => {
     return props.state.updateAttributes({ [attribute]: value });
   }, 200);
-  const inputId = nanoid();
   const uploadFile = async (file?: File | null): Promise<void> => {
     if (file && file.type.includes("image")) {
       setUploading(true);
 
       const uploadedUrl = await uploadFileUtil(file);
 
-      if (uploadedUrl) {
-        props.state.updateAttributes({ src: uploadedUrl });
-      }
+      if (uploadedUrl) props.state.updateAttributes({ src: uploadedUrl });
 
       setUploading(false);
     }
   };
-  const getPlaceholder = (): string => {
-    if (inputMode() === "src") {
-      return options().cover ? "Cover image URL" : "Image URL";
-    }
-
-    return options().cover ? "Cover alt description" : "Alt description";
-  };
+  const inputId = nanoid();
 
   if (storage.droppedFile()) {
     uploadFile(storage.droppedFile());
     storage.setDroppedFile(null);
   }
 
+  createEffect(
+    on(
+      () => props.state.selected,
+      () => {
+        const element = menuRef();
+
+        if (!element || !element.parentElement) return;
+
+        const { left, width } = element.parentElement.getBoundingClientRect();
+        const right = window.innerWidth - left - width;
+
+        setLeft(-Math.abs((right - left) / 2));
+      }
+    )
+  );
+
   return (
-    <div class="flex p-0 transition-shadow duration-200 border-0 rounded-xl">
-      <Tooltip text="Alt">
-        <IconButton
-          path={mdiText}
-          color={inputMode() === "alt" ? "primary" : "contrast"}
-          text={inputMode() === "alt" ? "primary" : "soft"}
-          onClick={() => {
-            setInputMode("alt");
+    <div
+      class={clsx(
+        "pointer-events-auto flex bg-gray-50 dark:bg-gray-900 border-gray-200 dark:border-gray-700 border-y-2 backdrop-blur-sm relative !md:left-unset",
+        options().cover && "w-full border-t-0",
+        !options().cover &&
+          "md:gap-2 w-screen md:w-auto md:border-0 md:rounded-2xl !md:bg-transparent"
+      )}
+      style={{ left: `${left()}px` }}
+      ref={setMenuRef}
+    >
+      <Card class={clsx("flex py-0 m-0 border-0  px-1 gap-1", !options().cover && "md:border-2")}>
+        <Tooltip text="Alt">
+          <IconButton
+            path={mdiText}
+            color={inputMode() === "alt" ? "primary" : "contrast"}
+            text={inputMode() === "alt" ? "primary" : "soft"}
+            variant={inputMode() === "alt" ? "solid" : "text"}
+            class="m-0"
+            onClick={() => {
+              setInputMode("alt");
+            }}
+          ></IconButton>
+        </Tooltip>
+        <Tooltip text="Image URL">
+          <IconButton
+            path={mdiLinkVariant}
+            color={inputMode() === "src" ? "primary" : "contrast"}
+            text={inputMode() === "src" ? "primary" : "soft"}
+            variant={inputMode() === "src" ? "solid" : "text"}
+            class="m-0"
+            onClick={() => {
+              setInputMode("src");
+            }}
+          ></IconButton>
+        </Tooltip>
+      </Card>
+      <Card class={clsx("p-1 m-0 border-0 flex-1", !options().cover && "md:border-2")}>
+        <Input
+          wrapperClass={clsx("max-w-full min-w-unset flex-1", !options().cover && "md:w-96 ")}
+          class="w-full bg-transparent m-0 flex-1 text-lg"
+          placeholder={placeholder()}
+          value={attrs()[inputMode()] || ""}
+          disabled={!props.state.editor.isEditable}
+          setValue={(value) => {
+            updateAttribute.clear();
+            updateAttribute(inputMode(), value);
           }}
-        ></IconButton>
-      </Tooltip>
-      <Tooltip text="Image URL">
-        <IconButton
-          path={mdiLinkVariant}
-          color={inputMode() === "src" ? "primary" : "contrast"}
-          text={inputMode() === "src" ? "primary" : "soft"}
-          onClick={() => {
-            setInputMode("src");
-          }}
-        ></IconButton>
-      </Tooltip>
-      <Input
-        color="contrast"
-        wrapperClass="flex-1 max-w-full min-w-unset"
-        class="w-full"
-        placeholder={getPlaceholder()}
-        value={attrs()[inputMode()] || ""}
-        disabled={!props.state.editor.isEditable}
-        setValue={(value) => {
-          updateAttribute.clear();
-          updateAttribute(inputMode(), value);
-        }}
-      />
-      <Show when={props.state.editor.isEditable}>
+        />
+      </Card>
+      <Card class={clsx("p-1 m-0 border-0", !options().cover && "md:border-2")}>
         <input
           type="file"
           hidden
@@ -95,20 +128,19 @@ const ImageMenu: Component<ImageMenuProps> = (props) => {
           }}
         />
         <label for={inputId} class="flex items-center justify-center">
-          <Tooltip text={uploading() ? "Uploading" : "Upload image"}>
-            <Show
-              when={!uploading()}
-              fallback={
-                <Button badge color="contrast" class="flex items-center justify-center w-8 h-8">
-                  <Loader class="w-6 h-6" />
-                </Button>
-              }
-            >
-              <IconButton path={mdiUpload} color="contrast" text="soft" badge></IconButton>
-            </Show>
+          <Tooltip text={uploading() ? "Uploading" : "Upload image"} class="mt-1">
+            <IconButton
+              loading={uploading()}
+              path={mdiUpload}
+              color="contrast"
+              class="m-0"
+              text="soft"
+              badge
+              variant="text"
+            ></IconButton>
           </Tooltip>
         </label>
-      </Show>
+      </Card>
     </div>
   );
 };

programming_language: TypeScript
filename: view.tsx
change_type: ModificationType.MODIFY
diff: @@ -6,14 +6,14 @@ import clsx from "clsx";
 import { mdiAlertCircle, mdiImage } from "@mdi/js";
 import { debounce } from "@solid-primitives/scheduled";
 import { createRef, validateURL } from "#lib/utils";
-import { Card, Icon, Loader } from "#components/primitives";
+import { Icon, Loader } from "#components/primitives";
 
 const ImageView: Component = () => {
   const { state } = useSolidNodeView<ImageAttributes>();
   const [error, setError] = createSignal(false);
   const [loading, setLoading] = createSignal(false);
   const [objectURL, setObjectURL] = createSignal("");
-  const [currentSrc, setCurrentSrc] = createRef("");
+  const [currentSrc, setCurrentSrc] = createSignal("");
   const [imageContainerRef, setImageContainerRef] = createRef<HTMLElement | null>(null);
   const updateWidth = debounce((width: string) => state().updateAttributes({ width }), 250);
   const updateAspectRatio = debounce(
@@ -38,7 +38,7 @@ const ImageView: Component = () => {
     }
   });
   const removeImage = (): void => {
-    if (objectURL()) {
+    if (currentSrc()) {
       URL.revokeObjectURL(objectURL());
       setCurrentSrc("");
       setObjectURL("");
@@ -56,42 +56,21 @@ const ImageView: Component = () => {
 
     removeImage();
 
-    try {
-      if (!src) {
-        setError(false);
-        setLoading(false);
-
-        return;
-      }
-
-      if (!validateURL(src)) {
-        setError(true);
-        setLoading(false);
-
-        return;
-      }
-
-      const response = await fetch(
-        src.startsWith(window.env.PUBLIC_ASSETS_URL) ? src : `/proxy?url=${encodeURIComponent(src)}`
-      );
-
-      if (!response.ok) {
-        setError(true);
-        setLoading(false);
-
-        return;
-      }
+    if (!src) {
+      setError(false);
+      setLoading(false);
 
-      const blob = await response.blob();
-      const objectURL = URL.createObjectURL(blob);
+      return;
+    }
 
-      setCurrentSrc(src);
-      setObjectURL(objectURL);
-    } catch (error) {
+    if (!validateURL(src)) {
       setError(true);
-    } finally {
       setLoading(false);
+
+      return;
     }
+
+    setCurrentSrc(src);
   }, 350);
   const handleNewImageContainer = (element: HTMLElement): void => {
     const imageContainer = imageContainerRef();
@@ -133,7 +112,7 @@ const ImageView: Component = () => {
   );
 
   return (
-    <NodeViewWrapper class={clsx(!options().cover && "my-5")}>
+    <NodeViewWrapper>
       <div
         class={clsx(
           "relative rounded-2xl",
@@ -143,84 +122,88 @@ const ImageView: Component = () => {
         <div
           class={clsx(
             "border-gray-200 dark:border-gray-700",
-            options().cover ? "border-b-2" : "border-2 rounded-t-2xl"
+            options().cover ? "border-b-2" : "border-2 rounded-2xl"
           )}
         >
-          <Show
-            when={objectURL()}
-            fallback={
-              <div
-                class={clsx(
-                  "w-full bg-gradient-to-tr flex justify-center items-center relative",
-                  options().cover ? "min-h-48" : "rounded-t-2xl"
-                )}
-                style={{
-                  "padding-top": getPaddingTop()
-                }}
-              >
-                <div class="absolute flex flex-col items-center justify-center font-bold text-white transform -translate-y-1/2 top-1/2">
-                  <Show when={!loading()} fallback={<Loader class="w-8 h-8" />}>
-                    <Show
-                      when={!error()}
-                      fallback={
-                        <>
-                          <Icon path={mdiAlertCircle} class="w-16 h-16" />
-                          <span class="absolute top-full">Error</span>
-                        </>
-                      }
-                    >
-                      <Icon path={mdiImage} class="w-16 h-16" />
-                    </Show>
-                  </Show>
-                </div>
-              </div>
-            }
+          <div
+            class={clsx(
+              "w-full border-gray-200 dark:border-gray-700 flex justify-center items-center overflow-hidden bg-gray-100 dark:bg-gray-800 relative",
+              !error() && !loading() && currentSrc() ? "" : "opacity-0 !absolute",
+              !options().cover && "rounded-2xl"
+            )}
           >
             <div
               class={clsx(
-                "w-full border-gray-200 dark:border-gray-700 flex justify-center items-center overflow-hidden bg-gray-100 dark:bg-gray-800 relative",
-                !options().cover && "rounded-t-2xl"
+                "overflow-hidden min-w-40 !h-full",
+                state().editor.isEditable && "resize"
+              )}
+              ref={handleNewImageContainer}
+              style={{ width: attrs().width }}
+            >
+              <img
+                alt={attrs().alt}
+                src={currentSrc()}
+                class={clsx("object-contain w-full m-0 transition-opacity duration-300")}
+                onLoad={(event) => {
+                  setError(false);
+                  setLoading(false);
+
+                  const image = event.currentTarget;
+                  const w = image.naturalWidth;
+                  const h = image.naturalHeight;
+                  const aspectRatio = w / h;
+
+                  updateAspectRatio.clear();
+                  updateAspectRatio(`${aspectRatio}`);
+                }}
+                onError={() => {
+                  if (!currentSrc()) return;
+
+                  setLoading(false);
+                  removeImage();
+                  setError(true);
+                }}
+              />
+            </div>
+          </div>
+          <Show when={loading() || !currentSrc()}>
+            <div
+              class={clsx(
+                "w-full bg-gradient-to-tr flex justify-center items-center relative",
+                options().cover ? "min-h-48" : "rounded-2xl"
               )}
+              style={{
+                "padding-top": getPaddingTop()
+              }}
             >
-              <div
-                class={clsx(
-                  "overflow-hidden min-w-40 !h-full",
-                  state().editor.isEditable && "resize"
-                )}
-                ref={handleNewImageContainer}
-                style={{ width: attrs().width }}
-              >
-                <img
-                  alt={attrs().alt}
-                  src={objectURL()}
-                  data-src={currentSrc()}
-                  class={clsx("object-contain w-full m-0 transition-opacity duration-300")}
-                  onLoad={(event) => {
-                    const image = event.currentTarget;
-                    const w = image.naturalWidth;
-                    const h = image.naturalHeight;
-                    const aspectRatio = w / h;
-
-                    updateAspectRatio.clear();
-                    updateAspectRatio(`${aspectRatio}`);
-                  }}
-                  onError={() => {
-                    removeImage();
-                    setError(true);
-                  }}
-                />
+              <div class="absolute flex flex-col items-center justify-center font-bold text-white transform -translate-y-1/2 top-1/2">
+                <Show when={!loading()} fallback={<Loader class="w-8 h-8" />}>
+                  <Show
+                    when={!error()}
+                    fallback={
+                      <>
+                        <Icon path={mdiAlertCircle} class="w-16 h-16" />
+                        <span class="absolute top-full">Error</span>
+                      </>
+                    }
+                  >
+                    <Icon path={mdiImage} class="w-16 h-16" />
+                  </Show>
+                </Show>
               </div>
             </div>
           </Show>
         </div>
-        <Card
+        <div
           class={clsx(
-            "m-0 border-0 border-b-2 rounded-t-none",
-            options().cover ? "rounded-none" : "border-x-2"
+            "w-full justify-center items-center z-1 pointer-events-none",
+            selected() ? "grid" : "hidden",
+            options().cover ? "!flex relative" : "absolute -bottom-14"
           )}
         >
           <ImageMenu state={state()} />
-        </Card>
+        </div>
+        <div data-type="draggable-item" />
       </div>
     </NodeViewWrapper>
   );

programming_language: TypeScript
filename: index.ts
change_type: ModificationType.MODIFY
diff: @@ -12,5 +12,6 @@ export * from "./block-action-menu";
 export * from "./comment-menu";
 export * from "./block-paste";
 export * from "./table-menu";
-export * from "./wrapper";
+export * from "./element";
 export * from "./auto-dir";
+export * from "./element-menu";

programming_language: TypeScript
filename: component.tsx
change_type: ModificationType.MODIFY
diff: @@ -12,7 +12,7 @@ interface SlashMenuItem {
   icon: string;
   label: string;
   group: string;
-  block?: App.WorkspaceSettings["blocks"][number] | "wrapper";
+  block?: App.WorkspaceSettings["blocks"][number];
   embed?: App.WorkspaceSettings["embeds"][number];
   ref: Ref<HTMLElement | null>;
   command(params: { editor: SolidEditor; range: Range }): void;

programming_language: TypeScript
filename: menu.tsx
change_type: ModificationType.DELETE
diff: @@ -1,48 +0,0 @@
-import { Component, createEffect, createSignal } from "solid-js";
-import { SearchableSelect } from "#components/fragments";
-import { App, useAuthenticatedUserData } from "#context";
-
-interface WrapperMenuProps {
-  state: {
-    key: string;
-    setKey(key: string): void;
-  };
-}
-
-const WrapperMenu: Component<WrapperMenuProps> = (props) => {
-  const { workspaceSettings } = useAuthenticatedUserData();
-  const selectedOption = (): App.Wrapper | null => {
-    return (
-      (workspaceSettings()?.wrappers || []).find((wrapper) => wrapper.key === props.state.key) ||
-      null
-    );
-  };
-
-  props.state.setKey(selectedOption()?.key || "");
-
-  return (
-    <div class="w-full flex items-center justify-start text-base" contentEditable={false}>
-      <div>
-        <SearchableSelect
-          extractId={(option) => option.key}
-          filterOption={(option, query) => option.label.toLowerCase().includes(query.toLowerCase())}
-          options={workspaceSettings()?.wrappers || []}
-          renderOption={(option) => <div class="text-start">{option.label}</div>}
-          selectOption={(option) => {
-            props.state.setKey(option?.key || "");
-          }}
-          selected={selectedOption()}
-          loading={false}
-          placeholder="Wrapper"
-          buttonProps={{
-            class: "bg-gray-100",
-            color: "base",
-            text: "soft"
-          }}
-        />
-      </div>
-    </div>
-  );
-};
-
-export { WrapperMenu };

programming_language: unknown
filename: node.tsx
change_type: ModificationType.DELETE
diff: @@ -1,133 +0,0 @@
-import { WrapperMenu } from "./menu";
-import { Wrapper as BaseWrapper, WrapperAttributes } from "@vrite/editor";
-import { SolidEditor, SolidRenderer } from "@vrite/tiptap-solid";
-import { NodeView } from "@tiptap/core";
-import { keymap } from "@tiptap/pm/keymap";
-import { Node } from "@tiptap/pm/model";
-import { EditorState } from "@tiptap/pm/state";
-
-const Wrapper = BaseWrapper.extend({
-  addProseMirrorPlugins() {
-    const handleDeleteWrapper = (state: EditorState): boolean => {
-      if (this.editor.isActive("wrapper")) {
-        const currentDepth = state.selection.$from.depth;
-
-        let node: Node | null = null;
-        let pos: number | null = null;
-
-        for (let i = currentDepth; i >= 0; i--) {
-          const currentNode = state.selection.$from.node(i);
-
-          if (currentNode.type.name === "wrapper") {
-            node = currentNode;
-            pos = i > 0 ? state.selection.$from.before(i) : 0;
-            break;
-          }
-        }
-
-        if (
-          node &&
-          !node.textContent &&
-          node.content.childCount === 1 &&
-          node.content.firstChild?.type.name === "paragraph" &&
-          typeof pos === "number"
-        ) {
-          this.editor
-            .chain()
-            .deleteRange({
-              from: pos,
-              to: pos + node.nodeSize
-            })
-            .focus()
-            .run();
-
-          return true;
-        }
-      }
-
-      return false;
-    };
-
-    return [
-      keymap({
-        Delete: handleDeleteWrapper,
-        Backspace: handleDeleteWrapper
-      })
-    ];
-  },
-  addNodeView() {
-    const editor = this.editor as SolidEditor;
-
-    return (props) => {
-      let node = props.node as Node;
-
-      const referenceView = new NodeView(() => {}, props);
-      const dom = document.createElement("div");
-      const content = document.createElement("div");
-      const menu = document.createElement("div");
-
-      dom.setAttribute(
-        "class",
-        "px-3 pt-3 my-5 rounded-3xl border-gray-300 bg-gray-300 bg-opacity-30 dark:border-gray-700 dark:bg-gray-700 dark:bg-opacity-40 border-2"
-      );
-      dom.setAttribute("data-wrapper", "true");
-      content.setAttribute("class", "relative content mb-3");
-      menu.setAttribute("class", "mb-5");
-      menu.contentEditable = "false";
-
-      const renderer = new SolidRenderer<{ key: string; setKey(value: string): void }>(
-        WrapperMenu,
-        {
-          editor: this.editor as SolidEditor,
-          state: {
-            key: node.attrs.key,
-            setKey: (key) => {
-              if (typeof props.getPos === "function") {
-                editor.view.dispatch(
-                  editor.view.state.tr.setNodeMarkup(props.getPos(), undefined, {
-                    key: key || null
-                  })
-                );
-              }
-            }
-          }
-        }
-      );
-
-      menu.append(renderer.element);
-      dom.append(menu, content);
-
-      return {
-        dom,
-        contentDOM: content,
-        ignoreMutation(mutation: MutationRecord | { type: "selection"; target: Element }) {
-          if (mutation.type === "selection") {
-            return false;
-          }
-
-          return referenceView.ignoreMutation(mutation);
-        },
-        stopEvent(event) {
-          return referenceView.stopEvent(event);
-        },
-        destroy() {
-          renderer.destroy();
-        },
-        update(newNode) {
-          if (newNode.type.name !== "wrapper") return false;
-
-          node = newNode as Node;
-          renderer.setState((state) => ({
-            ...state,
-            key: node.attrs.key
-          }));
-
-          return true;
-        }
-      };
-    };
-  }
-});
-
-export { Wrapper };
-export type { WrapperAttributes };

programming_language: unknown
filename: monaco.ts
change_type: ModificationType.MODIFY
diff: @@ -14,29 +14,14 @@ declare global {
 }
 
 monaco.editor.defineTheme("dark", { ...darkTheme, base: "vs-dark" });
-monaco.editor.defineTheme("light", { ...lightTheme, base: "vs-dark" });
-monaco.editor.defineTheme("dark-contrast", {
-  ...darkTheme,
-  colors: {
-    ...darkTheme.colors,
-    "editor.background": "#1f2937",
-    "editorWidget.background": "#111827"
-  },
-  base: "vs-dark"
-});
-monaco.editor.defineTheme("light-contrast", {
-  ...lightTheme,
-  colors: {
-    ...lightTheme.colors,
-    "editor.background": "#f3f4f6",
-    "editorWidget.background": "#f9fafb"
-  },
-  base: "vs-dark"
-});
+monaco.editor.defineTheme("light", { ...lightTheme, base: "vs" });
 monaco.languages.typescript.typescriptDefaults.setDiagnosticsOptions({
   noSemanticValidation: true,
   noSyntaxValidation: true
 });
+monaco.languages.typescript.javascriptDefaults.setDiagnosticsOptions({
+  diagnosticCodesToIgnore: [17008, 1005]
+});
 monaco.languages.typescript.typescriptDefaults.setCompilerOptions({
   noUnusedLocals: false
 });

programming_language: TypeScript
filename: styles.css
change_type: ModificationType.MODIFY
diff: @@ -18,12 +18,14 @@
 }
 
 .ProseMirror-gapcursor {
-  width: 100%;
+  @apply !w-full !m-0;
 }
 .ProseMirror-gapcursor::after {
-  width: 100% !important;
-  top: -19px !important;
-  @apply !border-primary my-2;
+  @apply !border-primary !w-full !z-1 !my-0 !top-0;
+}
+div:not([data-element="true"]) + .ProseMirror-gapcursor:has(+ div)::after,
+div + .ProseMirror-gapcursor:has(+ div:not([data-element="true"]))::after {
+  @apply !my-2.5;
 }
 .ProseMirror-dropcursor {
   @apply text-primary;

programming_language: CSS
filename: styles.scss
change_type: ModificationType.MODIFY
diff: @@ -43,12 +43,8 @@ kbd {
   cursor: col-resize;
 }
 .prose-editor {
-  .ProseMirror:not(:where(.not-prose, .not-prose *)) {
-    > * + div:not(.tableWrapper) {
-      @apply mb-5;
-    }
-
-    padding-bottom: 8rem;
+  .ProseMirror {
+    @apply pb-48;
   }
   .tableWrapper {
     @apply overflow-auto pb-2 mb-3;
@@ -72,11 +68,11 @@ kbd {
     }
 
     tr {
-      @apply border-2 border-gray-200 dark:border-gray-700;
+      @apply border-2 border-gray-300 dark:border-gray-700;
     }
     td,
     th {
-      @apply text-left font-500 border-2 border-gray-200 dark:border-gray-700 relative p-2 vertical-top;
+      @apply text-left font-500 border-2 border-gray-300 dark:border-gray-700 relative p-2 vertical-top;
       min-width: 100px;
       border-style: none solid solid none;
       word-break: break-all;
@@ -210,10 +206,10 @@ kbd {
   :where(ul:not([data-type="taskList"]) li > * + *, ol li > * + *):not(
       :where(.not-prose, .not-prose *)
     ) {
-    @apply my-5;
+    // @apply my-5;
   }
   :where(li > ul, li > ol, li > div > ul, li > div > ol):not(:where(.not-prose, .not-prose *)) {
-    @apply m-0;
+    //@apply m-0;
   }
   :where(ul[data-type="taskList"]):not(:where(.not-prose, .not-prose *)) {
     padding-left: 0rem;
@@ -256,14 +252,37 @@ kbd {
   --un-prose-hr: #6b7280;
   --un-prose-invert-lists: #9ca3af;
   --un-prose-invert-hr: #9ca3af;
-  --highlighted-thread: "G3JAKWBAsWA1xXnPcJ-Zu";
+  --highlighted-thread: "";
+  :where([aria-expanded="false"] > .ProseMirror, .content, blockquote, li) {
+    &
+      > :where(div, ul, ol, p, blockquote, hr):not(.ProseMirror-gapcursor)
+      + :where(div, ul, ol, p, blockquote, hr, h1, h2, h3, h4, h5, h6):not([data-element="true"]),
+    &
+      > :where(div, ul, ol, p, blockquote, hr):not([data-element="true"], .ProseMirror-gapcursor)
+      + :where(div, ul, ol, p, blockquote, hr, h1, h2, h3, h4, h5, h6),
+    &
+      > :where(div, ul, ol, p, blockquote, hr):not(.ProseMirror-gapcursor)
+      + .ProseMirror-gapcursor
+      + :where(div, ul, ol, p, blockquote, hr, h1, h2, h3, h4, h5, h6):not([data-element="true"]),
+    &
+      > :where(div, ul, ol, p, blockquote, hr):not([data-element="true"], .ProseMirror-gapcursor)
+      + .ProseMirror-gapcursor
+      + :where(div, ul, ol, p, blockquote, hr, h1, h2, h3, h4, h5, h6) {
+      @apply mt-5;
+    }
+  }
 
-  :where(div[data-wrapper="true"]) {
+  :where(div[data-element="true"]) {
     .content > :first-child,
-    .content > :first-child [data-node-view-wrapper="true"] {
+    .content > .ProseMirror-gapcursor:first-child + *,
+    .content > :first-child > div > [data-node-view-wrapper="true"],
+    .content > .ProseMirror-gapcursor:first-child + * > div > [data-node-view-wrapper="true"] {
       margin-top: 0 !important;
     }
-    .content > :last-child:not([data-wrapper="true"]) {
+    .content > :last-child,
+    .content > .ProseMirror-gapcursor:last-child + *,
+    .content > :last-child > div > [data-node-view-wrapper="true"],
+    .content > .ProseMirror-gapcursor:last-child + * > div > [data-node-view-wrapper="true"] {
       margin-bottom: 0 !important;
     }
   }
@@ -276,8 +295,7 @@ kbd {
       content: unset !important;
     }
     @apply bg-gray-200 text-gray-700 font-medium dark:bg-gray-900 dark:text-gray-300 py-1 px-2 rounded-lg;
-    font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono",
-      "Courier New", monospace !important;
+    font-family: "JetBrainsMonoVariable", monospace !important;
   }
   :where(mark) {
     @apply text-gray-700;
@@ -353,21 +371,8 @@ kbd {
     margin: 0;
   }
 }
-.rounded {
-  .monaco-editor,
-  .monaco-editor > *:first-child {
-    @apply rounded-2xl;
-  }
-  .monaco-editor .editor-widget {
-    @apply overflow-hidden rounded-lg;
-  }
-  .monaco-editor .monaco-hover {
-    @apply rounded-lg;
-  }
-}
-
-.ProseMirror .rounded .monaco-editor,
-.ProseMirror .rounded .monaco-editor > *:first-child {
+.ProseMirror .monaco-editor,
+.ProseMirror .monaco-editor > *:first-child {
   @apply rounded-b-none;
 }
 .split-view[data-code-editor-theme="dark"] .monaco-diff-editor {
@@ -387,3 +392,85 @@ kbd {
     @apply md:(border-l-1 border-gray-200);
   }
 }
+
+.monaco-editor .editor-widget {
+  @apply overflow-hidden;
+  border-radius: 0.5rem !important;
+}
+.monaco-editor .monaco-hover {
+  border-radius: 0.5rem !important;
+}
+.rounded-editor-2xl {
+  .monaco-editor,
+  .monaco-editor > *:first-child {
+    @apply rounded-2xl;
+  }
+}
+.rounded-editor-t-2xl {
+  .monaco-editor,
+  .monaco-editor > *:first-child {
+    border-top-left-radius: calc(1rem - 2px);
+    border-top-right-radius: calc(1rem - 2px);
+  }
+}
+
+.rounded-editor-lg {
+  .monaco-editor,
+  .monaco-editor > *:first-child {
+    @apply rounded-lg;
+  }
+}
+.customized-editor-show-keyboard-hidden {
+  [widgetid="editor.contrib.ShowKeyboardWidget"] {
+    display: none !important;
+  }
+}
+.customized-editor {
+  --customized-editor-background: #f9fafb;
+  --customized-editor-widget-background: #f3f4f6;
+  .mtk2 {
+    color: var(--customized-editor-background);
+  }
+  .monaco-editor {
+    .inputarea.ime-input {
+      background-color: var(--customized-editor-background);
+    }
+    .view-overlays .current-line {
+      background-color: var(--customized-editor-widget-background) !important;
+      @apply border-gray-300 border-0;
+    }
+    .view-overlays > *:last-child:first-child .current-line {
+      background-color: transparent !important;
+    }
+    --vscode-editor-background: var(--customized-editor-background);
+    --vscode-editorStickyScroll-background: var(--customized-editor-background);
+    --vscode-breadcrumb-background: var(--customized-editor-background);
+    --vscode-editorGutter-background: var(--customized-editor-background);
+    --vscode-editorMarkerNavigation-background: var(--customized-editor-background);
+
+    // Editor Widget
+    .find-widget {
+      background-color: var(--customized-editor-widget-background);
+    }
+    --vscode-editorWidget-background: var(--customized-editor-widget-background);
+    --vscode-quickInput-background: var(--customized-editor-widget-background);
+    --vscode-editorHoverWidget-background: var(--customized-editor-widget-background);
+    --vscode-listFilterWidget-background: var(--customized-editor-widget-background);
+    --vscode-checkbox-selectBackground: var(--customized-editor-widget-background);
+    --vscode-breadcrumbPicker-background: var(--customized-editor-widget-background);
+  }
+}
+.customized-editor-contrast {
+  --customized-editor-background: #f3f4f6;
+  --customized-editor-widget-background: #f9fafb;
+}
+.dark {
+  .customized-editor {
+    --customized-editor-background: #111827;
+    --customized-editor-widget-background: #1f2937;
+  }
+  .customized-editor-contrast {
+    --customized-editor-background: #1f2937;
+    --customized-editor-widget-background: #111827;
+  }
+}

programming_language: CSS
filename: error-messages.tsx
change_type: ModificationType.MODIFY
diff: @@ -2,6 +2,7 @@ const errorMessages: Record<string, string> = {
   invalidEmail: "Incorrect email address",
   invalidCredentials: "Invalid credentials",
   emailNotVerified: "Email not verified",
+  magicLinkAlreadySent: "Wait 1 min before requesting a new magic link",
   totpTokenInvalid: "Invalid 2FA code",
   resourceNotFound: "User not found",
   alreadyExists: "User already exists"

programming_language: TypeScript
filename: index.tsx
change_type: ModificationType.MODIFY
diff: @@ -129,7 +129,7 @@ const ConflictView: Component<{ monaco: typeof monaco }> = (props) => {
         data-code-editor-theme={codeEditorTheme()}
       />
       <Show when={!conflictData() || currentContent.loading}>
-        <div class="h-full w-full absolute top-0 left-0 bg-gray-100 dark:bg-gray-800 flex justify-center items-center">
+        <div class="h-full w-full absolute top-0 left-0 bg-gray-100 dark:bg-gray-800 flex justify-center items-center z-12">
           <Show when={!conflictData()} fallback={<Loader />}>
             <span class="text-2xl font-semibold text-gray-500 dark:text-gray-400">
               Select a conflict to resolve

programming_language: TypeScript
filename: slug.tsx
change_type: ModificationType.MODIFY
diff: @@ -31,7 +31,12 @@ const SlugInput: Component<SlugInputProps> = (props) => {
           onChange={(event) => {
             const { value } = event.currentTarget;
 
-            props.setSlug(convertToSlug(value));
+            props.setSlug(
+              value
+                .split("/")
+                .map((slugPart) => convertToSlug(slugPart))
+                .join("/")
+            );
           }}
         />
       </Show>

programming_language: TypeScript
filename: editor.tsx
change_type: ModificationType.MODIFY
diff: @@ -18,7 +18,7 @@ import { CharacterCount } from "@tiptap/extension-character-count";
 import * as Y from "yjs";
 import { useLocation, useNavigate } from "@solidjs/router";
 import { CellSelection } from "@tiptap/pm/tables";
-import { AllSelection } from "@tiptap/pm/state";
+import { AllSelection, NodeSelection } from "@tiptap/pm/state";
 import clsx from "clsx";
 import { Instance } from "tippy.js";
 import { scrollIntoView } from "seamless-scroll-polyfill";
@@ -37,6 +37,7 @@ import {
   createBlockMenuOptions,
   BlockPaste,
   TableMenuPlugin,
+  ElementMenuPlugin,
   CommentMenuPlugin,
   AutoDir
 } from "#lib/editor";
@@ -143,6 +144,7 @@ const Editor: Component<EditorProps> = (props) => {
       }),
       hostConfig.extensions && BlockActionMenuPlugin,
       TableMenuPlugin,
+      ElementMenuPlugin,
       CommentMenuPlugin,
       Collab.configure({
         document: ydoc
@@ -172,9 +174,10 @@ const Editor: Component<EditorProps> = (props) => {
     const { empty } = selection;
     const isAllSelection = selection instanceof AllSelection;
     const isCellSelection = selection instanceof CellSelection;
+    const isNodeSelection = selection instanceof NodeSelection;
     const isEmptyTextBlock = !doc.textBetween(from, to).length && isTextSelection(state.selection);
 
-    if (!view.hasFocus() || isAllSelection) {
+    if ((!view.hasFocus() && !isNodeSelection) || isAllSelection) {
       setBubbleMenuOpened(false);
 
       return false;
@@ -187,7 +190,8 @@ const Editor: Component<EditorProps> = (props) => {
     }
 
     if (
-      ["image", "codeBlock", "embed", "horizontalRule"].some((name) => {
+      isNodeSelection &&
+      ["horizontalRule", "image", "codeBlock", "embed", "element"].some((name) => {
         return editor.isActive(name);
       })
     ) {
@@ -211,7 +215,10 @@ const Editor: Component<EditorProps> = (props) => {
     const { selection } = state;
     const { $anchor, empty } = selection;
     const isRootDepth =
-      $anchor.depth === 1 || ($anchor.depth === 2 && $anchor.node(1).type.name === "wrapper");
+      $anchor.depth === 1 ||
+      ["element", "blockquote", "listItem", "taskItem"].includes(
+        $anchor.node($anchor.depth - 1)?.type?.name
+      );
     const isEmptyTextBlock =
       $anchor.parent.isTextblock &&
       !$anchor.parent.type.spec.code &&
@@ -274,6 +281,8 @@ const Editor: Component<EditorProps> = (props) => {
               zIndex: 30,
               hideOnClick: false,
               interactive: true,
+              placement: "bottom",
+              popperOptions: { modifiers: [{ name: "flip", enabled: false }] },
               animation: breakpoints.md() ? "scale-subtle" : "shift-away-subtle",
               onHide() {
                 if (containerRef()?.contains(el)) return false;

programming_language: TypeScript
filename: bubble-menu.tsx
change_type: ModificationType.DELETE
diff: @@ -1,441 +0,0 @@
-import { SolidEditor } from "@vrite/tiptap-solid";
-import {
-  mdiFormatBold,
-  mdiFormatItalic,
-  mdiFormatStrikethrough,
-  mdiCodeTags,
-  mdiLinkVariant,
-  mdiFormatColorHighlight,
-  mdiFormatSubscript,
-  mdiFormatSuperscript,
-  mdiCheck,
-  mdiDelete,
-  mdiTableColumnRemove,
-  mdiTableRowRemove,
-  mdiTableMergeCells,
-  mdiTableSplitCell,
-  mdiTableRemove,
-  mdiCommentOutline,
-  mdiTableHeadersEyeOff,
-  mdiPlus,
-  mdiKeyboardCloseOutline
-} from "@mdi/js";
-import { CellSelection } from "@tiptap/pm/tables";
-import { Component, createEffect, createSignal, For, Match, on, Show, Switch } from "solid-js";
-import { nanoid } from "nanoid";
-import clsx from "clsx";
-import { breakpoints, createRef, Ref } from "#lib/utils";
-import { Card, IconButton, Input, Tooltip } from "#components/primitives";
-import { App, useAuthenticatedUserData, useClient } from "#context";
-
-type BubbleMenuMode = "format" | "link" | "table" | "block";
-interface BubbleMenuProps {
-  editor: SolidEditor;
-  opened: boolean;
-  contentPieceId?: string;
-  class?: string;
-  mode?: BubbleMenuMode;
-  ref?: Ref<HTMLElement>[1];
-  blur?(): void;
-  setBlockMenuOpened?(opened: boolean): void;
-}
-
-const BubbleMenu: Component<BubbleMenuProps> = (props) => {
-  const [activeMarks, setActiveMarks] = createSignal<string[]>([]);
-  const { workspaceSettings = () => null } = useAuthenticatedUserData() || {};
-  const client = useClient();
-  const [mode, setMode] = createSignal<BubbleMenuMode>("format");
-  const [link, setLink] = createSignal("");
-  const [linkInputRef, setLinkInputRef] = createRef<HTMLInputElement | null>(null);
-  const commentMenuItem = {
-    icon: mdiCommentOutline,
-    mark: "comment",
-    label: "Comment",
-    async onClick() {
-      if (props.editor.isActive("comment")) {
-        props.editor.commands.unsetComment();
-      } else {
-        const threadFragment = nanoid();
-
-        props.editor.chain().setComment({ thread: threadFragment }).focus().run();
-
-        try {
-          await client.comments.createThread.mutate({
-            contentPieceId: props.contentPieceId || "",
-            fragment: threadFragment
-          });
-        } catch (error) {
-          props.editor.commands.unsetComment();
-        }
-      }
-    }
-  };
-  const closeKeyboardItem = {
-    icon: mdiKeyboardCloseOutline,
-    label: "Close keyboard",
-    async onClick() {
-      props.blur?.();
-    }
-  };
-  const menus = (
-    [
-      {
-        icon: mdiFormatBold,
-        mark: "bold",
-        label: "Bold"
-      },
-      {
-        icon: mdiFormatItalic,
-        mark: "italic",
-        label: "Italic"
-      },
-      {
-        icon: mdiFormatStrikethrough,
-        mark: "strike",
-        label: "Strike"
-      },
-      {
-        icon: mdiCodeTags,
-        mark: "code",
-        label: "Code"
-      },
-      {
-        icon: mdiLinkVariant,
-        mark: "link",
-        label: "Link",
-        onClick() {
-          setMode("link");
-        }
-      },
-      { icon: mdiFormatColorHighlight, mark: "highlight", label: "Highlight" },
-      { icon: mdiFormatSubscript, mark: "subscript", label: "Subscript" },
-      { icon: mdiFormatSuperscript, mark: "superscript", label: "Superscript" },
-      ...(props.contentPieceId && breakpoints.md() ? [commentMenuItem] : []),
-      ...(breakpoints.md() ? [] : [closeKeyboardItem])
-    ] as Array<{ icon: string; mark?: string; label: string; onClick?(): void }>
-  ).filter(({ mark }) => {
-    if (!mark || mark === "comment") return true;
-
-    if (!workspaceSettings()) {
-      return true;
-    }
-
-    return workspaceSettings()!.marks.includes(mark as App.WorkspaceSettings["marks"][number]);
-  });
-  const tableMenus = [
-    {
-      icon: mdiTableHeadersEyeOff,
-      label: "Toggle header cell off",
-      show() {
-        const { selection } = props.editor.state;
-
-        if (selection instanceof CellSelection) {
-          const tableNode = selection.$anchorCell.node(1);
-          const rowNode = selection.$anchorCell.node(2);
-
-          if (tableNode.child(0) === rowNode) {
-            return false;
-          }
-
-          return selection.$anchorCell.nodeAfter?.type.name === "tableHeader";
-        }
-
-        return false;
-      },
-      onClick() {
-        props.editor.chain().toggleHeaderCell().focus().run();
-      }
-    },
-    {
-      icon: mdiTableMergeCells,
-      label: "Merge cells",
-      show() {
-        const { selection } = props.editor.state;
-
-        if (selection instanceof CellSelection) {
-          return selection.$anchorCell.pos !== selection.$headCell.pos;
-        }
-
-        return false;
-      },
-      onClick() {
-        props.editor.chain().mergeCells().run();
-      }
-    },
-    {
-      icon: mdiTableSplitCell,
-      label: "Split cell",
-      show() {
-        const { selection } = props.editor.state;
-
-        if (
-          selection instanceof CellSelection &&
-          selection.$anchorCell.pos === selection.$headCell.pos
-        ) {
-          return (
-            selection.$anchorCell.nodeAfter?.attrs.colspan > 1 ||
-            selection.$anchorCell.nodeAfter?.attrs.rowspan > 1
-          );
-        }
-
-        return false;
-      },
-      onClick() {
-        props.editor.chain().splitCell().run();
-      }
-    },
-    {
-      icon: mdiTableColumnRemove,
-      label: "Delete column(s)",
-      show() {
-        const { selection } = props.editor.state;
-
-        if (selection instanceof CellSelection) {
-          const tableNode = selection.$anchorCell.node(1);
-
-          let isSingleColumn = false;
-
-          tableNode.content.forEach((rowNode) => {
-            isSingleColumn = rowNode.childCount === 1;
-          });
-
-          return !isSingleColumn;
-        }
-
-        return true;
-      },
-      onClick() {
-        props.editor.chain().deleteColumn().focus().run();
-      }
-    },
-    {
-      icon: mdiTableRowRemove,
-      label: "Delete row(s)",
-
-      show() {
-        const { selection } = props.editor.state;
-
-        if (selection instanceof CellSelection) {
-          const tableNode = selection.$anchorCell.node(1);
-
-          if (tableNode.content.childCount === 1) {
-            return false;
-          }
-        }
-
-        return true;
-      },
-      onClick() {
-        props.editor.chain().deleteRow().focus().run();
-      }
-    },
-    {
-      icon: mdiTableRemove,
-      label: "Delete table",
-
-      show() {
-        const { selection } = props.editor.state;
-
-        if (selection instanceof CellSelection) {
-          const tableNode = selection.$anchorCell.node(1);
-
-          if (tableNode.childCount === 1) return true;
-
-          let isSingleColumn = false;
-
-          tableNode.content.forEach((rowNode) => {
-            isSingleColumn = rowNode.childCount === 1;
-          });
-
-          return isSingleColumn;
-        }
-
-        return false;
-      },
-      onClick() {
-        props.editor.chain().deleteTable().focus().run();
-      }
-    }
-  ];
-  const marks = menus.map((menu) => menu.mark);
-  const saveLink = (): void => {
-    props.editor.chain().unsetCode().setLink({ href: link() }).focus().run();
-    setMode("format");
-  };
-
-  props.editor.on("update", () => {
-    setActiveMarks(marks.filter((mark) => mark && props.editor.isActive(mark)) as string[]);
-  });
-  props.editor.on("selectionUpdate", () => {
-    setActiveMarks(marks.filter((mark) => mark && props.editor.isActive(mark)) as string[]);
-
-    if (props.editor.state.selection instanceof CellSelection) {
-      setMode("table");
-    } else if (!props.editor.state.selection.empty) {
-      setMode("format");
-    }
-  });
-  createEffect(
-    on(mode, (mode) => {
-      if (mode === "link") {
-        setLink(props.editor.getAttributes("link").href || "");
-        setTimeout(() => {
-          const linkInput = linkInputRef();
-
-          linkInput?.focus();
-        }, 300);
-      } else {
-        setLink("");
-      }
-    })
-  );
-  createEffect(
-    on(
-      () => props.mode,
-      (mode) => {
-        setMode((currentMode) => mode || currentMode);
-      }
-    )
-  );
-  createEffect(
-    on(
-      () => props.opened,
-      (opened) => {
-        if (!opened) {
-          setLink("");
-          setTimeout(() => {
-            setMode("format");
-          }, 300);
-        }
-      }
-    )
-  );
-
-  return (
-    <Card
-      class={clsx(
-        "relative flex p-0 overflow-x-auto scrollbar-hidden md:overflow-initial",
-        props.class
-      )}
-      ref={props.ref}
-    >
-      <Switch>
-        <Match when={mode() === "block"}>
-          <IconButton
-            path={mdiPlus}
-            text="soft"
-            variant="text"
-            label="Insert block"
-            onClick={(event) => {
-              props.setBlockMenuOpened?.(true);
-              event.preventDefault();
-              event.stopPropagation();
-            }}
-          />
-          <IconButton
-            path={mdiKeyboardCloseOutline}
-            text="soft"
-            variant="text"
-            onClick={(event) => {
-              props.blur?.();
-              event.preventDefault();
-              event.stopPropagation();
-            }}
-          />
-        </Match>
-        <Match when={mode() === "table"}>
-          <For
-            each={tableMenus}
-            fallback={<span class="px-1.5 py-0.5 text-base">No available options</span>}
-          >
-            {(menuItem) => {
-              return (
-                <Show when={!menuItem.show || menuItem.show()}>
-                  <Tooltip text={menuItem.label} side="bottom" wrapperClass="snap-start">
-                    <IconButton
-                      path={menuItem.icon}
-                      text="soft"
-                      variant="text"
-                      color="base"
-                      onClick={(event) => {
-                        menuItem.onClick();
-                        event.preventDefault();
-                        event.stopPropagation();
-                      }}
-                    />
-                  </Tooltip>
-                </Show>
-              );
-            }}
-          </For>
-        </Match>
-        <Match when={mode() === "format"}>
-          <div class="flex">
-            <For
-              each={menus}
-              fallback={<span class="px-1.5 py-0.5 text-base">No available options</span>}
-            >
-              {(menu) => {
-                const active = (): boolean => {
-                  return Boolean(menu.mark && activeMarks().includes(menu.mark));
-                };
-
-                return (
-                  <Tooltip text={menu.label} side="bottom" wrapperClass="snap-start">
-                    <IconButton
-                      path={menu.icon}
-                      text={active() ? "primary" : "soft"}
-                      variant={active() ? "solid" : "text"}
-                      color={active() ? "primary" : "base"}
-                      onClick={(event) => {
-                        const chain = props.editor.chain();
-
-                        if (menu.onClick) {
-                          menu.onClick();
-                        } else if (menu.mark) {
-                          if (menu.mark !== "code") {
-                            chain.unsetCode();
-                          }
-
-                          chain.toggleMark(menu.mark).focus().run();
-                        }
-
-                        event.preventDefault();
-                        event.stopPropagation();
-                      }}
-                    />
-                  </Tooltip>
-                );
-              }}
-            </For>
-          </div>
-        </Match>
-        <Match when={mode() === "link"}>
-          <Input
-            ref={setLinkInputRef}
-            value={link()}
-            placeholder="Paste a link..."
-            wrapperClass="w-full md:w-auto"
-            setValue={(value) => {
-              setLink(value);
-            }}
-            onEnter={saveLink}
-            class="py-0 my-0 bg-transparent"
-          />
-          <IconButton path={mdiCheck} text="soft" variant="text" onClick={saveLink} />
-          <IconButton
-            path={mdiDelete}
-            text="soft"
-            variant="text"
-            onClick={() => {
-              props.editor.chain().unsetLink().focus().run();
-              setMode("format");
-            }}
-          />
-        </Match>
-      </Switch>
-    </Card>
-  );
-};
-
-export { BubbleMenu };

programming_language: unknown
filename: block.tsx
change_type: ModificationType.ADD
diff: @@ -0,0 +1,48 @@
+import { mdiPlus, mdiKeyboardCloseOutline } from "@mdi/js";
+import clsx from "clsx";
+import { Component } from "solid-js";
+import { SolidEditor } from "@vrite/tiptap-solid";
+import { Card, IconButton } from "#components/primitives";
+
+const BlockMenu: Component<{
+  class?: string;
+  mode: string;
+  opened: boolean;
+  editor: SolidEditor;
+  blur?(): void;
+  setMode(mode: string): void;
+  setBlockMenuOpened?(opened: boolean): void;
+}> = (props) => {
+  return (
+    <Card
+      class={clsx(
+        "relative flex p-0 overflow-x-auto scrollbar-hidden md:overflow-initial not-prose",
+        props.class
+      )}
+    >
+      <IconButton
+        path={mdiPlus}
+        text="soft"
+        variant="text"
+        label="Insert block"
+        onClick={(event) => {
+          props.setBlockMenuOpened?.(true);
+          event.preventDefault();
+          event.stopPropagation();
+        }}
+      />
+      <IconButton
+        path={mdiKeyboardCloseOutline}
+        text="soft"
+        variant="text"
+        onClick={(event) => {
+          props.blur?.();
+          event.preventDefault();
+          event.stopPropagation();
+        }}
+      />
+    </Card>
+  );
+};
+
+export { BlockMenu };

programming_language: TypeScript
filename: format.tsx
change_type: ModificationType.ADD
diff: @@ -0,0 +1,165 @@
+import clsx from "clsx";
+import { Component, For, createSignal } from "solid-js";
+import { SolidEditor } from "@vrite/tiptap-solid";
+import {
+  mdiFormatBold,
+  mdiFormatItalic,
+  mdiFormatStrikethrough,
+  mdiCodeTags,
+  mdiLinkVariant,
+  mdiFormatColorHighlight,
+  mdiFormatSubscript,
+  mdiFormatSuperscript,
+  mdiKeyboardCloseOutline,
+  mdiCommentOutline
+} from "@mdi/js";
+import { nanoid } from "nanoid";
+import { Card, IconButton, Tooltip } from "#components/primitives";
+import { App, useAuthenticatedUserData, useClient } from "#context";
+import { breakpoints } from "#lib/utils";
+
+const FormatMenu: Component<{
+  class?: string;
+  mode: string;
+  opened: boolean;
+  editor: SolidEditor;
+  contentPieceId?: string;
+  blur?(): void;
+  setMode(mode: string): void;
+}> = (props) => {
+  const [activeMarks, setActiveMarks] = createSignal<string[]>([]);
+  const { workspaceSettings = () => null } = useAuthenticatedUserData() || {};
+  const client = useClient();
+  const commentMenuItem = {
+    icon: mdiCommentOutline,
+    mark: "comment",
+    label: "Comment",
+    async onClick() {
+      if (props.editor.isActive("comment")) {
+        props.editor.commands.unsetComment();
+      } else {
+        const threadFragment = nanoid();
+
+        props.editor.chain().setComment({ thread: threadFragment }).focus().run();
+
+        try {
+          await client.comments.createThread.mutate({
+            contentPieceId: props.contentPieceId || "",
+            fragment: threadFragment
+          });
+        } catch (error) {
+          props.editor.commands.unsetComment();
+        }
+      }
+    }
+  };
+  const closeKeyboardItem = {
+    icon: mdiKeyboardCloseOutline,
+    label: "Close keyboard",
+    async onClick() {
+      props.editor.commands.blur?.();
+    }
+  };
+  const menus = (
+    [
+      {
+        icon: mdiFormatBold,
+        mark: "bold",
+        label: "Bold"
+      },
+      {
+        icon: mdiFormatItalic,
+        mark: "italic",
+        label: "Italic"
+      },
+      {
+        icon: mdiFormatStrikethrough,
+        mark: "strike",
+        label: "Strike"
+      },
+      {
+        icon: mdiCodeTags,
+        mark: "code",
+        label: "Code"
+      },
+      {
+        icon: mdiLinkVariant,
+        mark: "link",
+        label: "Link",
+        onClick() {
+          props.setMode("link");
+        }
+      },
+      { icon: mdiFormatColorHighlight, mark: "highlight", label: "Highlight" },
+      { icon: mdiFormatSubscript, mark: "subscript", label: "Subscript" },
+      { icon: mdiFormatSuperscript, mark: "superscript", label: "Superscript" },
+      ...(props.contentPieceId && breakpoints.md() ? [commentMenuItem] : []),
+      ...(breakpoints.md() ? [] : [closeKeyboardItem])
+    ] as Array<{ icon: string; mark?: string; label: string; onClick?(): void }>
+  ).filter(({ mark }) => {
+    if (!mark || mark === "comment") return true;
+
+    if (!workspaceSettings()) {
+      return true;
+    }
+
+    return workspaceSettings()!.marks.includes(mark as App.WorkspaceSettings["marks"][number]);
+  });
+  const marks = menus.map((menu) => menu.mark);
+
+  props.editor.on("update", () => {
+    setActiveMarks(marks.filter((mark) => mark && props.editor.isActive(mark)) as string[]);
+  });
+  props.editor.on("selectionUpdate", () => {
+    setActiveMarks(marks.filter((mark) => mark && props.editor.isActive(mark)) as string[]);
+  });
+
+  return (
+    <Card
+      class={clsx(
+        "relative flex p-0 overflow-x-auto scrollbar-hidden md:overflow-initial not-prose",
+        props.class
+      )}
+    >
+      <For
+        each={menus}
+        fallback={<span class="px-1.5 py-0.5 text-base">No available options</span>}
+      >
+        {(menu) => {
+          const active = (): boolean => {
+            return Boolean(menu.mark && activeMarks().includes(menu.mark));
+          };
+
+          return (
+            <Tooltip text={menu.label} side="bottom" wrapperClass="snap-start">
+              <IconButton
+                path={menu.icon}
+                text={active() ? "primary" : "soft"}
+                variant={active() ? "solid" : "text"}
+                color={active() ? "primary" : "base"}
+                onClick={(event) => {
+                  const chain = props.editor.chain();
+
+                  if (menu.onClick) {
+                    menu.onClick();
+                  } else if (menu.mark) {
+                    if (menu.mark !== "code") {
+                      chain.unsetCode();
+                    }
+
+                    chain.toggleMark(menu.mark).focus().run();
+                  }
+
+                  event.preventDefault();
+                  event.stopPropagation();
+                }}
+              />
+            </Tooltip>
+          );
+        }}
+      </For>
+    </Card>
+  );
+};
+
+export { FormatMenu };

programming_language: TypeScript
filename: index.tsx
change_type: ModificationType.ADD
diff: @@ -0,0 +1,101 @@
+import { LinkMenu } from "./link";
+import { FormatMenu } from "./format";
+import { TableMenu } from "./table";
+import { BlockMenu } from "./block";
+import { SolidEditor } from "@vrite/tiptap-solid";
+import { CellSelection } from "@tiptap/pm/tables";
+import { Component, createEffect, createSignal, Match, on, Switch } from "solid-js";
+import { Ref } from "#lib/utils";
+
+type BubbleMenuMode = "format" | "link" | "table" | "block";
+interface BubbleMenuProps {
+  editor: SolidEditor;
+  opened: boolean;
+  contentPieceId?: string;
+  class?: string;
+  mode?: BubbleMenuMode;
+  ref?: Ref<HTMLElement>[1];
+  blur?(): void;
+  setBlockMenuOpened?(opened: boolean): void;
+}
+
+const BubbleMenu: Component<BubbleMenuProps> = (props) => {
+  const [mode, setMode] = createSignal<BubbleMenuMode>("format");
+
+  props.editor.on("selectionUpdate", ({ editor }) => {
+    const { selection } = editor.state;
+
+    if (props.editor.state.selection instanceof CellSelection) {
+      setMode("table");
+    } else if (!props.editor.state.selection.empty) {
+      setMode("format");
+    }
+  });
+  createEffect(
+    on(
+      () => props.mode,
+      (mode) => {
+        setMode((currentMode) => mode || currentMode);
+      }
+    )
+  );
+  createEffect(
+    on(
+      () => props.opened,
+      (opened) => {
+        if (!opened) {
+          setTimeout(() => {
+            setMode("format");
+          }, 300);
+        }
+      }
+    )
+  );
+
+  return (
+    <Switch>
+      <Match when={mode() === "block"}>
+        <BlockMenu
+          editor={props.editor}
+          mode={mode()}
+          opened={props.opened}
+          setMode={setMode}
+          setBlockMenuOpened={props.setBlockMenuOpened}
+          blur={props.blur}
+          class={props.class}
+        />
+      </Match>
+      <Match when={mode() === "table"}>
+        <TableMenu
+          editor={props.editor}
+          mode={mode()}
+          opened={props.opened}
+          setMode={setMode}
+          class={props.class}
+        />
+      </Match>
+      <Match when={mode() === "format"}>
+        <FormatMenu
+          editor={props.editor}
+          mode={mode()}
+          opened={props.opened}
+          setMode={setMode}
+          class={props.class}
+          contentPieceId={props.contentPieceId}
+          blur={props.blur}
+        />
+      </Match>
+      <Match when={mode() === "link"}>
+        <LinkMenu
+          editor={props.editor}
+          mode={mode()}
+          opened={props.opened}
+          setMode={setMode}
+          class={props.class}
+        />
+      </Match>
+    </Switch>
+  );
+};
+
+export { BubbleMenu };

programming_language: TypeScript
filename: link.tsx
change_type: ModificationType.ADD
diff: @@ -0,0 +1,82 @@
+import { mdiCheck, mdiDelete } from "@mdi/js";
+import clsx from "clsx";
+import { Component, createEffect, createSignal, on } from "solid-js";
+import { SolidEditor } from "@vrite/tiptap-solid";
+import { Card, Input, IconButton } from "#components/primitives";
+import { createRef } from "#lib/utils";
+
+const LinkMenu: Component<{
+  class?: string;
+  mode: string;
+  opened: boolean;
+  editor: SolidEditor;
+  setMode(mode: string): void;
+}> = (props) => {
+  const [link, setLink] = createSignal("");
+  const [linkInputRef, setLinkInputRef] = createRef<HTMLInputElement | null>(null);
+  const saveLink = (): void => {
+    props.editor.chain().unsetCode().setLink({ href: link() }).focus().run();
+    props.setMode("format");
+  };
+
+  createEffect(
+    on(
+      () => props.opened,
+      (opened) => {
+        if (!opened) {
+          setLink("");
+        }
+      }
+    )
+  );
+  createEffect(
+    on(
+      () => props.mode,
+      (mode) => {
+        if (mode === "link") {
+          setLink(props.editor.getAttributes("link").href || "");
+          setTimeout(() => {
+            const linkInput = linkInputRef();
+
+            linkInput?.focus();
+          }, 300);
+        } else {
+          setLink("");
+        }
+      }
+    )
+  );
+
+  return (
+    <Card
+      class={clsx(
+        "relative flex p-0 overflow-x-auto scrollbar-hidden md:overflow-initial not-prose",
+        props.class
+      )}
+    >
+      <Input
+        ref={setLinkInputRef}
+        value={link()}
+        placeholder="Paste a link..."
+        wrapperClass="w-full md:w-auto"
+        setValue={(value) => {
+          setLink(value);
+        }}
+        onEnter={saveLink}
+        class="py-0 my-0 bg-transparent"
+      />
+      <IconButton path={mdiCheck} text="soft" variant="text" onClick={saveLink} />
+      <IconButton
+        path={mdiDelete}
+        text="soft"
+        variant="text"
+        onClick={() => {
+          props.editor.chain().unsetLink().focus().run();
+          props.setMode("format");
+        }}
+      />
+    </Card>
+  );
+};
+
+export { LinkMenu };

programming_language: TypeScript
filename: table.tsx
change_type: ModificationType.ADD
diff: @@ -0,0 +1,194 @@
+import {
+  mdiTableColumnRemove,
+  mdiTableHeadersEyeOff,
+  mdiTableMergeCells,
+  mdiTableRemove,
+  mdiTableRowRemove,
+  mdiTableSplitCell
+} from "@mdi/js";
+import clsx from "clsx";
+import { Component, For, Show, createEffect, on } from "solid-js";
+import { SolidEditor } from "@vrite/tiptap-solid";
+import { CellSelection } from "@tiptap/pm/tables";
+import { Card, IconButton, Tooltip } from "#components/primitives";
+import { createRef } from "#lib/utils";
+
+const TableMenu: Component<{
+  class?: string;
+  mode: string;
+  opened: boolean;
+  editor: SolidEditor;
+  setMode(mode: string): void;
+}> = (props) => {
+  const tableMenus = [
+    {
+      icon: mdiTableHeadersEyeOff,
+      label: "Toggle header cell off",
+      show() {
+        const { selection } = props.editor.state;
+
+        if (selection instanceof CellSelection) {
+          const tableNode = selection.$anchorCell.node(1);
+          const rowNode = selection.$anchorCell.node(2);
+
+          if (tableNode.child(0) === rowNode) {
+            return false;
+          }
+
+          return selection.$anchorCell.nodeAfter?.type.name === "tableHeader";
+        }
+
+        return false;
+      },
+      onClick() {
+        props.editor.chain().toggleHeaderCell().focus().run();
+      }
+    },
+    {
+      icon: mdiTableMergeCells,
+      label: "Merge cells",
+      show() {
+        const { selection } = props.editor.state;
+
+        if (selection instanceof CellSelection) {
+          return selection.$anchorCell.pos !== selection.$headCell.pos;
+        }
+
+        return false;
+      },
+      onClick() {
+        props.editor.chain().mergeCells().run();
+      }
+    },
+    {
+      icon: mdiTableSplitCell,
+      label: "Split cell",
+      show() {
+        const { selection } = props.editor.state;
+
+        if (
+          selection instanceof CellSelection &&
+          selection.$anchorCell.pos === selection.$headCell.pos
+        ) {
+          return (
+            selection.$anchorCell.nodeAfter?.attrs.colspan > 1 ||
+            selection.$anchorCell.nodeAfter?.attrs.rowspan > 1
+          );
+        }
+
+        return false;
+      },
+      onClick() {
+        props.editor.chain().splitCell().run();
+      }
+    },
+    {
+      icon: mdiTableColumnRemove,
+      label: "Delete column(s)",
+      show() {
+        const { selection } = props.editor.state;
+
+        if (selection instanceof CellSelection) {
+          const tableNode = selection.$anchorCell.node(1);
+
+          let isSingleColumn = false;
+
+          tableNode.content.forEach((rowNode) => {
+            isSingleColumn = rowNode.childCount === 1;
+          });
+
+          return !isSingleColumn;
+        }
+
+        return true;
+      },
+      onClick() {
+        props.editor.chain().deleteColumn().focus().run();
+      }
+    },
+    {
+      icon: mdiTableRowRemove,
+      label: "Delete row(s)",
+
+      show() {
+        const { selection } = props.editor.state;
+
+        if (selection instanceof CellSelection) {
+          const tableNode = selection.$anchorCell.node(1);
+
+          if (tableNode.content.childCount === 1) {
+            return false;
+          }
+        }
+
+        return true;
+      },
+      onClick() {
+        props.editor.chain().deleteRow().focus().run();
+      }
+    },
+    {
+      icon: mdiTableRemove,
+      label: "Delete table",
+
+      show() {
+        const { selection } = props.editor.state;
+
+        if (selection instanceof CellSelection) {
+          const tableNode = selection.$anchorCell.node(1);
+
+          if (tableNode.childCount === 1) return true;
+
+          let isSingleColumn = false;
+
+          tableNode.content.forEach((rowNode) => {
+            isSingleColumn = rowNode.childCount === 1;
+          });
+
+          return isSingleColumn;
+        }
+
+        return false;
+      },
+      onClick() {
+        props.editor.chain().deleteTable().focus().run();
+      }
+    }
+  ];
+
+  return (
+    <Card
+      class={clsx(
+        "relative flex p-0 overflow-x-auto scrollbar-hidden md:overflow-initial not-prose",
+        props.class
+      )}
+    >
+      <For
+        each={tableMenus}
+        fallback={<span class="px-1.5 py-0.5 text-base">No available options</span>}
+      >
+        {(menuItem) => {
+          return (
+            <Show when={!menuItem.show || menuItem.show()}>
+              <Tooltip text={menuItem.label} side="bottom" wrapperClass="snap-start">
+                <IconButton
+                  path={menuItem.icon}
+                  text="soft"
+                  variant="text"
+                  color="base"
+                  onClick={(event) => {
+                    menuItem.onClick();
+                    event.preventDefault();
+                    event.stopPropagation();
+                  }}
+                />
+              </Tooltip>
+            </Show>
+          );
+        }}
+      </For>
+    </Card>
+  );
+};
+
+export { TableMenu };

programming_language: TypeScript
filename: index.ts
change_type: ModificationType.MODIFY
diff: @@ -1,6 +1,6 @@
-export * from "./bubble-menu";
-export * from "./export-menu";
-export * from "./floating-menu";
-export * from "./link-preview-menu";
-export * from "./stats-menu";
-export * from "./comment-threads-menu";
+export * from "./bubble";
+export * from "./comment-threads";
+export * from "./export";
+export * from "./floating";
+export * from "./link-preview";
+export * from "./stats";

programming_language: TypeScript
filename: extension-card.tsx
change_type: ModificationType.MODIFY
diff: @@ -1,7 +1,7 @@
 import { ExtensionIcon } from "./extension-icon";
 import { mdiTune, mdiDownloadOutline } from "@mdi/js";
 import { Component, Show } from "solid-js";
-import { ExtensionDetails, hasPermission, useClient } from "#context";
+import { ExtensionDetails, hasPermission, useClient, useExtensions } from "#context";
 import { Card, Heading, IconButton } from "#components/primitives";
 
 interface ExtensionCardProps {
@@ -12,6 +12,7 @@ interface ExtensionCardProps {
 
 const ExtensionCard: Component<ExtensionCardProps> = (props) => {
   const client = useClient();
+  const { callFunction } = useExtensions();
 
   return (
     <Card class="m-0 gap-1 flex flex-col justify-center items-center" color="contrast">
@@ -41,6 +42,18 @@ const ExtensionCard: Component<ExtensionCardProps> = (props) => {
                     permissions: props.extension.spec.permissions || []
                   }
                 });
+                const onConfigureCallback = props.extension.spec.lifecycle?.["on:configure"];
+
+                if (onConfigureCallback) {
+                  await callFunction(props.extension.spec, onConfigureCallback, {
+                    extensionId: id,
+                    token,
+                    context: () => ({
+                      config: {},
+                      spec: props.extension.spec
+                    })
+                  });
+                }
 
                 props.setOpenedExtension({ ...props.extension, config: {}, id, token });
               }

programming_language: TypeScript
filename: index.tsx
change_type: ModificationType.MODIFY
diff: @@ -47,6 +47,7 @@ const extractFileName = (path: string): { fileName: string; directory: string }
   return { fileName, directory };
 };
 const InitialSyncCard: Component = () => {
+  const { notify } = useNotifications();
   const [loading, setLoading] = createSignal(false);
   const client = useClient();
 
@@ -70,7 +71,14 @@ const InitialSyncCard: Component = () => {
           loading={loading()}
           onClick={async () => {
             setLoading(true);
-            await client.git.github.initialSync.mutate();
+
+            try {
+              await client.git.github.initialSync.mutate();
+              notify({ text: "Latest content pulled", type: "success" });
+            } catch (error) {
+              notify({ text: "Couldn't pull content", type: "error" });
+            }
+
             setLoading(false);
           }}
         >
@@ -108,6 +116,7 @@ const CommitCard: Component<{ changedRecords: App.GitRecord[] }> = (props) => {
 
                 if (status === "committed") {
                   notify({ text: "Changes committed", type: "success" });
+                  setMessage("");
                 } else {
                   notify({
                     text: "Pull required before committing changes",

programming_language: TypeScript
filename: configure-subsection.tsx
change_type: ModificationType.MODIFY
diff: @@ -1,6 +1,6 @@
 import { ConfigureTokenAction } from "./configure-action";
 import { mdiInformation, mdiKeyChain } from "@mdi/js";
-import { Component, For, Show, createEffect, createResource } from "solid-js";
+import { Component, For, Show, createEffect, createMemo, createResource, on } from "solid-js";
 import { createStore } from "solid-js/store";
 import { InputField, TitledCard } from "#components/fragments";
 import { Select, Heading, Loader } from "#components/primitives";

programming_language: TypeScript
filename: appearance.tsx
change_type: ModificationType.MODIFY
diff: @@ -50,7 +50,7 @@ const AppearanceSection: Component = () => {
 
   return (
     <div class="flex justify-center flex-col items-start w-full gap-5">
-      <TitledCard icon={mdiThemeLightDark} label="UI theme">
+      <TitledCard icon={mdiThemeLightDark} label="Theme">
         <ThemePicker
           theme={userSettings()?.uiTheme || "auto"}
           setTheme={async (theme) => {
@@ -58,14 +58,6 @@ const AppearanceSection: Component = () => {
           }}
         />
       </TitledCard>
-      <TitledCard label="Code editor theme" icon={mdiCodeTags}>
-        <ThemePicker
-          theme={userSettings()?.codeEditorTheme || "dark"}
-          setTheme={async (theme) => {
-            await client.userSettings.update.mutate({ codeEditorTheme: theme });
-          }}
-        />
-      </TitledCard>
       <TitledCard label="Accent color" icon={mdiPaletteSwatch}>
         <div class="grid grid-cols-3 @lg:grid-cols-5 gap-4 w-full group/container">
           <For each={accentColors}>

programming_language: TypeScript
filename: configure-wrapper-subsection.tsx
change_type: ModificationType.DELETE
diff: @@ -1,98 +0,0 @@
-import { mdiCheck, mdiInformation } from "@mdi/js";
-import { Component, createEffect, createMemo, createSignal } from "solid-js";
-import { createStore } from "solid-js/store";
-import { InputField, TitledCard } from "#components/fragments";
-import { Button, IconButton, Tooltip } from "#components/primitives";
-import { useClient, App, useNotifications } from "#context";
-import { validateKey } from "#lib/utils";
-
-interface ConfigureWrapperSubSectionProps {
-  setActionComponent(component: Component<{}> | null): void;
-  onWrapperConfigured(): void;
-}
-
-const ConfigureWrapperSubSection: Component<ConfigureWrapperSubSectionProps> = (props) => {
-  const client = useClient();
-  const { notify } = useNotifications();
-  const [loading, setLoading] = createSignal(false);
-  const [wrapperData, setWrapperData] = createStore<App.Wrapper>({
-    key: "",
-    label: ""
-  });
-  const filled = createMemo(() => {
-    return Boolean(wrapperData.label && validateKey(wrapperData.key));
-  });
-  const onClick = async (): Promise<void> => {
-    try {
-      setLoading(true);
-      await client.workspaceSettings.createWrapper.mutate(wrapperData);
-      notify({ text: "New Wrapper created", type: "success" });
-      props.onWrapperConfigured();
-      setLoading(false);
-    } catch (error) {
-      notify({ text: "Failed to create new Wrapper", type: "error" });
-      setLoading(false);
-    }
-  };
-
-  createEffect(() => {
-    setWrapperData("key", wrapperData.label.toLowerCase().replace(/\s|-/g, "_").slice(0, 20));
-  });
-  props.setActionComponent(() => {
-    return (
-      <>
-        <Button
-          color="primary"
-          class="m-0 hidden @md:flex"
-          loading={loading()}
-          disabled={!filled()}
-          onClick={onClick}
-        >
-          Create Wrapper
-        </Button>
-        <Tooltip text="Create Wrapper" wrapperClass="flex @md:hidden" class="mt-1" fixed>
-          <IconButton
-            color="primary"
-            path={mdiCheck}
-            class="m-0"
-            loading={loading()}
-            disabled={!filled()}
-            onClick={onClick}
-          />
-        </Tooltip>
-      </>
-    );
-  });
-
-  return (
-    <>
-      <TitledCard icon={mdiInformation} label="Details">
-        <InputField
-          label="Wrapper label"
-          color="contrast"
-          placeholder="Label"
-          type="text"
-          value={wrapperData.label}
-          inputProps={{ maxLength: 50 }}
-          setValue={(value) => setWrapperData("label", value)}
-        >
-          Descriptive label for the wrapper.
-        </InputField>
-        <InputField
-          label="Wrapper key"
-          color="contrast"
-          placeholder="wrapper_key"
-          type="text"
-          value={wrapperData.key}
-          inputProps={{ maxLength: 20 }}
-          setValue={(value) => setWrapperData("key", value)}
-        >
-          Key identifying the Wrapper in JSON content. Has to be unique, and can only contain
-          letters, numbers and underscores.
-        </InputField>
-      </TitledCard>
-    </>
-  );
-};
-
-export { ConfigureWrapperSubSection };

programming_language: unknown
filename: index.tsx
change_type: ModificationType.MODIFY
diff: @@ -1,5 +1,4 @@
 import { marks, blocks, embeds } from "./options";
-import { ConfigureWrapperSubSection } from "./configure-wrapper-subsection";
 import { SettingsSectionComponent } from "../view";
 import {
   mdiApplicationBrackets,
@@ -24,74 +23,13 @@ import {
   useNotifications
 } from "#context";
 
-const WrapperDetails: Component<{
-  wrapper: App.Wrapper;
-  onEdit?(): void;
-  onDelete?(): void;
-}> = (props) => {
-  const [loading, setLoading] = createSignal(false);
-  const { notify } = useNotifications();
-  const client = useClient();
-
-  return (
-    <Card class="flex flex-col gap-0 w-full m-0" color="contrast">
-      <div class="flex items-start justify-center gap-2 w-full">
-        <Heading level={3} class="break-anywhere flex-1">
-          {props.wrapper.label || "[No name]"}
-        </Heading>
-        <Show
-          when={!props.wrapper.extension}
-          fallback={
-            <Tooltip text="Extension" class="mt-1">
-              <IconButton path={mdiPuzzle} text="soft" class="m-0" badge />
-            </Tooltip>
-          }
-        >
-          <Show when={hasPermission("manageWorkspace")}>
-            <Tooltip text="Delete" class="mt-1">
-              <IconButton
-                path={mdiTrashCan}
-                text="soft"
-                class="m-0"
-                loading={loading()}
-                onClick={async () => {
-                  try {
-                    setLoading(true);
-                    await client.workspaceSettings.deleteWrapper.mutate({
-                      key: props.wrapper.key
-                    });
-                    setLoading(false);
-                    props.onDelete?.();
-                    notify({
-                      text: "Wrapper deleted",
-                      type: "success"
-                    });
-                  } catch (error) {
-                    setLoading(false);
-                    notify({
-                      text: "Failed to delete wrapper",
-                      type: "error"
-                    });
-                  }
-                }}
-              />
-            </Tooltip>
-          </Show>
-        </Show>
-      </div>
-    </Card>
-  );
-};
 const EditorSection: SettingsSectionComponent = (props) => {
   const { notify } = useNotifications();
-  const [openedSubsection, setOpenedSubsection] = createSignal<"none" | "configure-wrapper">(
-    "none"
-  );
+  const [openedSubsection, setOpenedSubsection] = createSignal<"none">("none");
   const { workspaceSettings } = useAuthenticatedUserData();
   const [enabledMarks, setEnabledMarks] = createSignal<App.WorkspaceSettings["marks"]>([]);
   const [enabledBlocks, setEnabledBlocks] = createSignal<App.WorkspaceSettings["blocks"]>([]);
   const [enabledEmbeds, setEnabledEmbeds] = createSignal<App.WorkspaceSettings["embeds"]>([]);
-  const [wrappers, setWrappers] = createSignal<App.WorkspaceSettings["wrappers"]>([]);
   const [prettierConfig, setPrettierConfig] =
     createSignal<App.WorkspaceSettings["prettierConfig"]>("");
   const client = useClient();
@@ -110,23 +48,12 @@ const EditorSection: SettingsSectionComponent = (props) => {
       embeds: enabledEmbeds()
     });
   }, 350);
-  const handleNewWrapper = (): void => {
-    setOpenedSubsection("configure-wrapper");
-    props.setSubSection({
-      label: "New wrapper",
-      icon: mdiCube,
-      goBack() {
-        setOpenedSubsection("none");
-      }
-    });
-  };
 
   createEffect(() => {
     setEnabledMarks(workspaceSettings()?.marks || []);
     setEnabledBlocks(workspaceSettings()?.blocks || []);
     setEnabledEmbeds(workspaceSettings()?.embeds || []);
     setPrettierConfig(workspaceSettings()?.prettierConfig || "");
-    setWrappers(workspaceSettings()?.wrappers || []);
   });
   createEffect(
     on(openedSubsection, (openedSubsection) => {
@@ -274,44 +201,6 @@ const EditorSection: SettingsSectionComponent = (props) => {
             </For>
           </div>
         </TitledCard>
-        <Show when={enabledBlocks().includes("wrapper")}>
-          <TitledCard
-            label="Wrappers"
-            icon={mdiCube}
-            action={
-              <Show when={hasPermission("manageWorkspace")}>
-                <>
-                  <Button color="primary" class="m-0 hidden @md:flex" onClick={handleNewWrapper}>
-                    New Wrapper
-                  </Button>
-                  <Tooltip text="New Wrapper" wrapperClass="flex @md:hidden" class="mt-1" fixed>
-                    <IconButton
-                      path={mdiPlus}
-                      class="m-0"
-                      color="primary"
-                      onClick={handleNewWrapper}
-                    />
-                  </Tooltip>
-                </>
-              </Show>
-            }
-          >
-            <div class="flex flex-col gap-2 w-full">
-              <For
-                each={wrappers()}
-                fallback={
-                  <p class="px-2 w-full text-start text-gray-500 dark:text-gray-400">
-                    No wrappers found
-                  </p>
-                }
-              >
-                {(wrapper) => {
-                  return <WrapperDetails wrapper={wrapper} />;
-                }}
-              </For>
-            </div>
-          </TitledCard>
-        </Show>
         <TitledCard label="Prettier config" icon={mdiCodeTagsCheck}>
           <p class="prose text-gray-500 dark:text-gray-400">
             Customize your Prettier config for consistent code formatting for all users of the
@@ -320,6 +209,7 @@ const EditorSection: SettingsSectionComponent = (props) => {
           <MiniCodeEditor
             minHeight={200}
             fileName="prettierrc.json"
+            color="contrast"
             code={JSON.stringify(JSON.parse(workspaceSettings()?.prettierConfig || "{}"), null, 2)}
             onSave={async (value) => {
               try {
@@ -341,14 +231,6 @@ const EditorSection: SettingsSectionComponent = (props) => {
           />
         </TitledCard>
       </Match>
-      <Match when={openedSubsection() === "configure-wrapper"}>
-        <ConfigureWrapperSubSection
-          setActionComponent={props.setActionComponent}
-          onWrapperConfigured={() => {
-            setOpenedSubsection("none");
-          }}
-        />
-      </Match>
     </Switch>
   );
 };

programming_language: TypeScript
filename: options.ts
change_type: ModificationType.MODIFY
diff: @@ -96,7 +96,7 @@ const blocks: Record<
     { label: "Image", icon: mdiImage, value: "image" },
     { label: "Table", icon: mdiTable, value: "table" },
     { label: "Horizontal Rule", icon: mdiMinus, value: "horizontalRule" },
-    { label: "Wrapper", icon: mdiCubeOutline, value: "wrapper" }
+    { label: "Element", icon: mdiCubeOutline, value: "element" }
   ]
 };
 const embeds: Array<{

programming_language: TypeScript
filename: index.tsx
change_type: ModificationType.MODIFY
diff: @@ -10,26 +10,26 @@ import {
   on,
   onCleanup
 } from "solid-js";
-import { mdiFormatListBulleted, mdiPlusCircle, mdiTrashCan, mdiTune } from "@mdi/js";
+import { mdiFormatListBulleted, mdiPlusCircle, mdiPuzzle, mdiTrashCan, mdiTune } from "@mdi/js";
 import { createStore } from "solid-js/store";
 import { TitledCard } from "#components/fragments";
 import { App, hasPermission, useClient, useNotifications } from "#context";
 import { Button, Card, Heading, IconButton, Loader, Tooltip } from "#components/primitives";
 
 interface TransformerDetailsProps {
-  transformer: App.Transformer & { inUse?: boolean };
+  transformer: App.Transformer & { inUse?: boolean; extension?: boolean };
   onEdit?(): void;
   onDelete?(): void;
 }
 
 const useTransformers = (): {
   loading: Accessor<boolean>;
-  transformers(): Array<App.Transformer & { inUse?: boolean }>;
+  transformers(): Array<App.Transformer & { inUse?: boolean; extension?: boolean }>;
 } => {
   const client = useClient();
   const [loading, setLoading] = createSignal(false);
   const [state, setState] = createStore<{
-    transformers: Array<App.Transformer>;
+    transformers: Array<App.Transformer & { inUse?: boolean; extension?: boolean }>;
   }>({
     transformers: []
   });
@@ -72,25 +72,34 @@ const TransformerDetails: Component<TransformerDetailsProps> = (props) => {
       <Heading level={2} class="break-anywhere flex-1">
         {props.transformer.label}
       </Heading>
-      <Show when={hasPermission("manageWorkspace")}>
-        <div class="flex gap-2">
-          <Tooltip text="Delete" class="mt-1" enabled={!props.transformer.inUse}>
-            <IconButton
-              path={mdiTrashCan}
-              loading={loading()}
-              disabled={props.transformer.inUse}
-              class="m-0"
-              text="soft"
-              onClick={async () => {
-                setLoading(true);
-                await client.transformers.delete.mutate({ id: props.transformer.id });
-                setLoading(false);
-                props.onDelete?.();
-                notify({ text: "Transformer deleted", type: "success" });
-              }}
-            />
+      <Show
+        when={!props.transformer.extension}
+        fallback={
+          <Tooltip text="Extension" class="mt-1">
+            <IconButton path={mdiPuzzle} text="soft" class="m-0" badge />
           </Tooltip>
-        </div>
+        }
+      >
+        <Show when={hasPermission("manageWorkspace")}>
+          <div class="flex gap-2">
+            <Tooltip text="Delete" class="mt-1" enabled={!props.transformer.inUse}>
+              <IconButton
+                path={mdiTrashCan}
+                loading={loading()}
+                disabled={props.transformer.inUse}
+                class="m-0"
+                text="soft"
+                onClick={async () => {
+                  setLoading(true);
+                  await client.transformers.delete.mutate({ id: props.transformer.id });
+                  setLoading(false);
+                  props.onDelete?.();
+                  notify({ text: "Transformer deleted", type: "success" });
+                }}
+              />
+            </Tooltip>
+          </div>
+        </Show>
       </Show>
     </Card>
   );

programming_language: TypeScript
filename: configure-webhook-subsection.tsx
change_type: ModificationType.MODIFY
diff: @@ -19,7 +19,7 @@ const ConfigureWebhookSubsection: Component<ConfigureWebhookSubsectionProps> = (
   const [loading, setLoading] = createSignal(false);
   const [webhookData, setWebhookData] = createStore<Omit<App.Webhook, "id">>({
     description: "",
-    event: "" as App.WebhookEvent,
+    event: "" as App.WebhookEventName,
     name: "",
     url: ""
   });
@@ -149,7 +149,7 @@ const ConfigureWebhookSubsection: Component<ConfigureWebhookSubsectionProps> = (
           options={webhookEvents}
           value={webhookData.event || ""}
           setValue={(value) => {
-            setWebhookData("event", value as App.WebhookEvent);
+            setWebhookData("event", value as App.WebhookEventName);
           }}
         >
           Event for which the Webhook should be called

programming_language: TypeScript
filename: events.ts
change_type: ModificationType.MODIFY
diff: @@ -1,6 +1,6 @@
 import { App } from "#context";
 
-const webhookEvents: Array<{ label: string; value: App.WebhookEvent }> = [
+const webhookEvents: Array<{ label: string; value: App.WebhookEventName }> = [
   { label: "Content piece updated", value: "contentPieceUpdated" },
   { label: "New content piece added", value: "contentPieceAdded" },
   { label: "Content piece removed", value: "contentPieceRemoved" },

programming_language: TypeScript
filename: tsconfig.json
change_type: ModificationType.MODIFY
diff: @@ -9,7 +9,7 @@
     "resolveJsonModule": true,
     "jsx": "preserve",
     "jsxImportSource": "solid-js",
-    "types": ["vite/client", "mdx", "@vrite/extensions"],
+    "types": ["vite/client", "@vrite/extensions"],
     "baseUrl": ".",
     "paths": {
       "#*": ["./src/*", "../../packages/backend/src/*"]

programming_language: TypeScript
filename: vite.config.ts
change_type: ModificationType.MODIFY
diff: @@ -6,6 +6,7 @@ import unocss from "unocss/vite";
 export default defineConfig(async ({ mode }) => {
   const plugins: PluginOption[] = [tsconfigPaths(), unocss(), solidPlugin()];
   const env = loadEnv(mode, process.cwd(), "PUBLIC_");
+  const proxyTarget = env.PUBLIC_APP_URL;
 
   if (mode === "development") {
     // Only transform index.html in dev mode - in production Handlebars will do this
@@ -25,14 +26,13 @@ export default defineConfig(async ({ mode }) => {
     server: {
       proxy: {
         "/api": {
-          target: "http://localhost:3333",
+          target: proxyTarget,
           ws: true
         },
-        "/session": { target: "http://localhost:3333", ws: true },
-        "/login": { target: "http://localhost:3333", ws: true },
-        "/github": { target: "http://localhost:3333", ws: true },
-        "/proxy": { target: "http://localhost:3333", ws: true },
-        "/upload": { target: "http://localhost:3333", ws: true }
+        "/session": { target: proxyTarget, ws: true },
+        "/login": { target: proxyTarget, ws: true },
+        "/github": { target: proxyTarget, ws: true },
+        "/upload": { target: proxyTarget, ws: true }
       }
     },
     build: {

programming_language: TypeScript
filename: package.json
change_type: ModificationType.MODIFY
diff: @@ -1,6 +1,6 @@
 {
   "name": "vrite",
-  "version": "0.2.1",
+  "version": "0.3.0",
   "license": "AGPL-3.0-only",
   "private": true,
   "workspaces": [

programming_language: JavaScript
filename: comments.ts
change_type: ModificationType.MODIFY
diff: @@ -1,7 +1,7 @@
-import { Collection, Db, ObjectId } from "mongodb";
-import { UnderscoreID, zodId } from "#lib/mongo";
 import { Profile, profile } from "./users";
+import { Collection, Db, ObjectId } from "mongodb";
 import { z } from "zod";
+import { UnderscoreID, zodId } from "#lib/mongo";
 
 const comment = z.object({
   id: zodId(),

programming_language: TypeScript
filename: index.ts
change_type: ModificationType.MODIFY
diff: @@ -17,6 +17,5 @@ export * from "./content-variants";
 export * from "./variants";
 export * from "./content-groups";
 export * from "./git-data";
-export * from "./versions";
 export * from "./variants";
 export * from "./transformers";

programming_language: TypeScript
filename: transformers.ts
change_type: ModificationType.MODIFY
diff: @@ -16,6 +16,7 @@ interface Transformer<ID extends string | ObjectId = string>
 }
 interface FullTransformer<ID extends string | ObjectId = string> extends Transformer<ID> {
   workspaceId: ID;
+  extensionId?: ID;
 }
 
 const getTransformersCollection = (db: Db): Collection<UnderscoreID<FullTransformer<ObjectId>>> => {

programming_language: TypeScript
filename: users.ts
change_type: ModificationType.MODIFY
diff: @@ -5,7 +5,7 @@ import { UnderscoreID, zodId } from "#lib/mongo";
 const user = z.object({
   id: zodId(),
   username: z.string().min(1).max(20),
-  email: z.string().email(),
+  email: z.string().email().max(320),
   external: z
     .object({
       github: z

programming_language: TypeScript
filename: versions.ts
change_type: ModificationType.DELETE
diff: @@ -1,38 +0,0 @@
-import { ContentPiece, contentPiece } from "./content-pieces";
-import { ContentPieceVariant, contentPieceVariant } from "./content-piece-variants";
-import { Binary, Collection, Db, ObjectId } from "mongodb";
-import { z } from "zod";
-import { UnderscoreID, zodId } from "#lib/mongo";
-
-const version = z.object({
-  id: zodId(),
-  name: z.string(),
-  date: z.string(),
-  content: z.any().optional(),
-  contentPiece: contentPieceVariant.omit({ variantId: true, contentPieceId: true, id: true }),
-  contentPieceId: zodId(),
-  variantId: zodId().optional()
-});
-
-interface Version<ID extends string | ObjectId = string>
-  extends Omit<
-    z.infer<typeof version>,
-    "id" | "date" | "contentPieceId" | "variantId" | "content" | "contentPiece"
-  > {
-  date: ID extends string ? string : Date;
-  content?: Binary;
-  contentPiece: Omit<ContentPieceVariant<ID>, "id" | "variantId" | "contentPieceId">;
-  contentPieceId: ID;
-  variantId?: ID;
-  id: ID;
-}
-interface FullVersion<ID extends string | ObjectId = string> extends Version<ID> {
-  workspaceId: ID;
-}
-
-const getVersionsCollection = (db: Db): Collection<UnderscoreID<FullVersion<ObjectId>>> => {
-  return db.collection("contents");
-};
-
-export { getVersionsCollection, version };
-export type { Version, FullVersion };

programming_language: unknown
filename: webhooks.ts
change_type: ModificationType.MODIFY
diff: @@ -13,7 +13,7 @@ const contentGroupEvents = [
   "contentGroupMoved"
 ] as const;
 const memberEvents = ["memberInvited", "memberAdded", "memberRemoved"] as const;
-const webhookEvent = z.enum([...contentPieceEvents, ...contentGroupEvents, ...memberEvents]);
+const webhookEventName = z.enum([...contentPieceEvents, ...contentGroupEvents, ...memberEvents]);
 const webhookMetadata = z.object({
   contentGroupId: zodId()
 });
@@ -23,10 +23,10 @@ const webhook = z.object({
   name: z.string().min(1).max(50),
   description: z.string().optional(),
   metadata: webhookMetadata.optional(),
-  event: webhookEvent
+  event: webhookEventName
 });
 
-type WebhookEvent = z.infer<typeof webhookEvent>;
+type WebhookEventName = z.infer<typeof webhookEventName>;
 type WebhookMetadata<ID extends string | ObjectId = string> = {
   contentGroupId: ID;
 };
@@ -47,10 +47,10 @@ const getWebhooksCollection = (db: Db): Collection<UnderscoreID<FullWebhook<Obje
 
 export {
   webhook,
-  webhookEvent,
+  webhookEventName,
   getWebhooksCollection,
   contentPieceEvents,
   contentGroupEvents,
   memberEvents
 };
-export type { WebhookEvent, Webhook, FullWebhook };
+export type { WebhookEventName, Webhook, FullWebhook };

programming_language: TypeScript
filename: workspace-memberships.ts
change_type: ModificationType.MODIFY
diff: @@ -6,7 +6,7 @@ const workspaceMembership = z.object({
   id: zodId(),
   userId: zodId().optional(),
   roleId: zodId(),
-  email: z.string().email().optional(),
+  email: z.string().email().max(320).optional(),
   name: z.string().max(50).optional()
 });
 const workspaceInviteCodeDetails = z.object({

programming_language: TypeScript
filename: workspace-settings.ts
change_type: ModificationType.MODIFY
diff: @@ -33,15 +33,6 @@ const metadataSettings = z
     enabledFields: z.array(metadataField).optional()
   })
   .partial();
-const wrapper = z.object({
-  label: z.string().min(1).max(50),
-  key: z
-    .string()
-    .min(1)
-    .max(20)
-    .regex(/^[a-z0-9_]*$/),
-  extension: z.boolean().optional()
-});
 const marks = [
   "bold",
   "italic",
@@ -67,7 +58,7 @@ const blocks = [
   "horizontalRule",
   "image",
   "table",
-  "wrapper"
+  "element"
 ] as const;
 const embeds = ["codepen", "codesandbox", "youtube"] as const;
 const workspaceSettings = z.object({
@@ -76,15 +67,12 @@ const workspaceSettings = z.object({
   metadata: metadataSettings.optional(),
   marks: z.array(z.enum(marks)),
   blocks: z.array(z.enum(blocks)),
-  embeds: z.array(z.enum(embeds)),
-  wrappers: z.array(wrapper).optional()
+  embeds: z.array(z.enum(embeds))
 });
 
-interface Wrapper extends z.infer<typeof wrapper> {}
 interface WorkspaceSettings<ID extends string | ObjectId = string>
-  extends Omit<z.infer<typeof workspaceSettings>, "id" | "wrappers"> {
+  extends Omit<z.infer<typeof workspaceSettings>, "id"> {
   id: ID;
-  wrappers?: Wrapper[];
 }
 interface FullWorkspaceSettings<ID extends string | ObjectId = string>
   extends WorkspaceSettings<ID> {
@@ -107,7 +95,6 @@ export {
   embeds,
   workspaceSettings,
   metadataSettings,
-  wrapper,
   getWorkspaceSettingsCollection
 };
-export type { MetadataField, MetadataSettings, WorkspaceSettings, FullWorkspaceSettings, Wrapper };
+export type { MetadataField, MetadataSettings, WorkspaceSettings, FullWorkspaceSettings };

programming_language: TypeScript
filename: env.ts
change_type: ModificationType.MODIFY
diff: @@ -1,4 +1,4 @@
-import { optional, z } from "zod";
+import { z } from "zod";
 
 const envSchema = z.object({
   NODE_ENV: z.string(),

programming_language: JavaScript
filename: comment.ts
change_type: ModificationType.ADD
diff: @@ -0,0 +1,34 @@
+import { Observable } from "@trpc/server/observable";
+import { Comment, CommentThread, CommentMember } from "#database";
+import { Context } from "#lib/context";
+import { createEventPublisher, createEventSubscription } from "#lib/pub-sub";
+
+type CommentEvent =
+  | { action: "createThread"; data: CommentThread }
+  | { action: "resolveThread"; data: Pick<CommentThread, "id" | "fragment" | "resolved"> }
+  | { action: "deleteThread"; data: Pick<CommentThread, "id" | "fragment"> }
+  | {
+      action: "createComment";
+      data: Omit<Comment, "memberId"> & { member: CommentMember | null };
+    }
+  | {
+      action: "updateComment";
+      data: Pick<Comment, "id" | "content">;
+    }
+  | {
+      action: "deleteComment";
+      data: Pick<Comment, "id">;
+    };
+
+const publishCommentEvent = createEventPublisher<CommentEvent>((contentPieceId) => {
+  return `comments:${contentPieceId}`;
+});
+const subscribeToCommentEvents = (
+  ctx: Context,
+  contentPieceId: string
+): Observable<CommentEvent, unknown> => {
+  return createEventSubscription<CommentEvent>(ctx, `comments:${contentPieceId}`);
+};
+
+export { publishCommentEvent, subscribeToCommentEvents };
+export type { CommentEvent };

programming_language: TypeScript
filename: content-group.ts
change_type: ModificationType.ADD
diff: @@ -0,0 +1,30 @@
+import { Observable } from "@trpc/server/observable";
+import { Context } from "#lib/context";
+import { createEventPublisher, createEventSubscription } from "#lib/pub-sub";
+import { ContentGroup } from "#database";
+
+type ContentGroupEvent =
+  | {
+      action: "create";
+      data: ContentGroup;
+    }
+  | {
+      action: "update";
+      data: Partial<ContentGroup> & { id: string };
+    }
+  | { action: "delete"; data: { id: string } }
+  | { action: "move"; data: ContentGroup }
+  | { action: "reorder"; data: { id: string; index: number } };
+
+const publishContentGroupEvent = createEventPublisher<ContentGroupEvent>(
+  (workspaceId) => `contentGroups:${workspaceId}`
+);
+const subscribeToContentGroupEvents = (
+  ctx: Context,
+  workspaceId: string
+): Observable<ContentGroupEvent, unknown> => {
+  return createEventSubscription<ContentGroupEvent>(ctx, `contentGroups:${workspaceId}`);
+};
+
+export { publishContentGroupEvent, subscribeToContentGroupEvents };
+export type { ContentGroupEvent };

programming_language: TypeScript
filename: content-piece.ts
change_type: ModificationType.ADD
diff: @@ -0,0 +1,36 @@
+import { Observable } from "@trpc/server/observable";
+import { Context } from "#lib/context";
+import { createEventPublisher, createEventSubscription } from "#lib/pub-sub";
+import { FullContentPieceWithAdditionalData } from "#database";
+
+type ContentPieceEvent =
+  | { action: "delete"; userId: string; data: { id: string } }
+  | { action: "create"; userId: string; data: FullContentPieceWithAdditionalData }
+  | {
+      action: "update";
+      userId: string;
+      variantId?: string;
+      data: Partial<FullContentPieceWithAdditionalData> & { id: string };
+    }
+  | {
+      action: "move";
+      userId: string;
+      data: {
+        contentPiece: FullContentPieceWithAdditionalData;
+        nextReferenceId?: string;
+        previousReferenceId?: string;
+      };
+    };
+
+const publishContentPieceEvent = createEventPublisher<ContentPieceEvent>((contentGroupId) => {
+  return `contentPieces:${contentGroupId}`;
+});
+const subscribeToContentPieceEvents = (
+  ctx: Context,
+  contentGroupId: string
+): Observable<ContentPieceEvent, unknown> => {
+  return createEventSubscription<ContentPieceEvent>(ctx, `contentPieces:${contentGroupId}`);
+};
+
+export { publishContentPieceEvent, subscribeToContentPieceEvents };
+export type { ContentPieceEvent };

programming_language: TypeScript
filename: extension.ts
change_type: ModificationType.ADD
diff: @@ -0,0 +1,22 @@
+import { Observable } from "@trpc/server/observable";
+import { ContextObject, Extension } from "#database";
+import { Context } from "#lib/context";
+import { createEventPublisher, createEventSubscription } from "#lib/pub-sub";
+
+type ExtensionEvent =
+  | { action: "delete"; data: { id: string } }
+  | { action: "create"; data: Extension & { id: string } }
+  | { action: "update"; data: { id: string; config: ContextObject } };
+
+const publishExtensionEvent = createEventPublisher<ExtensionEvent>((workspaceId) => {
+  return `extensions:${workspaceId}`;
+});
+const subscribeToExtensionEvents = (
+  ctx: Context,
+  workspaceId: string
+): Observable<ExtensionEvent, unknown> => {
+  return createEventSubscription<ExtensionEvent>(ctx, `extensions:${workspaceId}`);
+};
+
+export { publishExtensionEvent, subscribeToExtensionEvents };
+export type { ExtensionEvent };

programming_language: TypeScript
filename: git-data.ts
change_type: ModificationType.ADD
diff: @@ -0,0 +1,31 @@
+import { Observable } from "@trpc/server/observable";
+import { GitData } from "#database";
+import { Context } from "#lib/context";
+import { createEventPublisher, createEventSubscription } from "#lib/pub-sub";
+
+type GitDataEvent =
+  | {
+      action: "configure";
+      data: GitData;
+    }
+  | {
+      action: "update";
+      data: Partial<GitData>;
+    }
+  | {
+      action: "reset";
+      data: {};
+    };
+
+const publishGitDataEvent = createEventPublisher<GitDataEvent>((workspaceId) => {
+  return `gitData:${workspaceId}`;
+});
+const subscribeToGitDataEvents = (
+  ctx: Context,
+  workspaceId: string
+): Observable<GitDataEvent, unknown> => {
+  return createEventSubscription<GitDataEvent>(ctx, `gitData:${workspaceId}`);
+};
+
+export { publishGitDataEvent, subscribeToGitDataEvents };
+export type { GitDataEvent };

programming_language: TypeScript
filename: index.ts
change_type: ModificationType.ADD
diff: @@ -0,0 +1,16 @@
+export * from "./comment";
+export * from "./content-group";
+export * from "./content-piece";
+export * from "./extension";
+export * from "./tag";
+export * from "./token";
+export * from "./transformer";
+export * from "./user-settings";
+export * from "./user";
+export * from "./variant";
+export * from "./workspace-membership";
+export * from "./webhook";
+export * from "./workspace-settings";
+export * from "./workspace";
+export * from "./git-data";
+export * from "./role";

programming_language: TypeScript
filename: role.ts
change_type: ModificationType.ADD
diff: @@ -0,0 +1,23 @@
+import { Observable } from "@trpc/server/observable";
+import { Role } from "#database";
+import { Context } from "#lib/context";
+import { createEventPublisher, createEventSubscription } from "#lib/pub-sub";
+
+type RoleEvent =
+  | {
+      action: "create";
+      data: Role;
+    }
+  | { action: "update"; data: Partial<Role> & { id: string } }
+  | { action: "delete"; data: { id: string; newRole: Role } };
+
+const publishRoleEvent = createEventPublisher((workspaceId) => `roles:${workspaceId}`);
+const subscribeToRoleEvents = (
+  ctx: Context,
+  workspaceId: string
+): Observable<RoleEvent, unknown> => {
+  return createEventSubscription<RoleEvent>(ctx, `roles:${workspaceId}`);
+};
+
+export { publishRoleEvent, subscribeToRoleEvents };
+export type { RoleEvent };

programming_language: TypeScript
filename: tag.ts
change_type: ModificationType.ADD
diff: @@ -0,0 +1,20 @@
+import { Observable } from "@trpc/server/observable";
+import { Context } from "#lib/context";
+import { createEventPublisher, createEventSubscription } from "#lib/pub-sub";
+import { Tag } from "#database";
+
+type TagEvent =
+  | { action: "create"; data: Tag }
+  | { action: "update"; data: Partial<Tag> & { id: string } }
+  | {
+      action: "delete";
+      data: { id: string };
+    };
+
+const publishTagEvent = createEventPublisher<TagEvent>((workspaceId) => `tags:${workspaceId}`);
+const subscribeToTagEvents = (ctx: Context, workspaceId: string): Observable<TagEvent, unknown> => {
+  return createEventSubscription<TagEvent>(ctx, `tags:${workspaceId}`);
+};
+
+export { publishTagEvent, subscribeToTagEvents };
+export type { TagEvent };

programming_language: TypeScript
filename: token.ts
change_type: ModificationType.ADD
diff: @@ -0,0 +1,25 @@
+import { Observable } from "@trpc/server/observable";
+import { Context } from "#lib/context";
+import { createEventPublisher, createEventSubscription } from "#lib/pub-sub";
+import { Token } from "#database";
+
+type TokenEvent =
+  | {
+      action: "create";
+      data: Token;
+    }
+  | { action: "update"; data: Partial<Token> & { id: string } }
+  | { action: "delete"; data: { id: string } };
+
+const publishTokenEvent = createEventPublisher<TokenEvent>(
+  (workspaceId) => `tokens:${workspaceId}`
+);
+const subscribeToTokenEvents = (
+  ctx: Context,
+  workspaceId: string
+): Observable<TokenEvent, unknown> => {
+  return createEventSubscription<TokenEvent>(ctx, `tokens:${workspaceId}`);
+};
+
+export { publishTokenEvent, subscribeToTokenEvents };
+export type { TokenEvent };

programming_language: TypeScript
filename: transformer.ts
change_type: ModificationType.ADD
diff: @@ -0,0 +1,27 @@
+import { Observable } from "@trpc/server/observable";
+import { Context } from "#lib/context";
+import { createEventPublisher, createEventSubscription } from "#lib/pub-sub";
+import { Transformer } from "#database";
+
+type TransformerEvent =
+  | {
+      action: "create";
+      data: Transformer & { id: string };
+    }
+  | {
+      action: "delete";
+      data: { id: string };
+    };
+
+const publishTransformerEvent = createEventPublisher<TransformerEvent>(
+  (workspaceId) => `transformers:${workspaceId}`
+);
+const subscribeToTransformerEvents = (
+  ctx: Context,
+  workspaceId: string
+): Observable<TransformerEvent, unknown> => {
+  return createEventSubscription<TransformerEvent>(ctx, `transformers:${workspaceId}`);
+};
+
+export { publishTransformerEvent, subscribeToTransformerEvents };
+export type { TransformerEvent };

programming_language: TypeScript
filename: user-settings.ts
change_type: ModificationType.ADD
diff: @@ -0,0 +1,19 @@
+import { Observable } from "@trpc/server/observable";
+import { AppearanceSettings } from "#database";
+import { Context } from "#lib/context";
+import { createEventPublisher, createEventSubscription } from "#lib/pub-sub";
+
+type UserSettingsEvent = { action: "update"; data: Partial<AppearanceSettings> };
+
+const publishUserSettingsEvent = createEventPublisher<UserSettingsEvent>(
+  (userId) => `userSettings:${userId}`
+);
+const subscribeToUserSettingsEvents = (
+  ctx: Context,
+  userId: string
+): Observable<UserSettingsEvent, unknown> => {
+  return createEventSubscription<UserSettingsEvent>(ctx, `userSettings:${userId}`);
+};
+
+export { publishUserSettingsEvent, subscribeToUserSettingsEvents };
+export type { UserSettingsEvent };

programming_language: TypeScript
filename: user.ts
change_type: ModificationType.ADD
diff: @@ -0,0 +1,17 @@
+import { Observable } from "@trpc/server/observable";
+import { VerificationDetails, Profile } from "#database";
+import { Context } from "#lib/context";
+import { createEventPublisher, createEventSubscription } from "#lib/pub-sub";
+
+type UserEvent = {
+  action: "update";
+  data: Partial<Profile> & { id: string } & Partial<VerificationDetails>;
+};
+
+const publishUserEvent = createEventPublisher<UserEvent>((userId: string) => `user:${userId}`);
+const subscribeToUserEvents = (ctx: Context, userId: string): Observable<UserEvent, unknown> => {
+  return createEventSubscription<UserEvent>(ctx, `user:${userId}`);
+};
+
+export { publishUserEvent, subscribeToUserEvents };
+export type { UserEvent };

programming_language: TypeScript
filename: variant.ts
change_type: ModificationType.ADD
diff: @@ -0,0 +1,31 @@
+import { Observable } from "@trpc/server/observable";
+import { Variant } from "#database";
+import { Context } from "#lib/context";
+import { createEventPublisher, createEventSubscription } from "#lib/pub-sub";
+
+type VariantEvent =
+  | {
+      action: "create";
+      data: Variant & { id: string };
+    }
+  | {
+      action: "update";
+      data: Partial<Variant> & { id: string };
+    }
+  | {
+      action: "delete";
+      data: { id: string };
+    };
+
+const publishVariantEvent = createEventPublisher<VariantEvent>(
+  (workspaceId) => `variants:${workspaceId}`
+);
+const subscribeToVariantEvents = (
+  ctx: Context,
+  workspaceId: string
+): Observable<VariantEvent, unknown> => {
+  return createEventSubscription<VariantEvent>(ctx, `variants:${workspaceId}`);
+};
+
+export { publishVariantEvent, subscribeToVariantEvents };
+export type { VariantEvent };

programming_language: TypeScript
filename: webhook.ts
change_type: ModificationType.ADD
diff: @@ -0,0 +1,31 @@
+import { Observable } from "@trpc/server/observable";
+import { Context } from "#lib/context";
+import { createEventPublisher, createEventSubscription } from "#lib/pub-sub";
+import { Webhook } from "#database";
+
+type WebhookEvent =
+  | {
+      action: "create";
+      data: Webhook & { id: string };
+    }
+  | {
+      action: "update";
+      data: Partial<Webhook> & { id: string };
+    }
+  | {
+      action: "delete";
+      data: { id: string };
+    };
+
+const publishWebhookEvent = createEventPublisher<WebhookEvent>((workspaceId) => {
+  return `webhooks:${workspaceId}`;
+});
+const subscribeToWebhookEvents = (
+  ctx: Context,
+  workspaceId: string
+): Observable<WebhookEvent, unknown> => {
+  return createEventSubscription<WebhookEvent>(ctx, `webhooks:${workspaceId}`);
+};
+
+export { publishWebhookEvent, subscribeToWebhookEvents };
+export type { WebhookEvent };

programming_language: TypeScript
filename: workspace-membership.ts
change_type: ModificationType.ADD
diff: @@ -0,0 +1,41 @@
+import { Observable } from "@trpc/server/observable";
+import { Role, WorkspaceMembership } from "#database";
+import { Context } from "#lib/context";
+import { createEventPublisher, createEventSubscription } from "#lib/pub-sub";
+
+type WorkspaceMembershipEvent =
+  | { action: "create"; data: { id: string; pendingInvite: boolean } & WorkspaceMembership }
+  | {
+      action: "update";
+      data: {
+        id: string;
+        userId: string;
+        role?: Role;
+        pendingInvite?: boolean;
+        profile?: {
+          fullName?: string;
+          username?: string;
+          avatar?: string;
+        };
+      } & Partial<WorkspaceMembership>;
+    }
+  | {
+      action: "delete";
+      data: { id: string; userId: string };
+    };
+
+const publishWorkspaceMembershipEvent = createEventPublisher<WorkspaceMembershipEvent>(
+  (workspaceId: string) => `workspaceMemberships:${workspaceId}`
+);
+const subscribeToWorkspaceMembershipEvents = (
+  ctx: Context,
+  workspaceId: string
+): Observable<WorkspaceMembershipEvent, unknown> => {
+  return createEventSubscription<WorkspaceMembershipEvent>(
+    ctx,
+    `workspaceMemberships:${workspaceId}`
+  );
+};
+
+export { publishWorkspaceMembershipEvent, subscribeToWorkspaceMembershipEvents };
+export type { WorkspaceMembershipEvent };

programming_language: TypeScript
filename: workspace-settings.ts
change_type: ModificationType.ADD
diff: @@ -0,0 +1,24 @@
+import { Observable } from "@trpc/server/observable";
+import { WorkspaceSettings } from "#database";
+import { Context } from "#lib/context";
+import { createEventPublisher, createEventSubscription } from "#lib/pub-sub";
+
+type WorkspaceSettingsEvent = {
+  action: "update";
+  data: Partial<Omit<WorkspaceSettings, "id">>;
+};
+
+const publishWorkspaceSettingsEvent = createEventPublisher<WorkspaceSettingsEvent>(
+  (workspaceId) => {
+    return `workspaceSettings:${workspaceId}`;
+  }
+);
+const subscribeToWorkspaceSettingsEvents = (
+  ctx: Context,
+  workspaceId: string
+): Observable<WorkspaceSettingsEvent, unknown> => {
+  return createEventSubscription<WorkspaceSettingsEvent>(ctx, `workspaceSettings:${workspaceId}`);
+};
+
+export { publishWorkspaceSettingsEvent, subscribeToWorkspaceSettingsEvents };
+export type { WorkspaceSettingsEvent };

programming_language: TypeScript
filename: workspace.ts
change_type: ModificationType.ADD
diff: @@ -0,0 +1,21 @@
+import { Observable } from "@trpc/server/observable";
+import { Workspace } from "#database";
+import { Context } from "#lib/context";
+import { createEventPublisher, createEventSubscription } from "#lib/pub-sub";
+
+type WorkspaceEvent =
+  | { action: "update"; data: Partial<Workspace> & { id: string } }
+  | { action: "delete"; data: { id: string } };
+
+const publishWorkspaceEvent = createEventPublisher<WorkspaceEvent>((workspaceId) => {
+  return `workspace:${workspaceId}`;
+});
+const subscribeToWorkspaceEvents = (
+  ctx: Context,
+  workspaceId: string
+): Observable<WorkspaceEvent, unknown> => {
+  return createEventSubscription<WorkspaceEvent>(ctx, `workspace:${workspaceId}`);
+};
+
+export { publishWorkspaceEvent, subscribeToWorkspaceEvents };
+export type { WorkspaceEvent };

programming_language: TypeScript
filename: index.ts
change_type: ModificationType.MODIFY
diff: @@ -1,5 +1,6 @@
-export * from "./server";
 export * from "./lib";
 export * from "./plugins";
-export * from "./routes";
 export * from "./database";
+export * from "./events";
+export * from "./routes";
+export * from "./server";

programming_language: TypeScript
filename: auth.ts
change_type: ModificationType.MODIFY
diff: @@ -1,7 +1,7 @@
 import { Context } from "./context";
 import { SessionData, getSessionId } from "./session";
 import { verifyValue } from "./hash";
-import { TokenPermission, getTokensCollection } from "#database/tokens";
+import { TokenPermission, getTokensCollection } from "#database";
 
 interface TokenData {
   permissions: TokenPermission[];

programming_language: TypeScript
filename: context.ts
change_type: ModificationType.MODIFY
diff: @@ -2,13 +2,21 @@ import { CreateFastifyContextOptions } from "@trpc/server/adapters/fastify";
 import { FastifyInstance, FastifyReply, FastifyRequest } from "fastify";
 import { Db } from "mongodb";
 
-interface Context {
+interface FastifyContext {
   fastify: FastifyInstance;
   req: FastifyRequest;
   res: FastifyReply;
+}
+interface Context extends FastifyContext {
   db: Db;
 }
 
+const createFastifyContext = (
+  { req, res }: CreateFastifyContextOptions,
+  fastify: FastifyInstance
+): FastifyContext => {
+  return { req, res, fastify };
+};
 const createContext = (
   { req, res }: CreateFastifyContextOptions,
   fastify: FastifyInstance
@@ -19,8 +27,11 @@ const createContext = (
     throw new Error("Database not connected");
   }
 
-  return { req, res, db, fastify };
+  return {
+    ...createFastifyContext({ req, res }, fastify),
+    db
+  };
 };
 
-export { createContext };
-export type { Context };
+export { createContext, createFastifyContext };
+export type { FastifyContext, Context };

programming_language: TypeScript
filename: index.ts
change_type: ModificationType.ADD
diff: @@ -0,0 +1,4 @@
+export {
+  createInputContentProcessor as createInputContentProcessorGitHub,
+  createOutputContentProcessor as createOutputContentProcessorGitHub
+} from "./process-content";

programming_language: TypeScript
filename: process-content.ts
change_type: ModificationType.RENAME
diff: @@ -1,3 +1,7 @@
+import { AuthenticatedContext } from "../../middleware";
+import { UnderscoreID } from "../../mongo";
+import { jsonToBuffer, htmlToJSON, bufferToJSON } from "../../processing";
+import { InputContentProcessor, OutputContentProcessor } from "../types";
 import {
   GenericJSONContentNode,
   gfmInputTransformer,
@@ -5,44 +9,18 @@ import {
   InputTransformer,
   OutputTransformer
 } from "@vrite/sdk/transformers";
-import { ObjectId, Binary } from "mongodb";
-import { convert as convertToSlug } from "url-slug";
+import { ObjectId } from "mongodb";
 import * as prettier from "prettier/standalone";
 import markdownPlugin from "prettier/plugins/markdown";
 import htmlPlugin from "prettier/plugins/html";
 import axios from "axios";
 import crypto from "node:crypto";
 import {
-  FullContentPiece,
-  FullContents,
   FullGitData,
   getTransformersCollection,
   getWorkspaceSettingsCollection,
   Transformer
 } from "#database";
-import { UnderscoreID, jsonToBuffer, htmlToJSON, bufferToJSON, AuthenticatedContext } from "#lib";
-
-interface ProcessInputResult {
-  buffer: Buffer;
-  contentHash: string;
-  metadata: Partial<
-    Pick<FullContentPiece, keyof NonNullable<ReturnType<InputTransformer>["contentPiece"]>>
-  >;
-}
-interface OutputContentProcessorInput {
-  buffer: Buffer;
-  contentPiece: UnderscoreID<FullContentPiece<ObjectId>>;
-}
-
-interface InputContentProcessor {
-  process(inputContent: string): Promise<ProcessInputResult>;
-  processBatch(inputContent: string[]): Promise<ProcessInputResult[]>;
-}
-
-interface OutputContentProcessor {
-  process(input: OutputContentProcessorInput): Promise<string>;
-  processBatch(input: OutputContentProcessorInput[]): Promise<string[]>;
-}
 
 const extensionParserMap = {
   mdx: "mdx",
@@ -256,58 +234,5 @@ const createOutputContentProcessor = async (
     }
   };
 };
-const createSyncedPieces = async (
-  inputs: Array<{
-    path: string;
-    content: string;
-    workspaceId: ObjectId;
-    contentGroupId: ObjectId;
-    order: string;
-  }>,
-  inputContentProcessor: InputContentProcessor
-): Promise<
-  Array<{
-    contentPiece: UnderscoreID<FullContentPiece<ObjectId>>;
-    content: UnderscoreID<FullContents<ObjectId>>;
-    contentHash: string;
-  }>
-> => {
-  const inputContentProcessorOutput = await inputContentProcessor.processBatch(
-    inputs.map((input) => input.content)
-  );
-
-  return inputs.map((input, index) => {
-    const filename = input.path.split("/").pop() || "";
-    const { buffer, contentHash, metadata } = inputContentProcessorOutput[index];
-    const { members, tags, date, ...inputMetadata } = metadata;
-    const contentPiece: UnderscoreID<FullContentPiece<ObjectId>> = {
-      _id: new ObjectId(),
-      workspaceId: input.workspaceId,
-      contentGroupId: input.contentGroupId,
-      order: input.order,
-      members: [],
-      slug: convertToSlug(filename),
-      tags: [],
-      title: filename,
-      filename,
-      ...inputMetadata,
-      ...(date && { date: new Date(date) }),
-      ...(members && { members: members.map((memberId) => new ObjectId(memberId)) }),
-      ...(tags && { tags: tags.map((tagId) => new ObjectId(tagId)) })
-    };
-    const content = {
-      _id: new ObjectId(),
-      contentPieceId: contentPiece._id,
-      content: new Binary(buffer)
-    };
-
-    return {
-      contentPiece,
-      contentHash,
-      content
-    };
-  });
-};
 
-export { createSyncedPieces, createInputContentProcessor, createOutputContentProcessor };
-export type { OutputContentProcessorInput, OutputContentProcessor, InputContentProcessor };
+export { createInputContentProcessor, createOutputContentProcessor };

programming_language: TypeScript
filename: hooks.ts
change_type: ModificationType.RENAME
diff: @@ -1,7 +1,10 @@
 /* eslint-disable sonarjs/no-identical-functions */
-import { AuthenticatedContext } from "./middleware";
-import { ObjectId, UnderscoreID } from "./mongo";
-import { jsonToBuffer } from "./processing";
+import { createGenericOutputContentProcessor } from "./process-content";
+import { OutputContentProcessor } from "./types";
+import { AuthenticatedContext } from "../middleware";
+import { UnderscoreID } from "../mongo";
+import { jsonToBuffer } from "../processing";
+import { ObjectId } from "mongodb";
 import crypto from "node:crypto";
 import {
   FullContentGroup,
@@ -14,11 +17,7 @@ import {
   getContentsCollection,
   getGitDataCollection
 } from "#database";
-import {
-  OutputContentProcessor,
-  createOutputContentProcessor as createOutputContentProcessorGitHub
-} from "#routes/git/github/process-content";
-import { publishGitDataEvent } from "#routes/git/events";
+import { publishGitDataEvent } from "#events";
 
 type GitSyncHookEvent =
   | "contentPieceUpdated"
@@ -74,23 +73,6 @@ type GitSyncHookHandler<E extends GitSyncHookEvent> = (
   data: GitSyncHookEventData[E]
 ) => Promise<GitSyncHookData>;
 
-const createGenericOutputContentProcessor = async (
-  ctx: AuthenticatedContext,
-  gitData: UnderscoreID<FullGitData<ObjectId>>
-): Promise<OutputContentProcessor> => {
-  if (gitData.provider === "github") {
-    return await createOutputContentProcessorGitHub(ctx, gitData);
-  }
-
-  return {
-    process() {
-      return Promise.resolve("");
-    },
-    processBatch(input) {
-      return Promise.resolve(input.map(() => ""));
-    }
-  };
-};
 const handleContentGroupMoved: GitSyncHookHandler<"contentGroupMoved"> = async (
   { ctx, directories, records, outputContentProcessor },
   data

programming_language: TypeScript
filename: index.ts
change_type: ModificationType.ADD
diff: @@ -0,0 +1,4 @@
+export * from "./hooks";
+export * from "./process-content";
+export * from "./github";
+export * from "./types";

programming_language: TypeScript
filename: process-content.ts
change_type: ModificationType.RENAME
diff: @@ -1,9 +1,5 @@
-import {
-  OutputContentProcessor,
-  InputContentProcessor,
-  createOutputContentProcessor as createOutputContentProcessorGitHub,
-  createInputContentProcessor as createInputContentProcessorGitHub
-} from "./github";
+import { createOutputContentProcessorGitHub, createInputContentProcessorGitHub } from "./github";
+import { InputContentProcessor, OutputContentProcessor } from "./types";
 import { ObjectId } from "mongodb";
 import { FullGitData } from "#database";
 import { AuthenticatedContext, UnderscoreID } from "#lib";

programming_language: TypeScript
filename: types.ts
change_type: ModificationType.ADD
diff: @@ -0,0 +1,28 @@
+import { InputTransformer } from "@vrite/sdk/transformers";
+import { ObjectId } from "mongodb";
+import { FullContentPiece } from "#database";
+import { UnderscoreID } from "#lib/mongo";
+
+interface ProcessInputResult {
+  buffer: Buffer;
+  contentHash: string;
+  metadata: Partial<
+    Pick<FullContentPiece, keyof NonNullable<ReturnType<InputTransformer>["contentPiece"]>>
+  >;
+}
+interface OutputContentProcessorInput {
+  buffer: Buffer;
+  contentPiece: UnderscoreID<FullContentPiece<ObjectId>>;
+}
+
+interface InputContentProcessor {
+  process(inputContent: string): Promise<ProcessInputResult>;
+  processBatch(inputContent: string[]): Promise<ProcessInputResult[]>;
+}
+
+interface OutputContentProcessor {
+  process(input: OutputContentProcessorInput): Promise<string>;
+  processBatch(input: OutputContentProcessorInput[]): Promise<string[]>;
+}
+
+export type { InputContentProcessor, OutputContentProcessor, OutputContentProcessorInput };

programming_language: TypeScript
filename: host-config.ts
change_type: ModificationType.ADD
diff: @@ -0,0 +1,16 @@
+import { z } from "zod";
+
+const hostConfig = z.object({
+  githubOAuth: z.boolean(),
+  githubApp: z.boolean(),
+  sendgrid: z.boolean(),
+  smtp: z.boolean(),
+  search: z.boolean(),
+  aiSearch: z.boolean(),
+  extensions: z.boolean()
+});
+
+interface HostConfig extends z.infer<typeof hostConfig> {}
+
+export { hostConfig };
+export type { HostConfig };

programming_language: TypeScript
filename: index.ts
change_type: ModificationType.MODIFY
diff: @@ -1,9 +1,16 @@
-export * from "./utils";
+export * from "./auth";
+export * from "./context";
+export * as errors from "./errors";
+export * from "./git-sync";
+export * from "./hash";
+export * from "./middleware";
 export * from "./mongo";
 export * from "./plugin";
 export * from "./processing";
-export * from "./hash";
+export * from "./pub-sub";
+export * from "./session";
 export * from "./trpc";
-export * from "./middleware";
-export * from "./git-sync-hooks";
-export * as errors from "./errors";
+export * from "./utils";
+export * from "./webhooks";
+export * from "./workspace";
+export * from "./host-config";

programming_language: TypeScript
filename: middleware.ts
change_type: ModificationType.MODIFY
diff: @@ -1,8 +1,9 @@
 import { processAuth } from "./auth";
 import { Context } from "./context";
+import * as errors from "./errors";
+import { HostConfig } from "./host-config";
+import { Meta, middleware } from "./trpc";
 import { ObjectId } from "mongodb";
-import { Meta, middleware } from "#lib/trpc";
-import * as errors from "#lib/errors";
 
 interface AuthMiddlewareContextExtension<W extends true | false = true> {
   auth: {
@@ -69,7 +70,7 @@ const isAuthenticatedUser = middleware(async ({ ctx, next, meta }) => {
 const isEnabled = middleware(async ({ ctx, next, meta }) => {
   const requiredConfig = meta?.requiredConfig || [];
 
-  if (requiredConfig.some((property) => !ctx.fastify.hostConfig[property])) {
+  if (requiredConfig.some((property) => !ctx.fastify.hostConfig[property as keyof HostConfig])) {
     throw errors.serverError();
   }
 

programming_language: TypeScript
filename: mongo.ts
change_type: ModificationType.MODIFY
diff: @@ -1,9 +1,8 @@
 import { z } from "zod";
-import { ObjectId, Db, Collection } from "mongodb";
 
 type UnderscoreID<T extends Record<string, any>> = Omit<T, "id"> & { _id: T["id"] };
 
 const zodId = (): z.ZodString => z.string().regex(/^[a-f\d]{24}$/i, "invalid id");
 
-export { zodId, ObjectId };
-export type { UnderscoreID, Db, Collection };
+export { zodId };
+export type { UnderscoreID };

programming_language: TypeScript
filename: processing.ts
change_type: ModificationType.MODIFY
diff: @@ -30,7 +30,7 @@ import {
   TableCell,
   TableHeader,
   TableRow,
-  Wrapper
+  Element
 } from "@vrite/editor";
 
 type Attrs = Record<string, string | number | boolean>;
@@ -74,7 +74,7 @@ const htmlToJSON = (html: string): DocJSON => {
     OrderedList,
     TaskList,
     Blockquote,
-    Wrapper,
+    Element,
     CodeBlock,
     HorizontalRule,
     Image,
@@ -107,7 +107,7 @@ const jsonToBuffer = (json: DocJSON): Buffer => {
     OrderedList,
     TaskList,
     Blockquote,
-    Wrapper,
+    Element,
     CodeBlock,
     HorizontalRule,
     Image,

programming_language: TypeScript
filename: session.ts
change_type: ModificationType.MODIFY
diff: @@ -1,11 +1,16 @@
 import { Context } from "./context";
 import { UnderscoreID } from "./mongo";
+import * as errors from "./errors";
 import { nanoid } from "nanoid";
 import { ObjectId } from "mongodb";
-import { getUserSettingsCollection } from "#database/user-settings";
-import { getWorkspaceMembershipsCollection } from "#database/workspace-memberships";
-import { BaseRoleType, FullRole, Permission, getRolesCollection } from "#database/roles";
-import * as errors from "#lib/errors";
+import {
+  BaseRoleType,
+  FullRole,
+  Permission,
+  getRolesCollection,
+  getUserSettingsCollection,
+  getWorkspaceMembershipsCollection
+} from "#database";
 
 declare module "node:net" {
   interface Socket {

programming_language: TypeScript
filename: trpc.ts
change_type: ModificationType.MODIFY
diff: @@ -1,9 +1,9 @@
 import { Context } from "./context";
 import { CustomError } from "./errors";
+import { HostConfig } from "./host-config";
 import { initTRPC } from "@trpc/server";
 import { OpenApiMeta } from "trpc-openapi";
 import { TokenPermission, Permission } from "#database";
-import { HostConfig } from "#plugins/host-config";
 
 type Meta = OpenApiMeta & {
   permissions?: { session?: Permission[]; token?: TokenPermission[] };

programming_language: TypeScript
filename: webhooks.ts
change_type: ModificationType.MODIFY
diff: @@ -1,10 +1,16 @@
 import { AuthenticatedContext } from "./middleware";
+import { zodId } from "./mongo";
 import axios from "axios";
 import { z } from "zod";
-import { ObjectId, zodId } from "#lib/mongo";
-import { WebhookEvent, getWebhooksCollection } from "#database/webhooks";
-import { contentGroup, contentPiece, getContentGroupsCollection } from "#database";
-import { workspaceMembership } from "#database/workspace-memberships";
+import { ObjectId } from "mongodb";
+import {
+  WebhookEvent,
+  getWebhooksCollection,
+  contentGroup,
+  contentPiece,
+  getContentGroupsCollection,
+  workspaceMembership
+} from "#database";
 
 const webhookPayload = z.union([
   contentPiece.extend({ slug: z.string(), locked: z.boolean().optional() }),
@@ -56,8 +62,7 @@ const runWebhooks = async (
         })
       });
     } catch (error) {
-      // eslint-disable-next-line no-console
-      console.error("Failed to run webhook", error);
+      ctx.fastify.log.error("Failed to run webhook", error);
     }
   }
 };

programming_language: TypeScript
filename: database.ts
change_type: ModificationType.MODIFY
diff: @@ -1,16 +1,16 @@
-import { publicPlugin } from "#lib/plugin";
-import { getContentPiecesCollection } from "#database/content-pieces";
-import { getRolesCollection } from "#database/roles";
-import { getTagsCollection } from "#database/tags";
-import { getTokensCollection } from "#database/tokens";
-import { getUserSettingsCollection } from "#database/user-settings";
-import { getWebhooksCollection } from "#database/webhooks";
-import { getWorkspaceSettingsCollection } from "#database/workspace-settings";
-import { getContentsCollection } from "#database/contents";
-import { getUsersCollection } from "#database/users";
-import { getCommentThreadsCollection } from "#database/comment-threads";
-import { getCommentsCollection } from "#database/comments";
+import { publicPlugin } from "#lib";
 import {
+  getUserSettingsCollection,
+  getWebhooksCollection,
+  getWorkspaceSettingsCollection,
+  getContentsCollection,
+  getUsersCollection,
+  getCommentThreadsCollection,
+  getCommentsCollection,
+  getContentPiecesCollection,
+  getRolesCollection,
+  getTagsCollection,
+  getTokensCollection,
   getContentGroupsCollection,
   getContentPieceVariantsCollection,
   getContentVariantsCollection,

programming_language: JavaScript
filename: email.ts
change_type: ModificationType.MODIFY
diff: @@ -1,12 +1,10 @@
-import { publicPlugin } from "../lib/plugin";
 import { EmailService, FastifyInstance } from "fastify";
 import { MailService } from "@sendgrid/mail";
 import { ObjectId } from "mongodb";
 import { EmailTemplate, getSubject, renderEmail } from "@vrite/emails";
 import * as nodemailer from "nodemailer";
-import { getWorkspacesCollection } from "#database/workspaces";
-import { getUsersCollection } from "#database/users";
-import * as errors from "#lib/errors";
+import { getWorkspacesCollection, getUsersCollection } from "#database";
+import { errors, publicPlugin } from "#lib";
 
 type EmailSender = (email: {
   to: string;
@@ -77,8 +75,7 @@ const createEmailSender = (fastify: FastifyInstance): EmailSender => {
           text: renderEmail(email.template, email.data, true)
         });
       } catch (error) {
-        // eslint-disable-next-line no-console
-        console.error(error);
+        fastify.log.error(error);
 
         throw errors.serverError();
       }
@@ -109,8 +106,7 @@ const createEmailSender = (fastify: FastifyInstance): EmailSender => {
           text: renderEmail(email.template, email.data, true)
         });
       } catch (error) {
-        // eslint-disable-next-line no-console
-        console.error(error);
+        fastify.log.error(error);
 
         throw errors.serverError();
       }
@@ -119,7 +115,7 @@ const createEmailSender = (fastify: FastifyInstance): EmailSender => {
 
   return async () => {
     // eslint-disable-next-line no-console
-    console.error("No email service configured");
+    fastify.log.error("No email service configured");
 
     throw errors.serverError();
   };

programming_language: TypeScript
filename: git-sync.ts
change_type: ModificationType.MODIFY
diff: @@ -1,6 +1,6 @@
 import { App } from "octokit";
 import { FastifyInstance } from "fastify";
-import { publicPlugin } from "#lib/plugin";
+import { publicPlugin } from "#lib";
 
 declare module "fastify" {
   interface FastifyInstance {

programming_language: TypeScript
filename: host-config.ts
change_type: ModificationType.MODIFY
diff: @@ -1,17 +1,4 @@
-import { publicPlugin } from "../lib/plugin";
-import { z } from "zod";
-
-const hostConfig = z.object({
-  githubOAuth: z.boolean(),
-  githubApp: z.boolean(),
-  sendgrid: z.boolean(),
-  smtp: z.boolean(),
-  search: z.boolean(),
-  aiSearch: z.boolean(),
-  extensions: z.boolean()
-});
-
-interface HostConfig extends z.infer<typeof hostConfig> {}
+import { HostConfig, publicPlugin } from "#lib";
 
 declare module "fastify" {
   interface FastifyInstance {
@@ -44,5 +31,4 @@ const hostConfigPlugin = publicPlugin(async (fastify) => {
   fastify.decorate("hostConfig", hostConfig);
 });
 
-export { hostConfigPlugin, hostConfig };
-export type { HostConfig };
+export { hostConfigPlugin };

programming_language: TypeScript
filename: oauth.ts
change_type: ModificationType.MODIFY
diff: @@ -2,12 +2,8 @@ import axios from "axios";
 import fastifyOAuth2, { FastifyOAuth2Options, OAuth2Namespace } from "@fastify/oauth2";
 import { ObjectId } from "mongodb";
 import { FastifyInstance } from "fastify";
-import { publicPlugin } from "#lib/plugin";
-import { generateSalt } from "#lib/hash";
-import { createSession } from "#lib/session";
-import { createWorkspace } from "#lib/workspace";
-import { getUsersCollection } from "#database/users";
-import { getUserSettingsCollection } from "#database";
+import { publicPlugin, generateSalt, createSession, createWorkspace } from "#lib";
+import { getUserSettingsCollection, getUsersCollection } from "#database";
 
 declare module "fastify" {
   interface FastifyInstance {
@@ -82,7 +78,7 @@ const registerGitHubOAuth = (fastify: FastifyInstance): void => {
         await userSettingsCollection.insertOne({
           _id: new ObjectId(),
           userId: newUser._id,
-          codeEditorTheme: "dark",
+          codeEditorTheme: "auto",
           uiTheme: "auto",
           accentColor: "energy",
           currentWorkspaceId: workspaceId
@@ -92,8 +88,7 @@ const registerGitHubOAuth = (fastify: FastifyInstance): void => {
 
       return res.redirect("/");
     } catch (error) {
-      // eslint-disable-next-line no-console
-      console.error(error);
+      fastify.log.error(error);
 
       return res.redirect("/auth");
     }

programming_language: TypeScript
filename: pub-sub.ts
change_type: ModificationType.MODIFY
diff: @@ -1,5 +1,5 @@
-import { publicPlugin } from "../lib/plugin";
 import type { PubSubMessage, PubSubPlugin } from "fastify";
+import { publicPlugin } from "#lib";
 
 declare module "fastify" {
   interface PubSubMessage {

programming_language: TypeScript
filename: s3.ts
change_type: ModificationType.MODIFY
diff: @@ -1,10 +1,5 @@
-import { publicPlugin } from "../lib/plugin";
-import {
-  S3Client,
-  CreateBucketCommand,
-  PutBucketCorsCommand,
-  HeadBucketCommand
-} from "@aws-sdk/client-s3";
+import { S3Client, CreateBucketCommand, HeadBucketCommand } from "@aws-sdk/client-s3";
+import { publicPlugin } from "#lib";
 
 declare module "fastify" {
   interface FastifyInstance {

programming_language: TypeScript
filename: search.ts
change_type: ModificationType.MODIFY
diff: @@ -10,7 +10,8 @@ import { FastifyInstance, SearchService } from "fastify";
 import { OpenAI } from "openai";
 import { Stream } from "openai/streaming";
 import { ChatCompletionChunk } from "openai/resources/chat";
-import { Db, ObjectId, UnderscoreID, bufferToJSON, publicPlugin } from "#lib";
+import { Db, ObjectId } from "mongodb";
+import { UnderscoreID, bufferToJSON, publicPlugin } from "#lib";
 import { FullContentPiece, getContentVariantsCollection, getContentsCollection } from "#database";
 
 interface RawSearchResult {

programming_language: TypeScript
filename: session.ts
change_type: ModificationType.MODIFY
diff: @@ -1,7 +1,6 @@
-import { appRouter } from "../routes";
 import { getHTTPStatusCodeFromError } from "@trpc/server/http";
-import { publicPlugin } from "#lib/plugin";
-import { CustomError } from "#lib/errors";
+import { appRouter } from "#routes";
+import { publicPlugin, errors } from "#lib";
 
 const sessionPlugin = publicPlugin(async (fastify) => {
   fastify.post("/session/refresh", async (req, res) => {
@@ -10,7 +9,7 @@ const sessionPlugin = publicPlugin(async (fastify) => {
     try {
       await caller.auth.refreshToken();
     } catch (e) {
-      const error = e as CustomError;
+      const error = e as errors.CustomError;
       const httpStatusCode = getHTTPStatusCodeFromError(error);
 
       res
@@ -26,7 +25,7 @@ const sessionPlugin = publicPlugin(async (fastify) => {
     try {
       await caller.auth.logout();
     } catch (e) {
-      const error = e as CustomError;
+      const error = e as errors.CustomError;
       const httpStatusCode = getHTTPStatusCodeFromError(error);
 
       res

programming_language: TypeScript
filename: trpc.ts
change_type: ModificationType.MODIFY
diff: @@ -1,8 +1,7 @@
-import { publicPlugin } from "../lib/plugin";
-import { createContext } from "../lib/context";
-import { appRouter } from "../routes";
 import { fastifyTRPCPlugin } from "@trpc/server/adapters/fastify";
 import { FastifyReply, FastifyRequest } from "fastify";
+import { appRouter } from "#routes";
+import { publicPlugin, createContext } from "#lib";
 
 const trpcPlugin = publicPlugin(async (fastify) => {
   await fastify.register(fastifyTRPCPlugin, {

programming_language: TypeScript
filename: auth.ts
change_type: ModificationType.MODIFY
diff: @@ -2,21 +2,24 @@ import { ObjectId } from "mongodb";
 import { nanoid } from "nanoid";
 import { z } from "zod";
 import * as OTPAuth from "otpauth";
-import { FullUser, getUsersCollection } from "#database/users";
-import { UnderscoreID } from "#lib/mongo";
-import { generateSalt, hashValue, verifyValue } from "#lib/hash";
-import { procedure, router } from "#lib/trpc";
+import { FullUser, getUsersCollection, getUserSettingsCollection } from "#database";
 import {
+  UnderscoreID,
+  generateSalt,
+  processAuth,
+  errors,
+  isAuthenticated,
+  isAuthenticatedUser,
+  hashValue,
+  verifyValue,
   createSession,
   deleteSession,
   getSessionId,
   refreshSession,
-  updateSession
-} from "#lib/session";
-import { processAuth } from "#lib/auth";
-import * as errors from "#lib/errors";
-import { isAuthenticated, isAuthenticatedUser } from "#lib/middleware";
-import { getUserSettingsCollection } from "#database";
+  updateSession,
+  procedure,
+  router
+} from "#lib";
 
 const totpConfig = {
   issuer: "Vrite",
@@ -52,9 +55,13 @@ const authRouter = router({
   register: procedure
     .input(
       z.object({
-        email: z.string().email(),
+        email: z.string().email().max(320),
         username: z.string().regex(/^[a-z0-9_]*$/),
-        password: z.string().regex(/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d).{8,}$/),
+        password: z
+          .string()
+          .regex(/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d).{8,}$/)
+          .min(8)
+          .max(128),
         redirect: z.string().optional()
       })
     )
@@ -94,7 +101,7 @@ const authRouter = router({
   sendMagicLink: procedure
     .input(
       z.object({
-        email: z.string().email(),
+        email: z.string().email().max(320),
         totpToken: z.string().optional(),
         redirect: z.string().optional()
       })
@@ -110,6 +117,12 @@ const authRouter = router({
         throw errors.unauthorized("emailNotVerified");
       }
 
+      const magicLinkSent = await ctx.fastify.redis.get(`user:${user._id}:magicLinkSent`);
+
+      if (magicLinkSent === "true") {
+        throw errors.unauthorized("magicLinkAlreadySent");
+      }
+
       if (user.totpSecret) {
         verifyTotp(user, input.totpToken);
       }
@@ -128,6 +141,7 @@ const authRouter = router({
         "EX",
         60 * 30
       );
+      await ctx.fastify.redis.set(`user:${user._id}:magicLinkSent`, "true", "EX", 60);
       await ctx.fastify.email.sendMagicLink(user.email, {
         code: magicLinkCode,
         userId: `${user._id}`
@@ -136,8 +150,8 @@ const authRouter = router({
   login: procedure
     .input(
       z.object({
-        email: z.string().email(),
-        password: z.string(),
+        email: z.string().email().max(320),
+        password: z.string().min(8).max(128),
         totpToken: z.string().optional()
       })
     )

programming_language: TypeScript
filename: comments.ts
change_type: ModificationType.MODIFY
diff: @@ -1,10 +1,6 @@
 import { Db, ObjectId } from "mongodb";
 import { z } from "zod";
-import { UnderscoreID, zodId } from "#lib/mongo";
-import { isAuthenticated } from "#lib/middleware";
-import { procedure, router } from "#lib/trpc";
-import * as errors from "#lib/errors";
-import { createEventPublisher, createEventSubscription } from "#lib/pub-sub";
+import { UnderscoreID, zodId, isAuthenticated, procedure, router, errors } from "#lib";
 import {
   CommentThread,
   commentThread,
@@ -15,26 +11,9 @@ import {
   commentMember,
   CommentWithAdditionalData,
   getWorkspaceMembershipsCollection,
-  getUsersCollection,
-  CommentMember
+  getUsersCollection
 } from "#database";
-
-type CommentEvent =
-  | { action: "createThread"; data: CommentThread }
-  | { action: "resolveThread"; data: Pick<CommentThread, "id" | "fragment" | "resolved"> }
-  | { action: "deleteThread"; data: Pick<CommentThread, "id" | "fragment"> }
-  | {
-      action: "createComment";
-      data: Omit<Comment, "memberId"> & { member: CommentMember | null };
-    }
-  | {
-      action: "updateComment";
-      data: Pick<Comment, "id" | "content">;
-    }
-  | {
-      action: "deleteComment";
-      data: Pick<Comment, "id">;
-    };
+import { publishCommentEvent, subscribeToCommentEvents } from "#events";
 
 const fetchCommentsMembers = async (
   db: Db,
@@ -99,9 +78,6 @@ const fetchThreadsFirstComments = async (
   return fetchCommentsMembers(db, comments);
 };
 const authenticatedProcedure = procedure.use(isAuthenticated);
-const publishEvent = createEventPublisher<CommentEvent>((contentPieceId) => {
-  return `comments:${contentPieceId}`;
-});
 const commentsRouter = router({
   getThread: authenticatedProcedure
     .input(z.object({ fragment: z.string() }))
@@ -216,7 +192,7 @@ const commentsRouter = router({
       };
 
       await commentThreadsCollection.insertOne(thread);
-      publishEvent(ctx, `${input.contentPieceId}`, {
+      publishCommentEvent(ctx, `${input.contentPieceId}`, {
         action: "createThread",
         data: {
           ...thread,
@@ -249,7 +225,7 @@ const commentsRouter = router({
           $set: { resolved: true }
         }
       );
-      publishEvent(ctx, `${existingThread.contentPieceId}`, {
+      publishCommentEvent(ctx, `${existingThread.contentPieceId}`, {
         action: "resolveThread",
         data: {
           id: `${existingThread._id}`,
@@ -289,7 +265,7 @@ const commentsRouter = router({
           $push: { comments: comment._id }
         }
       );
-      publishEvent(ctx, `${existingThread.contentPieceId}`, {
+      publishCommentEvent(ctx, `${existingThread.contentPieceId}`, {
         action: "createComment",
         data: (await fetchCommentsMembers(ctx.db, [comment]))[0]
       });
@@ -320,7 +296,7 @@ const commentsRouter = router({
         { _id: existingComment._id },
         { $set: { content: input.content } }
       );
-      publishEvent(ctx, `${existingThread.contentPieceId}`, {
+      publishCommentEvent(ctx, `${existingThread.contentPieceId}`, {
         action: "updateComment",
         data: {
           content: input.content,
@@ -353,7 +329,7 @@ const commentsRouter = router({
         { _id: existingThread._id },
         { $pull: { comments: existingComment._id } }
       );
-      publishEvent(ctx, `${existingThread.contentPieceId}`, {
+      publishCommentEvent(ctx, `${existingThread.contentPieceId}`, {
         action: "deleteComment",
         data: {
           id: `${existingComment._id}`
@@ -375,7 +351,7 @@ const commentsRouter = router({
 
       await commentThreadsCollection.deleteOne({ _id: existingThread._id });
       await commentsCollection.deleteMany({ threadId: existingThread._id });
-      publishEvent(ctx, `${existingThread.contentPieceId}`, {
+      publishCommentEvent(ctx, `${existingThread.contentPieceId}`, {
         action: "deleteThread",
         data: {
           id: `${existingThread._id}`,
@@ -386,7 +362,7 @@ const commentsRouter = router({
   changes: authenticatedProcedure
     .input(z.object({ contentPieceId: zodId() }))
     .subscription(({ ctx, input }) => {
-      return createEventSubscription<CommentEvent>(ctx, `comments:${input.contentPieceId}`);
+      return subscribeToCommentEvents(ctx, input.contentPieceId);
     })
 });
 

programming_language: TypeScript
filename: content-groups.ts
change_type: ModificationType.MODIFY
diff: @@ -1,11 +1,5 @@
 import { ObjectId } from "mongodb";
 import { z } from "zod";
-import { procedure, router } from "#lib/trpc";
-import { isAuthenticated } from "#lib/middleware";
-import { UnderscoreID, zodId } from "#lib/mongo";
-import * as errors from "#lib/errors";
-import { createEventPublisher, createEventSubscription } from "#lib/pub-sub";
-import { runWebhooks } from "#lib/webhooks";
 import {
   ContentGroup,
   contentGroup,
@@ -17,24 +11,18 @@ import {
   getWorkspacesCollection,
   FullContentGroup
 } from "#database";
-import { runGitSyncHook } from "#lib";
-
-type ContentGroupEvent =
-  | {
-      action: "create";
-      data: ContentGroup;
-    }
-  | {
-      action: "update";
-      data: Partial<ContentGroup> & { id: string };
-    }
-  | { action: "delete"; data: { id: string } }
-  | { action: "move"; data: ContentGroup }
-  | { action: "reorder"; data: { id: string; index: number } };
-
-const publishEvent = createEventPublisher<ContentGroupEvent>(
-  (workspaceId) => `contentGroups:${workspaceId}`
-);
+import {
+  runGitSyncHook,
+  runWebhooks,
+  errors,
+  UnderscoreID,
+  zodId,
+  isAuthenticated,
+  procedure,
+  router
+} from "#lib";
+import { subscribeToContentGroupEvents, publishContentGroupEvent } from "#events";
+
 const basePath = "/content-groups";
 const authenticatedProcedure = procedure.use(isAuthenticated);
 const rearrangeContentGroups = (
@@ -179,7 +167,10 @@ const contentGroupsRouter = router({
         ancestor: "ancestor" in input ? input.ancestor : undefined,
         name: "name" in input ? input.name : undefined
       });
-      publishEvent(ctx, `${ctx.auth.workspaceId}`, { action: "update", data: { id, ...update } });
+      publishContentGroupEvent(ctx, `${ctx.auth.workspaceId}`, {
+        action: "update",
+        data: { id, ...update }
+      });
     }),
   create: authenticatedProcedure
     .meta({
@@ -231,7 +222,7 @@ const contentGroupsRouter = router({
       }
 
       await contentGroupsCollection.insertOne(contentGroup);
-      publishEvent(ctx, `${ctx.auth.workspaceId}`, {
+      publishContentGroupEvent(ctx, `${ctx.auth.workspaceId}`, {
         action: "create",
         data: {
           id: `${contentGroup._id}`,
@@ -328,7 +319,7 @@ const contentGroupsRouter = router({
         descendants: contentGroup.descendants.map((id) => `${id}`),
         id: `${contentGroup._id}`
       });
-      publishEvent(ctx, `${ctx.auth.workspaceId}`, {
+      publishContentGroupEvent(ctx, `${ctx.auth.workspaceId}`, {
         action: "delete",
         data: input
       });
@@ -504,7 +495,7 @@ const contentGroupsRouter = router({
         ancestor: input.ancestor,
         contentGroup
       });
-      publishEvent(ctx, `${ctx.auth.workspaceId}`, {
+      publishContentGroupEvent(ctx, `${ctx.auth.workspaceId}`, {
         action: "move",
         data: {
           id: input.id,
@@ -583,14 +574,14 @@ const contentGroupsRouter = router({
         );
       }
 
-      publishEvent(ctx, `${ctx.auth.workspaceId}`, {
+      publishContentGroupEvent(ctx, `${ctx.auth.workspaceId}`, {
         action: "reorder",
         data: input
       });
     }),
   changes: authenticatedProcedure.subscription(async ({ ctx }) => {
-    return createEventSubscription<ContentGroupEvent>(ctx, `contentGroups:${ctx.auth.workspaceId}`);
+    return subscribeToContentGroupEvents(ctx, `${ctx.auth.workspaceId}`);
   })
 });
 
-export { contentGroupsRouter, publishEvent as publishContentGroupEvent };
+export { contentGroupsRouter };

programming_language: TypeScript
filename: content-pieces.ts
change_type: ModificationType.MODIFY
diff: @@ -3,25 +3,33 @@ import { z } from "zod";
 import { LexoRank } from "lexorank";
 import { convert as convertToSlug } from "url-slug";
 import { convert as convertToText } from "html-to-text";
-import { stringToRegex } from "#lib/utils";
-import { UnderscoreID, zodId } from "#lib/mongo";
-import { bufferToJSON, DocJSON, htmlToJSON, jsonToBuffer } from "#lib/processing";
-import { isAuthenticated } from "#lib/middleware";
-import { procedure, router } from "#lib/trpc";
 import {
   contentPiece,
   ContentPiece,
   ContentPieceMember,
   contentPieceMember,
   FullContentPiece,
-  FullContentPieceWithAdditionalData,
-  getContentPiecesCollection
-} from "#database/content-pieces";
-import { Tag, getTagsCollection, tag } from "#database/tags";
-import * as errors from "#lib/errors";
-import { getContentsCollection } from "#database/contents";
-import { runWebhooks } from "#lib/webhooks";
-import { createEventPublisher, createEventSubscription } from "#lib/pub-sub";
+  getContentPiecesCollection,
+  Tag,
+  getTagsCollection,
+  tag,
+  getContentsCollection
+} from "#database";
+import {
+  runWebhooks,
+  errors,
+  runGitSyncHook,
+  procedure,
+  router,
+  isAuthenticated,
+  bufferToJSON,
+  DocJSON,
+  htmlToJSON,
+  jsonToBuffer,
+  UnderscoreID,
+  zodId,
+  stringToRegex
+} from "#lib";
 import {
   FullContentPieceVariant,
   getContentGroupsCollection,
@@ -32,30 +40,8 @@ import {
   getWorkspaceMembershipsCollection,
   getWorkspaceSettingsCollection
 } from "#database";
-import { runGitSyncHook } from "#lib";
-
-type ContentPieceEvent =
-  | { action: "delete"; userId: string; data: { id: string } }
-  | { action: "create"; userId: string; data: FullContentPieceWithAdditionalData }
-  | {
-      action: "update";
-      userId: string;
-      variantId?: string;
-      data: Partial<FullContentPieceWithAdditionalData> & { id: string };
-    }
-  | {
-      action: "move";
-      userId: string;
-      data: {
-        contentPiece: FullContentPieceWithAdditionalData;
-        nextReferenceId?: string;
-        previousReferenceId?: string;
-      };
-    };
+import { publishContentPieceEvent, subscribeToContentPieceEvents } from "#events";
 
-const publishEvent = createEventPublisher<ContentPieceEvent>((contentGroupId) => {
-  return `contentPieces:${contentGroupId}`;
-});
 const webhookPayload = (
   contentPiece: UnderscoreID<FullContentPiece<ObjectId>>
 ): ContentPiece & { id: string; locked?: boolean } => {
@@ -151,21 +137,21 @@ const mergeVariantData = (
 };
 const getVariantDetails = async (
   db: Db,
-  variantIdOrName?: string
-): Promise<{ variantId: ObjectId | null; variantName: string | null }> => {
+  variantIdOrKey?: string
+): Promise<{ variantId: ObjectId | null; variantKey: string | null }> => {
   const variantsCollection = getVariantsCollection(db);
 
-  if (!variantIdOrName) return { variantId: null, variantName: null };
+  if (!variantIdOrKey) return { variantId: null, variantKey: null };
 
-  const isId = ObjectId.isValid(variantIdOrName);
+  const isId = ObjectId.isValid(variantIdOrKey);
   const variant = await variantsCollection.findOne({
-    ...(isId && { _id: new ObjectId(variantIdOrName) }),
-    ...(!isId && { name: variantIdOrName })
+    ...(isId && { _id: new ObjectId(variantIdOrKey) }),
+    ...(!isId && { key: variantIdOrKey })
   });
 
   if (!variant) throw errors.notFound("variant");
 
-  return { variantId: variant._id || null, variantName: variant.name || null };
+  return { variantId: variant._id || null, variantKey: variant.key || null };
 };
 const getCanonicalLinkFromPattern = (
   pattern: string,
@@ -229,7 +215,7 @@ const contentPiecesRouter = router({
       const workspaceSettings = await workspaceSettingsCollection.findOne({
         workspaceId: ctx.auth.workspaceId
       });
-      const { variantId, variantName } = await getVariantDetails(ctx.db, input.variant);
+      const { variantId, variantKey } = await getVariantDetails(ctx.db, input.variant);
       const baseContentPiece = await contentPiecesCollection.findOne({
         _id: new ObjectId(input.id)
       });
@@ -296,7 +282,7 @@ const contentPiecesRouter = router({
           typeof contentPiece.canonicalLink !== "string" && {
             canonicalLink: getCanonicalLinkFromPattern(
               workspaceSettings.metadata.canonicalLinkPattern,
-              { slug: contentPiece.slug, variant: variantName }
+              { slug: contentPiece.slug, variant: variantKey }
             )
           }),
         id: `${contentPiece._id}`,
@@ -353,7 +339,7 @@ const contentPiecesRouter = router({
         workspaceId: ctx.auth.workspaceId
       });
       const contentGroupId = new ObjectId(input.contentGroupId);
-      const { variantId, variantName } = await getVariantDetails(ctx.db, input.variant);
+      const { variantId, variantKey } = await getVariantDetails(ctx.db, input.variant);
       const cursor = contentPiecesCollection
         .find({
           workspaceId: ctx.auth.workspaceId,
@@ -405,7 +391,7 @@ const contentPiecesRouter = router({
               typeof contentPiece.canonicalLink !== "string" && {
                 canonicalLink: getCanonicalLinkFromPattern(
                   workspaceSettings.metadata.canonicalLinkPattern,
-                  { slug: contentPiece.slug, variant: variantName }
+                  { slug: contentPiece.slug, variant: variantKey }
                 )
               }),
             id: `${contentPiece._id}`,
@@ -500,7 +486,7 @@ const contentPiecesRouter = router({
       const tags = await fetchContentPieceTags(ctx.db, contentPiece);
       const members = await fetchContentPieceMembers(ctx.db, contentPiece);
 
-      publishEvent(ctx, `${contentPiece.contentGroupId}`, {
+      publishContentPieceEvent(ctx, `${contentPiece.contentGroupId}`, {
         action: "create",
         userId: `${ctx.auth.userId}`,
         data: {
@@ -573,7 +559,7 @@ const contentPiecesRouter = router({
       const workspaceSettings = await workspaceSettingsCollection.findOne({
         workspaceId: ctx.auth.workspaceId
       });
-      const { variantId, variantName } = await getVariantDetails(ctx.db, variant);
+      const { variantId, variantKey } = await getVariantDetails(ctx.db, variant);
       const baseContentPiece = await contentPiecesCollection.findOne({
         _id: new ObjectId(id)
       });
@@ -609,7 +595,14 @@ const contentPiecesRouter = router({
       };
 
       if (typeof update.slug !== "undefined") {
-        contentPieceUpdates.slug = convertToSlug(update.slug || update.title || contentPiece.title);
+        if (update.slug) {
+          contentPieceUpdates.slug = update.slug
+            .split("/")
+            .map((slugPart) => convertToSlug(slugPart))
+            .join("/");
+        } else {
+          contentPieceUpdates.slug = convertToSlug(update.title || contentPiece.title);
+        }
       } else if (convertToSlug(contentPiece.title) === contentPiece.slug) {
         contentPieceUpdates.slug = convertToSlug(update.title || contentPiece.title);
       }
@@ -701,7 +694,7 @@ const contentPiecesRouter = router({
       const tags = await fetchContentPieceTags(ctx.db, newContentPiece);
       const members = await fetchContentPieceMembers(ctx.db, newContentPiece);
 
-      publishEvent(ctx, `${newContentPiece.contentGroupId}`, {
+      publishContentPieceEvent(ctx, `${newContentPiece.contentGroupId}`, {
         action: "update",
         userId: `${ctx.auth.userId}`,
         data: {
@@ -710,7 +703,7 @@ const contentPiecesRouter = router({
             typeof newContentPiece.canonicalLink !== "string" && {
               canonicalLink: getCanonicalLinkFromPattern(
                 workspaceSettings.metadata.canonicalLinkPattern,
-                { slug: newContentPiece.slug, variant: variantName }
+                { slug: newContentPiece.slug, variant: variantKey }
               )
             }),
           id: `${newContentPiece._id}`,
@@ -758,7 +751,7 @@ const contentPiecesRouter = router({
       });
       runGitSyncHook(ctx, "contentPieceRemoved", { contentPiece });
       runWebhooks(ctx, "contentPieceRemoved", webhookPayload(contentPiece));
-      publishEvent(ctx, `${contentPiece.contentGroupId}`, {
+      publishContentPieceEvent(ctx, `${contentPiece.contentGroupId}`, {
         action: "delete",
         userId: `${ctx.auth.userId}`,
         data: { id: input.id }
@@ -862,7 +855,7 @@ const contentPiecesRouter = router({
         contentPiece,
         contentGroupId: input.contentGroupId
       });
-      publishEvent(
+      publishContentPieceEvent(
         ctx,
         [
           `${contentPiece.contentGroupId}`,
@@ -915,12 +908,8 @@ const contentPiecesRouter = router({
   changes: authenticatedProcedure
     .input(z.object({ contentGroupId: zodId() }))
     .subscription(async ({ ctx, input }) => {
-      return createEventSubscription<ContentPieceEvent>(
-        ctx,
-        `contentPieces:${input.contentGroupId}`
-      );
+      return subscribeToContentPieceEvents(ctx, input.contentGroupId);
     })
 });
 
 export { contentPiecesRouter, fetchContentPieceTags };
-export type { ContentPieceEvent };

programming_language: TypeScript
filename: extensions.ts
change_type: ModificationType.MODIFY
diff: @@ -1,38 +1,18 @@
 import { createToken } from "./tokens";
 import { z } from "zod";
 import { ObjectId } from "mongodb";
-import { isAuthenticated, isEnabled } from "#lib/middleware";
-import { procedure, router } from "#lib/trpc";
 import {
-  Extension,
   extension,
   contextObject,
   getExtensionsCollection,
-  ContextObject,
   tokenPermission,
   getTokensCollection,
-  getContentPiecesCollection,
-  FullContentPieceWithAdditionalData
+  getContentPiecesCollection
 } from "#database";
-import { createEventPublisher, createEventSubscription } from "#lib/pub-sub";
-import * as errors from "#lib/errors";
-import { zodId } from "#lib";
+import { zodId, errors, procedure, router, isAuthenticated, isEnabled } from "#lib";
+import { publishExtensionEvent, subscribeToExtensionEvents } from "#events/extension";
+import { publishContentPieceEvent } from "#events";
 
-type ExtensionEvent =
-  | { action: "delete"; data: { id: string } }
-  | { action: "create"; data: Extension & { id: string } }
-  | { action: "update"; data: { id: string; config: ContextObject } };
-
-const publishEvent = createEventPublisher<ExtensionEvent>((workspaceId) => {
-  return `extensions:${workspaceId}`;
-});
-const publishContentPieceEvent = createEventPublisher<{
-  action: "update";
-  userId: string;
-  data: Partial<FullContentPieceWithAdditionalData> & { id: string };
-}>((contentGroupId) => {
-  return `contentPieces:${contentGroupId}`;
-});
 const authenticatedProcedure = procedure.use(isAuthenticated).use(isEnabled);
 const basePath = "/extension";
 const extensionsRouter = router({
@@ -169,7 +149,7 @@ const extensionsRouter = router({
       }));
     }),
   changes: authenticatedProcedure.input(z.void()).subscription(({ ctx }) => {
-    return createEventSubscription<ExtensionEvent>(ctx, `extensions:${ctx.auth.workspaceId}`);
+    return subscribeToExtensionEvents(ctx, `${ctx.auth.workspaceId}`);
   }),
   install: authenticatedProcedure
     .meta({
@@ -220,7 +200,7 @@ const extensionsRouter = router({
         workspaceId: ctx.auth.workspaceId,
         token: value
       });
-      publishEvent(ctx, `${ctx.auth.workspaceId}`, {
+      publishExtensionEvent(ctx, `${ctx.auth.workspaceId}`, {
         action: "create",
         data: {
           config: {},
@@ -259,7 +239,7 @@ const extensionsRouter = router({
         throw errors.notFound("extension");
       }
 
-      publishEvent(ctx, `${ctx.auth.workspaceId}`, {
+      publishExtensionEvent(ctx, `${ctx.auth.workspaceId}`, {
         action: "update",
         data: {
           id: input.id,
@@ -288,7 +268,7 @@ const extensionsRouter = router({
       await tokensCollection.deleteOne({
         extensionId: new ObjectId(input.id)
       });
-      publishEvent(ctx, `${ctx.auth.workspaceId}`, {
+      publishExtensionEvent(ctx, `${ctx.auth.workspaceId}`, {
         action: "delete",
         data: { id: input.id }
       });

programming_language: TypeScript
filename: events.ts
change_type: ModificationType.DELETE
diff: @@ -1,23 +0,0 @@
-import { GitData } from "#database";
-import { createEventPublisher } from "#lib/pub-sub";
-
-type GitDataEvent =
-  | {
-      action: "configure";
-      data: GitData;
-    }
-  | {
-      action: "update";
-      data: Partial<GitData>;
-    }
-  | {
-      action: "reset";
-      data: {};
-    };
-
-const publishGitDataEvent = createEventPublisher<GitDataEvent>((workspaceId) => {
-  return `gitData:${workspaceId}`;
-});
-
-export { publishGitDataEvent };
-export type { GitDataEvent };

programming_language: unknown
filename: index.ts
change_type: ModificationType.MODIFY
diff: @@ -1,11 +1,3 @@
-import {
-  createSyncedPieces,
-  createInputContentProcessor,
-  createOutputContentProcessor,
-  OutputContentProcessorInput,
-  OutputContentProcessor,
-  InputContentProcessor
-} from "./process-content";
 import {
   commitChanges,
   getCommitsSince,
@@ -14,15 +6,23 @@ import {
   getDirectory
 } from "./requests";
 import { processPulledRecords } from "./pull";
-import { publishGitDataEvent } from "../events";
+import { createSyncedPieces } from "./synced-pieces";
 import { z } from "zod";
 import { LexoRank } from "lexorank";
-import { Binary } from "mongodb";
+import { Binary, ObjectId } from "mongodb";
 import { minimatch } from "minimatch";
 import crypto from "node:crypto";
-import { AuthenticatedContext, isAuthenticated, isEnabled } from "#lib/middleware";
-import { procedure, router } from "#lib/trpc";
-import * as errors from "#lib/errors";
+import {
+  createInputContentProcessorGitHub,
+  createOutputContentProcessorGitHub,
+  OutputContentProcessorInput,
+  AuthenticatedContext,
+  isAuthenticated,
+  isEnabled,
+  procedure,
+  router,
+  errors
+} from "#lib";
 import {
   FullContentGroup,
   FullContentPiece,
@@ -39,9 +39,12 @@ import {
   getWorkspacesCollection,
   githubData
 } from "#database";
-import { ObjectId, UnderscoreID, zodId } from "#lib";
-import { publishContentGroupEvent } from "#routes/content-groups";
-import { publishWorkspaceSettingsEvent } from "#routes/workspace-settings";
+import { UnderscoreID, zodId } from "#lib";
+import {
+  publishContentGroupEvent,
+  publishGitDataEvent,
+  publishWorkspaceSettingsEvent
+} from "#events";
 
 const authenticatedProcedure = procedure.use(isAuthenticated).use(isEnabled);
 const enableFilenameMetadata = async (ctx: AuthenticatedContext): Promise<void> => {
@@ -138,7 +141,7 @@ const githubRouter = router({
       );
       const { baseDirectory } = gitData.github;
       const basePath = baseDirectory.startsWith("/") ? baseDirectory.slice(1) : baseDirectory;
-      const inputContentProcessor = await createInputContentProcessor(ctx, gitData);
+      const inputContentProcessor = await createInputContentProcessorGitHub(ctx, gitData);
       const syncDirectory = async (
         path: string,
         ancestors: ObjectId[]
@@ -415,7 +418,7 @@ const githubRouter = router({
       );
 
       if (conflicts.length && !input.force) {
-        const outputContentProcessor = await createOutputContentProcessor(ctx, gitData);
+        const outputContentProcessor = await createOutputContentProcessorGitHub(ctx, gitData);
         const contentPieceIds = conflicts.map((conflict) => conflict.contentPieceId);
         const contentPieces = await contentPiecesCollection
           .find({ _id: { $in: contentPieceIds } })
@@ -497,7 +500,7 @@ const githubRouter = router({
 
       if (!gitData?.github) throw errors.notFound("githubData");
 
-      const outputContentProcessor = await createOutputContentProcessor(ctx, gitData);
+      const outputContentProcessor = await createOutputContentProcessorGitHub(ctx, gitData);
       const changedRecords = gitData.records.filter((record) => {
         return record.currentHash !== record.syncedHash;
       });
@@ -620,7 +623,7 @@ const githubRouter = router({
 
       if (!gitData?.github) throw errors.notFound("githubData");
 
-      const outputContentProcessor = await createOutputContentProcessor(ctx, gitData);
+      const outputContentProcessor = await createOutputContentProcessorGitHub(ctx, gitData);
       const contentPiece = await contentPiecesCollection.findOne({
         _id: new ObjectId(input.contentPieceId)
       });
@@ -663,7 +666,7 @@ const githubRouter = router({
 
       if (!gitData?.github) throw errors.notFound("githubData");
 
-      const inputContentProcessor = await createInputContentProcessor(ctx, gitData);
+      const inputContentProcessor = await createInputContentProcessorGitHub(ctx, gitData);
       const { buffer, metadata, contentHash } = await inputContentProcessor.process(input.content);
       const { date, members, tags, ...restMetadata } = metadata;
 
@@ -722,5 +725,4 @@ const githubRouter = router({
     })
 });
 
-export { githubRouter, createInputContentProcessor, createOutputContentProcessor };
-export type { OutputContentProcessor, InputContentProcessor };
+export { githubRouter };

programming_language: TypeScript
filename: pull.ts
change_type: ModificationType.MODIFY
diff: @@ -1,6 +1,7 @@
-import { createSyncedPieces, createInputContentProcessor } from "./process-content";
+import { createSyncedPieces } from "./synced-pieces";
 import { LexoRank } from "lexorank";
 import { ObjectId, Binary } from "mongodb";
+import { createInputContentProcessorGitHub } from "#lib";
 import {
   FullGitData,
   getContentGroupsCollection,
@@ -63,7 +64,7 @@ const processPulledRecords = async (
     pulledContent: string;
     pulledHash: string;
   }> = [];
-  const inputContentProcessor = await createInputContentProcessor(ctx, gitData);
+  const inputContentProcessor = await createInputContentProcessorGitHub(ctx, gitData);
   const createDirectory = async (
     path: string
   ): Promise<UnderscoreID<FullContentGroup<ObjectId>>> => {

programming_language: TypeScript
filename: synced-pieces.ts
change_type: ModificationType.ADD
diff: @@ -0,0 +1,59 @@
+import { ObjectId, Binary } from "mongodb";
+import { convert as convertToSlug } from "url-slug";
+import { FullContentPiece, FullContents } from "#database";
+import { InputContentProcessor, UnderscoreID } from "#lib";
+
+const createSyncedPieces = async (
+  inputs: Array<{
+    path: string;
+    content: string;
+    workspaceId: ObjectId;
+    contentGroupId: ObjectId;
+    order: string;
+  }>,
+  inputContentProcessor: InputContentProcessor
+): Promise<
+  Array<{
+    contentPiece: UnderscoreID<FullContentPiece<ObjectId>>;
+    content: UnderscoreID<FullContents<ObjectId>>;
+    contentHash: string;
+  }>
+> => {
+  const inputContentProcessorOutput = await inputContentProcessor.processBatch(
+    inputs.map((input) => input.content)
+  );
+
+  return inputs.map((input, index) => {
+    const filename = input.path.split("/").pop() || "";
+    const { buffer, contentHash, metadata } = inputContentProcessorOutput[index];
+    const { members, tags, date, ...inputMetadata } = metadata;
+    const contentPiece: UnderscoreID<FullContentPiece<ObjectId>> = {
+      _id: new ObjectId(),
+      workspaceId: input.workspaceId,
+      contentGroupId: input.contentGroupId,
+      order: input.order,
+      members: [],
+      slug: convertToSlug(filename),
+      tags: [],
+      title: filename,
+      filename,
+      ...inputMetadata,
+      ...(date && { date: new Date(date) }),
+      ...(members && { members: members.map((memberId) => new ObjectId(memberId)) }),
+      ...(tags && { tags: tags.map((tagId) => new ObjectId(tagId)) })
+    };
+    const content = {
+      _id: new ObjectId(),
+      contentPieceId: contentPiece._id,
+      content: new Binary(buffer)
+    };
+
+    return {
+      contentPiece,
+      contentHash,
+      content
+    };
+  });
+};
+
+export { createSyncedPieces };

programming_language: TypeScript
filename: index.ts
change_type: ModificationType.MODIFY
diff: @@ -1,15 +1,9 @@
 import { githubRouter } from "./github";
-import { GitDataEvent, publishGitDataEvent } from "./events";
 import { processRecords } from "./process-records";
-import {
-  createGenericInputContentProcessor,
-  createGenericOutputContentProcessor
-} from "./process-content";
 import { z } from "zod";
-import { procedure, router } from "#lib/trpc";
+import { publishGitDataEvent, subscribeToGitDataEvents } from "#events";
+import { procedure, router, errors, isAuthenticated } from "#lib";
 import { getGitDataCollection, gitData } from "#database";
-import { errors, isAuthenticated } from "#lib";
-import { createEventSubscription } from "#lib/pub-sub";
 
 const authenticatedProcedure = procedure.use(isAuthenticated);
 const gitRouter = router({
@@ -59,8 +53,8 @@ const gitRouter = router({
       publishGitDataEvent(ctx, `${ctx.auth.workspaceId}`, { action: "reset", data: {} });
     }),
   changes: authenticatedProcedure.input(z.void()).subscription(async ({ ctx }) => {
-    return createEventSubscription<GitDataEvent>(ctx, `gitData:${ctx.auth.workspaceId}`);
+    return subscribeToGitDataEvents(ctx, `${ctx.auth.workspaceId}`);
   })
 });
 
-export { gitRouter, createGenericInputContentProcessor, createGenericOutputContentProcessor };
+export { gitRouter };

programming_language: TypeScript
filename: process-records.ts
change_type: ModificationType.MODIFY
diff: @@ -1,6 +1,7 @@
 import { minimatch } from "minimatch";
+import { ObjectId } from "mongodb";
 import { FullGitData, GitRecord } from "#database";
-import { ObjectId, UnderscoreID } from "#lib";
+import { UnderscoreID } from "#lib";
 
 type RecordsProcessor = (gitData: UnderscoreID<FullGitData<ObjectId>>) => GitRecord<ObjectId>[];
 

programming_language: TypeScript
filename: index.ts
change_type: ModificationType.MODIFY
diff: @@ -15,16 +15,12 @@ import { contentGroupsRouter } from "./content-groups";
 import { extensionsRouter } from "./extensions";
 import { commentsRouter } from "./comments";
 import { variantsRouter } from "./variants";
-import {
-  createGenericInputContentProcessor,
-  createGenericOutputContentProcessor,
-  gitRouter
-} from "./git";
+import { gitRouter } from "./git";
 import { searchRouter } from "./search";
 import { transformersRouter } from "./transformers";
 import type { TRPCClientError } from "@trpc/client";
-import { Context, createContext } from "#lib/context";
-import { router } from "#lib/trpc";
+import { Context, createContext } from "#lib";
+import { router } from "#lib";
 
 const appRouter = router({
   auth: authRouter,
@@ -54,11 +50,6 @@ type ClientError = TRPCClientError<Router> & {
   data: TRPCClientError<Router>["data"] & { cause?: { code: string } & Record<string, string> };
 };
 
-export {
-  appRouter,
-  createContext,
-  createGenericInputContentProcessor,
-  createGenericOutputContentProcessor
-};
+export { appRouter, createContext };
 export type * from "#database";
 export type { ClientError, Router, PreviewData, HostConfig, Context };

programming_language: TypeScript
filename: roles.ts
change_type: ModificationType.MODIFY
diff: @@ -1,29 +1,15 @@
 import { z } from "zod";
 import { ObjectId } from "mongodb";
-import { procedure, router } from "#lib/trpc";
-import { isAuthenticated } from "#lib/middleware";
-import { zodId } from "#lib/mongo";
 import {
-  Role,
   baseRoleType,
   getRolesCollection,
   role,
   getWorkspaceMembershipsCollection,
   getUsersCollection
 } from "#database";
-import * as errors from "#lib/errors";
-import { createEventPublisher, createEventSubscription } from "#lib/pub-sub";
-import { updateSessionRole } from "#lib/session";
-
-type RoleEvent =
-  | {
-      action: "create";
-      data: Role;
-    }
-  | { action: "update"; data: Partial<Role> & { id: string } }
-  | { action: "delete"; data: { id: string; newRole: Role } };
-
-const publishEvent = createEventPublisher((workspaceId) => `roles:${workspaceId}`);
+import { zodId, isAuthenticated, procedure, router, updateSessionRole, errors } from "#lib";
+import { publishRoleEvent, subscribeToRoleEvents } from "#events";
+
 const basePath = "/roles";
 const authenticatedProcedure = procedure.use(isAuthenticated);
 const rolesRouter = router({
@@ -63,7 +49,7 @@ const rolesRouter = router({
       }));
     }),
   changes: authenticatedProcedure.input(z.void()).subscription(({ ctx }) => {
-    return createEventSubscription<RoleEvent>(ctx, `roles:${ctx.auth.workspaceId}`);
+    return subscribeToRoleEvents(ctx, `${ctx.auth.workspaceId}`);
   }),
   get: authenticatedProcedure
     .meta({
@@ -136,7 +122,7 @@ const rolesRouter = router({
         }
       );
       updateSessionRole(ctx, input.id);
-      publishEvent(ctx, `${ctx.auth.workspaceId}`, {
+      publishRoleEvent(ctx, `${ctx.auth.workspaceId}`, {
         action: "update",
         data: {
           ...input
@@ -161,7 +147,7 @@ const rolesRouter = router({
       };
 
       await rolesCollection.insertOne(role);
-      publishEvent(ctx, `${ctx.auth.workspaceId}`, {
+      publishRoleEvent(ctx, `${ctx.auth.workspaceId}`, {
         action: "create",
         data: {
           ...input,
@@ -211,7 +197,7 @@ const rolesRouter = router({
           }
         }
       );
-      publishEvent(ctx, `${ctx.auth.workspaceId}`, {
+      publishRoleEvent(ctx, `${ctx.auth.workspaceId}`, {
         action: "delete",
         data: {
           id: input.id,

programming_language: TypeScript
filename: search.ts
change_type: ModificationType.MODIFY
diff: @@ -1,7 +1,7 @@
 import { z } from "zod";
-import { isAuthenticated, isEnabled } from "#lib/middleware";
-import { procedure, router } from "#lib/trpc";
-import { errors, zodId } from "#lib";
+import { ObjectId } from "mongodb";
+import { errors, zodId, procedure, router, isAuthenticated, isEnabled } from "#lib";
+import { contentPiece, getContentPiecesCollection } from "#database";
 
 const authenticatedProcedure = procedure.use(isAuthenticated).use(isEnabled);
 const basePath = "/search";
@@ -24,12 +24,14 @@ const searchRouter = router({
       z.array(
         z.object({
           contentPieceId: z.string(),
+          contentPiece,
           breadcrumb: z.array(z.string()),
           content: z.string()
         })
       )
     )
     .query(async ({ ctx, input }) => {
+      const contentPiecesCollection = getContentPiecesCollection(ctx.db);
       const results = await ctx.fastify.search.search({
         query: input.query,
         workspaceId: ctx.auth.workspaceId,
@@ -37,8 +39,32 @@ const searchRouter = router({
         variantId: input.variantId,
         contentPieceId: input.contentPieceId
       });
+      const processedResults = results.data.Get.Content.map(({ _additional, ...result }) => result);
+      const contentPieces = await contentPiecesCollection
+        .find({
+          _id: { $in: processedResults.map(({ contentPieceId }) => new ObjectId(contentPieceId)) }
+        })
+        .toArray();
+
+      return processedResults.map(({ contentPieceId, content, breadcrumb }) => {
+        const { _id, date, contentGroupId, tags, members, ...contentPiece } = contentPieces.find(
+          ({ _id }) => _id.toString() === contentPieceId
+        )!;
 
-      return results.data.Get.Content.map(({ _additional, ...result }) => result);
+        return {
+          contentPieceId,
+          breadcrumb,
+          content,
+          contentPiece: {
+            id: `${_id}`,
+            contentGroupId: `${contentGroupId}`,
+            ...contentPiece,
+            ...(date && { date: date.toISOString() }),
+            ...(tags && { tags: tags.map((tagId) => `${tagId}`) }),
+            ...(members && { members: members.map((members) => `${members}`) })
+          }
+        };
+      });
     }),
   ask: authenticatedProcedure
     .meta({

programming_language: TypeScript
filename: tags.ts
change_type: ModificationType.MODIFY
diff: @@ -1,24 +1,11 @@
 import { ObjectId } from "mongodb";
 import { z } from "zod";
-import { zodId } from "#lib/mongo";
-import { stringToRegex } from "#lib/utils";
-import { isAuthenticated } from "#lib/middleware";
-import { procedure, router } from "#lib/trpc";
-import * as errors from "#lib/errors";
-import { createEventPublisher, createEventSubscription } from "#lib/pub-sub";
-import { ExtendedTag, Tag, getTagsCollection, tag, getContentPiecesCollection } from "#database";
-
-type TagEvent =
-  | { action: "create"; data: Tag }
-  | { action: "update"; data: Partial<Tag> & { id: string } }
-  | {
-      action: "delete";
-      data: { id: string };
-    };
+import { stringToRegex, isAuthenticated, procedure, router, errors, zodId } from "#lib";
+import { ExtendedTag, getTagsCollection, tag, getContentPiecesCollection } from "#database";
+import { publishTagEvent, subscribeToTagEvents } from "#events";
 
 const authenticatedProcedure = procedure.use(isAuthenticated);
 const basePath = "/tags";
-const publishEvent = createEventPublisher<TagEvent>((workspaceId) => `tags:${workspaceId}`);
 const tagsRouter = router({
   get: authenticatedProcedure
     .meta({
@@ -72,7 +59,7 @@ const tagsRouter = router({
 
       if (!matchedCount) throw errors.notFound("tag");
 
-      publishEvent(ctx, `${ctx.auth.workspaceId}`, {
+      publishTagEvent(ctx, `${ctx.auth.workspaceId}`, {
         action: "update",
         data: input
       });
@@ -94,7 +81,7 @@ const tagsRouter = router({
       };
 
       await tagsCollection.insertOne(tag);
-      publishEvent(ctx, `${ctx.auth.workspaceId}`, {
+      publishTagEvent(ctx, `${ctx.auth.workspaceId}`, {
         action: "create",
         data: {
           ...input,
@@ -160,7 +147,7 @@ const tagsRouter = router({
           }
         }
       );
-      publishEvent(ctx, `${ctx.auth.workspaceId}`, {
+      publishTagEvent(ctx, `${ctx.auth.workspaceId}`, {
         action: "delete",
         data: { id: input.id }
       });
@@ -188,7 +175,7 @@ const tagsRouter = router({
       });
     }),
   changes: authenticatedProcedure.input(z.void()).subscription(({ ctx }) => {
-    return createEventSubscription<TagEvent>(ctx, `tags:${ctx.auth.workspaceId}`);
+    return subscribeToTagEvents(ctx, `${ctx.auth.workspaceId}`);
   })
 });
 

programming_language: TypeScript
filename: tokens.ts
change_type: ModificationType.MODIFY
diff: @@ -1,23 +1,20 @@
 import { z } from "zod";
 import { ObjectId } from "mongodb";
 import { nanoid } from "nanoid";
-import { procedure, router } from "#lib/trpc";
-import { AuthenticatedContext, isAuthenticated } from "#lib/middleware";
-import { generateSalt, hashValue } from "#lib/hash";
-import { UnderscoreID, zodId } from "#lib/mongo";
-import { Token, FullToken, getTokensCollection, token } from "#database/tokens";
-import * as errors from "#lib/errors";
-import { createEventPublisher, createEventSubscription } from "#lib/pub-sub";
-
-type TokenEvent =
-  | {
-      action: "create";
-      data: Token;
-    }
-  | { action: "update"; data: Partial<Token> & { id: string } }
-  | { action: "delete"; data: { id: string } };
-
-const publishEvent = createEventPublisher<TokenEvent>((workspaceId) => `tokens:${workspaceId}`);
+import {
+  AuthenticatedContext,
+  isAuthenticated,
+  procedure,
+  router,
+  UnderscoreID,
+  zodId,
+  errors,
+  generateSalt,
+  hashValue
+} from "#lib";
+import { Token, FullToken, getTokensCollection, token } from "#database";
+import { publishTokenEvent, subscribeToTokenEvents } from "#events";
+
 const authenticatedProcedure = procedure.use(isAuthenticated);
 const createToken = async (
   input: Omit<Token, "id">,
@@ -75,7 +72,7 @@ const tokensRouter = router({
 
       if (deletedCount === 0) throw errors.notFound("token");
 
-      publishEvent(ctx, `${ctx.auth.workspaceId}`, {
+      publishTokenEvent(ctx, `${ctx.auth.workspaceId}`, {
         action: "delete",
         data: {
           id: input.id
@@ -125,7 +122,7 @@ const tokensRouter = router({
     .mutation(async ({ ctx, input }) => {
       const { token, value } = await createToken(input, ctx);
 
-      publishEvent(ctx, `${ctx.auth.workspaceId}`, {
+      publishTokenEvent(ctx, `${ctx.auth.workspaceId}`, {
         action: "create",
         data: {
           id: `${token._id}`,
@@ -161,7 +158,7 @@ const tokensRouter = router({
 
       if (matchedCount === 0) throw errors.notFound("token");
 
-      publishEvent(ctx, `${ctx.auth.workspaceId}`, {
+      publishTokenEvent(ctx, `${ctx.auth.workspaceId}`, {
         action: "update",
         data: {
           id,
@@ -170,7 +167,7 @@ const tokensRouter = router({
       });
     }),
   changes: authenticatedProcedure.input(z.void()).subscription(({ ctx }) => {
-    return createEventSubscription<TokenEvent>(ctx, `tokens:${ctx.auth.workspaceId}`);
+    return subscribeToTokenEvents(ctx, `${ctx.auth.workspaceId}`);
   }),
   regenerate: authenticatedProcedure
     .meta({

programming_language: TypeScript
filename: transformers.ts
change_type: ModificationType.MODIFY
diff: @@ -1,25 +1,9 @@
 import { z } from "zod";
-import { isAuthenticated } from "#lib/middleware";
-import { procedure, router } from "#lib/trpc";
-import * as errors from "#lib/errors";
-import { createEventPublisher, createEventSubscription } from "#lib/pub-sub";
-import { Transformer, getGitDataCollection, transformer } from "#database";
-import { ObjectId, zodId } from "#lib/mongo";
-import { getTransformersCollection } from "#database/transformers";
+import { ObjectId } from "mongodb";
+import { getGitDataCollection, transformer, getTransformersCollection } from "#database";
+import { zodId, errors, procedure, router, isAuthenticated } from "#lib";
+import { publishTransformerEvent, subscribeToTransformerEvents } from "#events";
 
-type TransformersEvent =
-  | {
-      action: "create";
-      data: Transformer & { id: string };
-    }
-  | {
-      action: "delete";
-      data: { id: string };
-    };
-
-const publishEvent = createEventPublisher<TransformersEvent>(
-  (workspaceId) => `transformers:${workspaceId}`
-);
 const authenticatedProcedure = procedure.use(isAuthenticated);
 const basePath = "/transformers";
 const transformersRouter = router({
@@ -31,15 +15,17 @@ const transformersRouter = router({
     .input(transformer.omit({ id: true }))
     .output(z.object({ id: zodId() }))
     .mutation(async ({ ctx, input }) => {
+      const extensionId = ctx.req.headers["x-vrite-extension-id"] as string | undefined;
       const transformersCollection = getTransformersCollection(ctx.db);
       const transformer = {
         _id: new ObjectId(),
         workspaceId: ctx.auth.workspaceId,
+        ...(extensionId && { extensionId: new ObjectId(extensionId) }),
         ...input
       };
 
       await transformersCollection.insertOne(transformer);
-      publishEvent(ctx, `${ctx.auth.workspaceId}`, {
+      publishTransformerEvent(ctx, `${ctx.auth.workspaceId}`, {
         action: "create",
         data: { ...input, id: `${transformer._id}` }
       });
@@ -71,7 +57,7 @@ const transformersRouter = router({
 
       if (!deletedCount) throw errors.notFound("transformer");
 
-      publishEvent(ctx, `${ctx.auth.workspaceId}`, { action: "delete", data: input });
+      publishTransformerEvent(ctx, `${ctx.auth.workspaceId}`, { action: "delete", data: input });
     }),
   list: authenticatedProcedure
     .meta({
@@ -79,7 +65,14 @@ const transformersRouter = router({
       permissions: { token: ["workspace:read"] }
     })
     .input(z.void())
-    .output(z.array(transformer.extend({ inUse: z.boolean().optional() })))
+    .output(
+      z.array(
+        transformer.extend({
+          inUse: z.boolean().optional(),
+          extension: z.boolean().optional()
+        })
+      )
+    )
     .query(async ({ ctx }) => {
       const gitDataCollection = getGitDataCollection(ctx.db);
       const transformersCollection = getTransformersCollection(ctx.db);
@@ -93,20 +86,20 @@ const transformersRouter = router({
         .sort("_id", -1)
         .toArray();
 
-      return transformers.map(({ _id, workspaceId, ...transformerData }) => {
+      return transformers.map(({ _id, workspaceId, extensionId, ...transformerData }) => {
         return {
           id: `${_id}`,
           workspaceId: `${workspaceId}`,
           inUse: gitData?.github?.transformer === `${_id}`,
+          ...(extensionId && { extension: true }),
           ...transformerData
         };
       });
     }),
 
   changes: authenticatedProcedure.input(z.void()).subscription(async ({ ctx }) => {
-    return createEventSubscription<TransformersEvent>(ctx, `transformers:${ctx.auth.workspaceId}`);
+    return subscribeToTransformerEvents(ctx, `${ctx.auth.workspaceId}`);
   })
 });
 
 export { transformersRouter };
-export type { TransformersEvent };

programming_language: TypeScript
filename: user-settings.ts
change_type: ModificationType.MODIFY
diff: @@ -1,20 +1,13 @@
 import { z } from "zod";
-import { isAuthenticated, isAuthenticatedUser } from "#lib/middleware";
-import { procedure, router } from "#lib/trpc";
-import * as errors from "#lib/errors";
-import { createEventPublisher, createEventSubscription } from "#lib/pub-sub";
 import {
   getWorkspacesCollection,
   getWorkspaceMembershipsCollection,
-  AppearanceSettings,
   appearanceSettings,
   getUserSettingsCollection
 } from "#database";
-import { zodId } from "#lib";
+import { zodId, errors, procedure, router, isAuthenticated, isAuthenticatedUser } from "#lib";
+import { publishUserSettingsEvent, subscribeToUserSettingsEvents } from "#events";
 
-type UserSettingsEvent = { action: "update"; data: Partial<AppearanceSettings> };
-
-const publishEvent = createEventPublisher<UserSettingsEvent>((userId) => `userSettings:${userId}`);
 const authenticatedUserProcedure = procedure.use(isAuthenticatedUser);
 const authenticatedProcedure = procedure.use(isAuthenticated);
 const basePath = "/user-settings";
@@ -24,7 +17,7 @@ const userSettingsRouter = router({
       openapi: { method: "PUT", path: basePath, protect: true },
       permissions: { token: ["userSettings:write"] }
     })
-    .input(appearanceSettings.partial())
+    .input(appearanceSettings.omit({ codeEditorTheme: true }).partial())
     .output(z.void())
     .mutation(async ({ ctx, input }) => {
       const userSettingsCollection = getUserSettingsCollection(ctx.db);
@@ -35,7 +28,10 @@ const userSettingsRouter = router({
 
       if (!matchedCount) throw errors.notFound("userSettings");
 
-      publishEvent(ctx, `${ctx.auth.userId}`, { action: "update", data: input });
+      publishUserSettingsEvent(ctx, `${ctx.auth.userId}`, {
+        action: "update",
+        data: { ...input, ...(input.uiTheme ? { codeEditorTheme: input.uiTheme } : {}) }
+      });
     }),
   get: authenticatedUserProcedure
     .meta({
@@ -53,7 +49,7 @@ const userSettingsRouter = router({
       if (!userSettings) throw errors.notFound("userSettings");
 
       return {
-        codeEditorTheme: userSettings.codeEditorTheme,
+        codeEditorTheme: userSettings.uiTheme,
         uiTheme: userSettings.uiTheme,
         accentColor: userSettings.accentColor
       };
@@ -81,9 +77,8 @@ const userSettingsRouter = router({
       return `${ctx.auth.workspaceId}`;
     }),
   changes: authenticatedUserProcedure.input(z.void()).subscription(async ({ ctx }) => {
-    return createEventSubscription<UserSettingsEvent>(ctx, `userSettings:${ctx.auth.userId}`);
+    return subscribeToUserSettingsEvents(ctx, `${ctx.auth.userId}`);
   })
 });
 
 export { userSettingsRouter };
-export type { UserSettingsEvent };

programming_language: TypeScript
filename: users.ts
change_type: ModificationType.MODIFY
diff: @@ -1,33 +1,15 @@
 import { z } from "zod";
 import { ObjectId } from "mongodb";
 import { nanoid } from "nanoid";
-import { hashValue } from "#lib/hash";
-import { isAuthenticated } from "#lib/middleware";
-import { UnderscoreID } from "#lib/mongo";
-import { procedure, router } from "#lib/trpc";
-import {
-  FullUser,
-  Profile,
-  VerificationDetails,
-  getUsersCollection,
-  profile,
-  verificationDetails
-} from "#database/users";
-import * as errors from "#lib/errors";
-import { createEventPublisher, createEventSubscription } from "#lib/pub-sub";
-import { stringToRegex } from "#lib/utils";
+import { procedure, router, errors, UnderscoreID, isAuthenticated, hashValue } from "#lib";
+import { FullUser, getUsersCollection, profile, verificationDetails } from "#database/users";
+import { publishUserEvent, subscribeToUserEvents } from "#events";
 
-type UserEvent = {
-  action: "update";
-  data: Partial<Profile> & { id: string } & Partial<VerificationDetails>;
-};
-
-const publishEvent = createEventPublisher<UserEvent>((userId: string) => `user:${userId}`);
 const authenticatedProcedure = procedure.use(isAuthenticated);
 const basePath = "/profile";
 const usersRouter = router({
   changes: authenticatedProcedure.input(z.void()).subscription(async ({ ctx }) => {
-    return createEventSubscription<UserEvent>(ctx, `user:${ctx.auth.userId}`);
+    return subscribeToUserEvents(ctx, `${ctx.auth.userId}`);
   }),
   get: authenticatedProcedure
     .meta({
@@ -118,7 +100,7 @@ const usersRouter = router({
           $set: update
         }
       );
-      publishEvent(ctx, `${ctx.auth.userId}`, {
+      publishUserEvent(ctx, `${ctx.auth.userId}`, {
         action: "update",
         data: {
           id: `${user._id}`,

programming_language: TypeScript
filename: utils.ts
change_type: ModificationType.MODIFY
diff: @@ -1,14 +1,13 @@
 import { z } from "zod";
 import ogs from "open-graph-scraper";
-import { PutObjectCommand } from "@aws-sdk/client-s3";
-import { getSignedUrl } from "@aws-sdk/s3-request-presigner";
-import { nanoid } from "nanoid";
-import mime from "mime-types";
-import { extractPreviewDataFromOpenGraph } from "#lib/utils";
-import { isAuthenticated } from "#lib/middleware";
-import { procedure, router } from "#lib/trpc";
-import * as errors from "#lib/errors";
-import { hostConfig, HostConfig } from "#plugins/host-config";
+import {
+  procedure,
+  router,
+  errors,
+  extractPreviewDataFromOpenGraph,
+  hostConfig,
+  HostConfig
+} from "#lib";
 
 const previewData = z
   .object({
@@ -22,7 +21,6 @@ const previewData = z
 
 interface PreviewData extends z.infer<typeof previewData> {}
 
-const authenticatedProcedure = procedure.use(isAuthenticated);
 const utilsRouter = router({
   hostConfig: procedure.output(hostConfig).query(({ ctx }) => {
     return ctx.fastify.hostConfig;

programming_language: TypeScript
filename: variants.ts
change_type: ModificationType.MODIFY
diff: @@ -1,34 +1,14 @@
 import { z } from "zod";
-import { isAuthenticated } from "#lib/middleware";
-import { procedure, router } from "#lib/trpc";
-import * as errors from "#lib/errors";
-import { createEventPublisher, createEventSubscription } from "#lib/pub-sub";
+import { ObjectId } from "mongodb";
 import {
-  Variant,
   getContentPieceVariantsCollection,
   getContentVariantsCollection,
   getVariantsCollection,
   variant
 } from "#database";
-import { ObjectId, zodId } from "#lib/mongo";
+import { zodId, errors, procedure, router, isAuthenticated } from "#lib";
+import { publishVariantEvent, subscribeToVariantEvents } from "#events";
 
-type VariantsEvent =
-  | {
-      action: "create";
-      data: Variant & { id: string };
-    }
-  | {
-      action: "update";
-      data: Partial<Variant> & { id: string };
-    }
-  | {
-      action: "delete";
-      data: { id: string };
-    };
-
-const publishEvent = createEventPublisher<VariantsEvent>(
-  (workspaceId) => `variants:${workspaceId}`
-);
 const authenticatedProcedure = procedure.use(isAuthenticated);
 const basePath = "/variants";
 const variantsRouter = router({
@@ -48,7 +28,7 @@ const variantsRouter = router({
       };
 
       await variantsCollection.insertOne(variant);
-      publishEvent(ctx, `${ctx.auth.workspaceId}`, {
+      publishVariantEvent(ctx, `${ctx.auth.workspaceId}`, {
         action: "create",
         data: { ...input, id: `${variant._id}` }
       });
@@ -72,7 +52,7 @@ const variantsRouter = router({
 
       if (!matchedCount) throw errors.notFound("variant");
 
-      publishEvent(ctx, `${ctx.auth.workspaceId}`, { action: "update", data: input });
+      publishVariantEvent(ctx, `${ctx.auth.workspaceId}`, { action: "update", data: input });
     }),
   delete: authenticatedProcedure
     .meta({
@@ -101,7 +81,7 @@ const variantsRouter = router({
 
       if (!deletedCount) throw errors.notFound("variant");
 
-      publishEvent(ctx, `${ctx.auth.workspaceId}`, { action: "delete", data: input });
+      publishVariantEvent(ctx, `${ctx.auth.workspaceId}`, { action: "delete", data: input });
       ctx.fastify.search.deleteContent({ variantId, workspaceId: ctx.auth.workspaceId });
     }),
   list: authenticatedProcedure
@@ -131,9 +111,8 @@ const variantsRouter = router({
     }),
 
   changes: authenticatedProcedure.input(z.void()).subscription(async ({ ctx }) => {
-    return createEventSubscription<VariantsEvent>(ctx, `variants:${ctx.auth.workspaceId}`);
+    return subscribeToVariantEvents(ctx, `${ctx.auth.workspaceId}`);
   })
 });
 
 export { variantsRouter };
-export type { VariantsEvent };

programming_language: TypeScript
filename: verification.ts
change_type: ModificationType.MODIFY
diff: @@ -1,44 +1,22 @@
 import { z } from "zod";
 import { ObjectId } from "mongodb";
-import { VerificationDetails, getUsersCollection } from "#database/users";
-import { procedure, router } from "#lib/trpc";
-import { createWorkspace } from "#lib/workspace";
-import * as errors from "#lib/errors";
-import { createSession } from "#lib/session";
-import { isAuthenticatedUser } from "#lib/middleware";
-import { verifyValue } from "#lib";
 import {
-  WorkspaceMembership,
+  getUsersCollection,
+  getUserSettingsCollection,
   getWorkspaceMembershipsCollection
-} from "#database/workspace-memberships";
-import { runWebhooks } from "#lib/webhooks";
-import { createEventPublisher } from "#lib/pub-sub";
-import { getUserSettingsCollection } from "#database";
-
-type VerifyUserEvent = {
-  action: "update";
-  data: { id: string } & Partial<VerificationDetails & { email: string }>;
-};
-type VerifyWorkspaceInviteEvent = {
-  action: "update";
-  data: {
-    id: string;
-    userId: string;
-    pendingInvite?: boolean;
-    profile?: {
-      fullName?: string;
-      username?: string;
-      avatar?: string;
-    };
-  } & Partial<WorkspaceMembership>;
-};
+} from "#database";
+import {
+  runWebhooks,
+  verifyValue,
+  isAuthenticatedUser,
+  createSession,
+  errors,
+  createWorkspace,
+  procedure,
+  router
+} from "#lib";
+import { publishUserEvent, publishWorkspaceMembershipEvent } from "#events";
 
-const publishUserEvent = createEventPublisher<VerifyUserEvent>(
-  (userId: string) => `user:${userId}`
-);
-const publishWorkspaceMembershipEvent = createEventPublisher<VerifyWorkspaceInviteEvent>(
-  (workspaceId: string) => `workspaceMemberships:${workspaceId}`
-);
 const authenticatedUserProcedure = procedure.use(isAuthenticatedUser);
 const verificationRouter = router({
   verifyMagicLink: procedure
@@ -108,7 +86,7 @@ const verificationRouter = router({
         await userSettingsCollection.insertOne({
           _id: new ObjectId(),
           userId: user._id,
-          codeEditorTheme: "dark",
+          codeEditorTheme: "auto",
           uiTheme: "auto",
           accentColor: "energy",
           currentWorkspaceId: workspaceId
@@ -116,7 +94,7 @@ const verificationRouter = router({
         await createSession(ctx, `${user._id}`);
       } catch (error) {
         // eslint-disable-next-line no-console
-        console.error(error);
+        ctx.fastify.log.error(error);
       }
 
       return "/";

programming_language: TypeScript
filename: versions.ts
change_type: ModificationType.DELETE
diff: @@ -1,192 +0,0 @@
-import { Db, ObjectId } from "mongodb";
-import { z } from "zod";
-import { isAuthenticated } from "#lib/middleware";
-import { UnderscoreID } from "#lib/mongo";
-import { procedure, router } from "#lib/trpc";
-import * as errors from "#lib/errors";
-import {
-  FullVersion,
-  getContentPieceVariantsCollection,
-  getContentPiecesCollection,
-  getContentVariantsCollection,
-  getContentsCollection,
-  getVersionsCollection,
-  version
-} from "#database";
-
-const authenticatedProcedure = procedure.use(isAuthenticated);
-const basePath = "/versions";
-const createVersion = async (
-  db: Db,
-  data: Pick<FullVersion<ObjectId>, "name" | "contentPieceId" | "variantId" | "workspaceId">
-): Promise<ObjectId> => {
-  const versionsCollection = getVersionsCollection(db);
-  const contentPiecesCollection = getContentPiecesCollection(db);
-  const contentsCollection = getContentsCollection(db);
-  const contentPieceVariantsCollection = getContentPieceVariantsCollection(db);
-  const contentVariantsCollection = getContentVariantsCollection(db);
-
-  let contentPiece = await contentPiecesCollection.findOne({
-    _id: data.contentPieceId,
-    workspaceId: data.workspaceId
-  });
-
-  if (!contentPiece) throw errors.notFound("contentPiece");
-
-  let content = await contentsCollection.findOne({
-    contentPieceId: contentPiece._id
-  });
-
-  if (!content) throw errors.notFound("content");
-
-  if (data.variantId) {
-    const contentPieceVariant = await contentPieceVariantsCollection.findOne({
-      contentPieceId: contentPiece._id,
-      variantId: data.variantId,
-      workspaceId: data.workspaceId
-    });
-
-    if (!contentPieceVariant) throw errors.notFound("contentPieceVariant");
-
-    const contentVariant = await contentVariantsCollection.findOne({
-      contentPieceId: contentPiece._id,
-      variantId: data.variantId
-    });
-
-    if (!contentVariant) throw errors.notFound("contentVariant");
-
-    contentPiece = { ...contentPiece, ...contentPieceVariant };
-    content = { ...content, ...contentVariant };
-  }
-
-  const version: UnderscoreID<FullVersion<ObjectId>> = {
-    _id: new ObjectId(),
-    name: data.name,
-    date: new Date(),
-    content: content.content,
-    contentPiece: {
-      members: contentPiece.members,
-      tags: contentPiece.tags,
-      title: contentPiece.title,
-      description: contentPiece.description,
-      slug: contentPiece.slug,
-      canonicalLink: contentPiece.canonicalLink,
-      coverAlt: contentPiece.coverAlt,
-      coverUrl: contentPiece.coverUrl,
-      customData: contentPiece.customData,
-      date: contentPiece.date
-    },
-    contentPieceId: contentPiece._id,
-    variantId: data.variantId,
-    workspaceId: data.workspaceId
-  };
-
-  await versionsCollection.insertOne(version);
-
-  return version._id;
-};
-const versionsRouter = router({
-  create: authenticatedProcedure
-    .input(version.pick({ name: true, contentPieceId: true, variantId: true }))
-    .output(version.pick({ id: true }))
-    .mutation(async ({ ctx, input }) => {
-      const versionId = await createVersion(ctx.db, {
-        name: input.name,
-        contentPieceId: new ObjectId(input.contentPieceId),
-        variantId: new ObjectId(input.variantId),
-        workspaceId: ctx.auth.workspaceId
-      });
-
-      return { id: `${versionId}` };
-    }),
-  delete: authenticatedProcedure
-    .input(
-      version.pick({
-        id: true
-      })
-    )
-    .output(z.void())
-    .mutation(async ({ ctx, input }) => {
-      const versionsCollection = getVersionsCollection(ctx.db);
-      const { deletedCount } = await versionsCollection.deleteOne({
-        _id: new ObjectId(input.id),
-        workspaceId: ctx.auth.workspaceId
-      });
-
-      if (!deletedCount) throw errors.notFound("version");
-    }),
-  restore: authenticatedProcedure
-    .input(
-      version.pick({
-        id: true
-      })
-    )
-    .output(z.void())
-    .mutation(async ({ ctx, input }) => {
-      const versionsCollection = getVersionsCollection(ctx.db);
-      const contentPiecesCollection = getContentPiecesCollection(ctx.db);
-      const contentsCollection = getContentsCollection(ctx.db);
-      const contentPieceVariantsCollection = getContentPieceVariantsCollection(ctx.db);
-      const contentVariantsCollection = getContentVariantsCollection(ctx.db);
-      const version = await versionsCollection.findOne({
-        _id: new ObjectId(input.id),
-        workspaceId: ctx.auth.workspaceId
-      });
-
-      if (!version) throw errors.notFound("version");
-
-      if (version.variantId) {
-        const contentPieceVariantUpdateResult = await contentPieceVariantsCollection.updateOne(
-          {
-            contentPieceId: version.contentPieceId,
-            variantId: version.variantId,
-            workspaceId: ctx.auth.workspaceId
-          },
-          {
-            $set: version.contentPiece
-          }
-        );
-
-        if (!contentPieceVariantUpdateResult.matchedCount) {
-          throw errors.notFound("contentPieceVariant");
-        }
-
-        const contentVariantUpdateResult = await contentVariantsCollection.updateOne(
-          {
-            contentPieceId: version.contentPieceId,
-            variantId: version.variantId
-          },
-          {
-            $set: {
-              content: version.content
-            }
-          }
-        );
-
-        if (!contentVariantUpdateResult.matchedCount) throw errors.notFound("contentVariant");
-
-        return;
-      }
-
-      const contentPieceUpdateResult = await contentPiecesCollection.updateOne(
-        {
-          _id: version.contentPieceId,
-          workspaceId: ctx.auth.workspaceId
-        },
-        { $set: version.contentPiece }
-      );
-
-      if (!contentPieceUpdateResult.matchedCount) throw errors.notFound("contentPiece");
-
-      const contentUpdateResult = await contentsCollection.updateOne(
-        {
-          contentPieceId: version.contentPieceId
-        },
-        { $set: { content: version.content } }
-      );
-
-      if (!contentUpdateResult.matchedCount) throw errors.notFound("content");
-    })
-});
-
-export { versionsRouter, createVersion };

programming_language: unknown
filename: webhooks.ts
change_type: ModificationType.MODIFY
diff: @@ -1,29 +1,9 @@
 import { ObjectId } from "mongodb";
 import { z } from "zod";
-import { procedure, router } from "#lib/trpc";
-import { isAuthenticated } from "#lib/middleware";
-import { UnderscoreID, zodId } from "#lib/mongo";
-import { FullWebhook, Webhook, getWebhooksCollection, webhook } from "#database/webhooks";
-import * as errors from "#lib/errors";
-import { createEventPublisher, createEventSubscription } from "#lib/pub-sub";
-
-type WebhookEvent =
-  | {
-      action: "create";
-      data: Webhook & { id: string };
-    }
-  | {
-      action: "update";
-      data: Partial<Webhook> & { id: string };
-    }
-  | {
-      action: "delete";
-      data: { id: string };
-    };
-
-const publishEvent = createEventPublisher<WebhookEvent>((workspaceId) => {
-  return `webhooks:${workspaceId}`;
-});
+import { FullWebhook, Webhook, getWebhooksCollection, webhook } from "#database";
+import { errors, isAuthenticated, UnderscoreID, zodId, procedure, router } from "#lib";
+import { publishWebhookEvent, subscribeToWebhookEvents } from "#events";
+
 const authenticatedProcedure = procedure.use(isAuthenticated);
 const basePath = "/webhooks";
 const webhooksRouter = router({
@@ -143,7 +123,7 @@ const webhooksRouter = router({
       } else if (webhook.event.startsWith("contentPiece")) throw errors.serverError();
 
       await webhooksCollection.insertOne(webhook);
-      publishEvent(ctx, `${ctx.auth.workspaceId}`, {
+      publishWebhookEvent(ctx, `${ctx.auth.workspaceId}`, {
         action: "create",
         data: { ...input, id: `${webhook._id}` }
       });
@@ -151,7 +131,7 @@ const webhooksRouter = router({
       return { id: `${webhook._id}` };
     }),
   changes: authenticatedProcedure.input(z.void()).subscription(({ ctx }) => {
-    return createEventSubscription<WebhookEvent>(ctx, `webhooks:${ctx.auth.workspaceId}`);
+    return subscribeToWebhookEvents(ctx, `${ctx.auth.workspaceId}`);
   }),
   update: authenticatedProcedure
     .meta({
@@ -189,7 +169,7 @@ const webhooksRouter = router({
 
       if (!matchedCount) throw errors.notFound("webhook");
 
-      publishEvent(ctx, `${ctx.auth.workspaceId}`, {
+      publishWebhookEvent(ctx, `${ctx.auth.workspaceId}`, {
         action: "update",
         data: input
       });
@@ -210,7 +190,7 @@ const webhooksRouter = router({
 
       if (!deletedCount) throw errors.notFound("webhook");
 
-      publishEvent(ctx, `${ctx.auth.workspaceId}`, {
+      publishWebhookEvent(ctx, `${ctx.auth.workspaceId}`, {
         action: "delete",
         data: input
       });

programming_language: TypeScript
filename: workspace-memberships.ts
change_type: ModificationType.MODIFY
diff: @@ -1,53 +1,33 @@
-import { procedure, router } from "../lib/trpc";
-import { AuthenticatedContext, isAuthenticated, isAuthenticatedUser } from "../lib/middleware";
-import { UnderscoreID, generateSalt, hashValue, stringToRegex, zodId } from "../lib";
 import { ObjectId } from "mongodb";
 import { z } from "zod";
 import { nanoid } from "nanoid";
 import {
+  contentPieceMember,
   FullWorkspaceMembership,
-  WorkspaceMembership,
   getWorkspaceMembershipsCollection,
-  workspaceMembership
-} from "#database/workspace-memberships";
-import * as errors from "#lib/errors";
-import { getWorkspacesCollection, workspace } from "#database/workspaces";
-import { createEventPublisher, createEventSubscription } from "#lib/pub-sub";
-import { runWebhooks } from "#lib/webhooks";
-import {
-  Role,
-  contentPieceMember,
+  workspaceMembership,
   getRolesCollection,
   getUsersCollection,
-  profile,
-  role
+  getWorkspacesCollection,
+  workspace
 } from "#database";
-import { updateSessionUser } from "#lib/session";
-
-type WorkspaceMembershipEvent =
-  | { action: "create"; data: { id: string; pendingInvite: boolean } & WorkspaceMembership }
-  | {
-      action: "update";
-      data: {
-        id: string;
-        userId: string;
-        role?: Role;
-        pendingInvite?: boolean;
-        profile?: {
-          fullName?: string;
-          username?: string;
-          avatar?: string;
-        };
-      } & Partial<WorkspaceMembership>;
-    }
-  | {
-      action: "delete";
-      data: { id: string; userId: string };
-    };
-
-const publishEvent = createEventPublisher<WorkspaceMembershipEvent>(
-  (workspaceId) => `workspaceMemberships:${workspaceId}`
-);
+import {
+  AuthenticatedContext,
+  isAuthenticated,
+  procedure,
+  router,
+  isAuthenticatedUser,
+  updateSessionUser,
+  runWebhooks,
+  errors,
+  UnderscoreID,
+  generateSalt,
+  hashValue,
+  stringToRegex,
+  zodId
+} from "#lib";
+import { publishWorkspaceMembershipEvent, subscribeToWorkspaceMembershipEvents } from "#events";
+
 const authenticatedProcedure = procedure.use(isAuthenticated);
 const authenticatedUserProcedure = procedure.use(isAuthenticatedUser);
 const basePath = "/workspace-memberships";
@@ -83,7 +63,7 @@ const removeMemberFromWorkspace = async (ctx: AuthenticatedContext, id?: string)
     _id: workspaceMembership._id
   });
   await updateSessionUser(ctx, `${workspaceMembership.userId}`);
-  publishEvent(ctx, `${ctx.auth.workspaceId}`, {
+  publishWorkspaceMembershipEvent(ctx, `${ctx.auth.workspaceId}`, {
     action: "delete",
     data: { id: `${workspaceMembership._id}`, userId: `${workspaceMembership.userId}` }
   });
@@ -150,7 +130,7 @@ const workspaceMembershipsRouter = router({
         }
       );
       await updateSessionUser(ctx, `${membership.userId}`);
-      publishEvent(ctx, `${ctx.auth.workspaceId}`, {
+      publishWorkspaceMembershipEvent(ctx, `${ctx.auth.workspaceId}`, {
         action: "update",
         data: {
           id: input.id,
@@ -332,7 +312,7 @@ const workspaceMembershipsRouter = router({
     })
     .input(
       z.object({
-        email: z.string().email(),
+        email: z.string().email().max(320),
         name: z.string(),
         roleId: zodId()
       })
@@ -368,7 +348,7 @@ const workspaceMembershipsRouter = router({
         inviteeName: input.name,
         membershipId: `${workspaceMembership._id}`
       });
-      publishEvent(ctx, `${ctx.auth.workspaceId}`, {
+      publishWorkspaceMembershipEvent(ctx, `${ctx.auth.workspaceId}`, {
         action: "create",
         data: {
           ...input,
@@ -379,10 +359,7 @@ const workspaceMembershipsRouter = router({
       runWebhooks(ctx, "memberInvited", { ...input, id: `${workspaceMembership._id}` });
     }),
   changes: authenticatedProcedure.subscription(({ ctx }) => {
-    return createEventSubscription<WorkspaceMembershipEvent>(
-      ctx,
-      `workspaceMemberships:${ctx.auth.workspaceId}`
-    );
+    return subscribeToWorkspaceMembershipEvents(ctx, `${ctx.auth.workspaceId}`);
   }),
   delete: authenticatedProcedure
     .meta({

programming_language: TypeScript
filename: workspace-settings.ts
change_type: ModificationType.MODIFY
diff: @@ -1,37 +1,15 @@
-import { procedure, router } from "../lib/trpc";
-import { isAuthenticated } from "../lib/middleware";
 import { z } from "zod";
 import zodToJsonSchema from "zod-to-json-schema";
 import { ObjectId } from "mongodb";
 import {
   FullWorkspaceSettings,
-  WorkspaceSettings,
-  wrapper,
   getWorkspaceSettingsCollection,
   prettierConfig,
-  workspaceSettings,
-  Wrapper
+  workspaceSettings
 } from "#database/workspace-settings";
-import * as errors from "#lib/errors";
-import { createEventPublisher, createEventSubscription } from "#lib/pub-sub";
+import { errors, isAuthenticated, procedure, router } from "#lib";
+import { subscribeToWorkspaceSettingsEvents, publishWorkspaceSettingsEvent } from "#events";
 
-type WorkspaceSettingsEvent =
-  | {
-      action: "update";
-      data: Partial<Omit<WorkspaceSettings, "id">>;
-    }
-  | {
-      action: "createWrapper";
-      data: Wrapper;
-    }
-  | {
-      action: "deleteWrapper";
-      data: Pick<Wrapper, "key">;
-    };
-
-const publishEvent = createEventPublisher<WorkspaceSettingsEvent>((workspaceId) => {
-  return `workspaceSettings:${workspaceId}`;
-});
 const authenticatedProcedure = procedure.use(isAuthenticated);
 const basePath = "/workspace-settings";
 const workspaceSettingsRouter = router({
@@ -58,107 +36,11 @@ const workspaceSettingsRouter = router({
         metadata: workspaceSettings.metadata,
         marks: workspaceSettings.marks,
         blocks: workspaceSettings.blocks,
-        embeds: workspaceSettings.embeds,
-        wrappers: workspaceSettings.wrappers || []
-      };
-    }),
-  createWrapper: authenticatedProcedure
-    .meta({
-      openapi: { method: "POST", path: `${basePath}/wrapper`, protect: true },
-      permissions: { session: ["manageWorkspace"], token: ["workspace:write"] }
-    })
-    .input(wrapper)
-    .output(z.object({ key: wrapper.shape.key }))
-    .mutation(async ({ input, ctx }) => {
-      const extensionId = ctx.req.headers["x-vrite-extension-id"] as string | undefined;
-      const workspaceSettingsCollection = getWorkspaceSettingsCollection(ctx.db);
-      const workspaceSettings = await workspaceSettingsCollection.findOne({
-        workspaceId: ctx.auth.workspaceId
-      });
-
-      if (!workspaceSettings) throw errors.notFound("workspaceSettings");
-
-      const sameKeyWrapperIndex =
-        workspaceSettings.wrappers?.findIndex((wrapper) => wrapper.key === input.key) || -1;
-
-      if (sameKeyWrapperIndex >= 0) {
-        await workspaceSettingsCollection.updateOne(
-          {
-            workspaceId: ctx.auth.workspaceId
-          },
-          {
-            $set: {
-              wrappers: (workspaceSettings.wrappers || []).map((item, index) => {
-                if (index === sameKeyWrapperIndex) {
-                  return {
-                    ...item,
-                    ...input,
-                    ...(extensionId && { extension: item.extension || true })
-                  };
-                }
-
-                return item;
-              })
-            }
-          }
-        );
-      } else {
-        await workspaceSettingsCollection.updateOne(
-          {
-            workspaceId: ctx.auth.workspaceId
-          },
-          {
-            $push: {
-              wrappers: {
-                ...input,
-                ...(extensionId && { extension: true })
-              }
-            }
-          }
-        );
-      }
-
-      publishEvent(ctx, `${ctx.auth.workspaceId}`, {
-        action: "createWrapper",
-        data: input
-      });
-
-      return {
-        key: input.key
+        embeds: workspaceSettings.embeds
       };
     }),
-  deleteWrapper: authenticatedProcedure
-    .meta({
-      openapi: { method: "DELETE", path: `${basePath}/wrapper`, protect: true },
-      permissions: { session: ["manageWorkspace"], token: ["workspace:write"] }
-    })
-    .input(wrapper.pick({ key: true }))
-    .output(z.void())
-    .mutation(async ({ input, ctx }) => {
-      const workspaceSettingsCollection = getWorkspaceSettingsCollection(ctx.db);
-
-      await workspaceSettingsCollection.updateOne(
-        {
-          workspaceId: ctx.auth.workspaceId
-        },
-        {
-          $pull: {
-            wrappers: {
-              key: input.key
-            }
-          }
-        }
-      );
-      publishEvent(ctx, `${ctx.auth.workspaceId}`, {
-        action: "deleteWrapper",
-        data: input
-      });
-    }),
   changes: authenticatedProcedure.input(z.void()).subscription(({ ctx }) => {
-    return createEventSubscription<WorkspaceSettingsEvent>(
-      ctx,
-      `workspaceSettings:${ctx.auth.workspaceId}`
-    );
+    return subscribeToWorkspaceSettingsEvents(ctx, `${ctx.auth.workspaceId}`);
   }),
   update: authenticatedProcedure
     .meta({
@@ -168,7 +50,7 @@ const workspaceSettingsRouter = router({
     .input(
       workspaceSettings
         .partial()
-        .omit({ id: true, prettierConfig: true, wrappers: true })
+        .omit({ id: true, prettierConfig: true })
         .extend({ prettierConfig: z.string().optional() })
     )
     .output(z.void())
@@ -196,7 +78,7 @@ const workspaceSettingsRouter = router({
 
       if (!matchedCount) throw errors.notFound("workspaceSettings");
 
-      publishEvent(ctx, `${ctx.auth.workspaceId}`, {
+      publishWorkspaceSettingsEvent(ctx, `${ctx.auth.workspaceId}`, {
         action: "update",
         data: input
       });
@@ -210,4 +92,4 @@ const workspaceSettingsRouter = router({
     })
 });
 
-export { workspaceSettingsRouter, publishEvent as publishWorkspaceSettingsEvent };
+export { workspaceSettingsRouter };

programming_language: TypeScript
filename: workspaces.ts
change_type: ModificationType.MODIFY
diff: @@ -1,20 +1,16 @@
-import { procedure, router } from "../lib/trpc";
-import { isAuthenticated, isAuthenticatedUser } from "../lib/middleware";
-import { zodId } from "../lib";
 import { z } from "zod";
-import * as errors from "#lib/errors";
-import { Workspace, getWorkspacesCollection, workspace } from "#database/workspaces";
-import { createEventPublisher, createEventSubscription } from "#lib/pub-sub";
-import { createWorkspace, deleteWorkspace } from "#lib/workspace";
-import { getUsersCollection } from "#database";
+import {
+  errors,
+  createWorkspace,
+  deleteWorkspace,
+  isAuthenticated,
+  isAuthenticatedUser,
+  procedure,
+  router
+} from "#lib";
+import { getWorkspacesCollection, workspace, getUsersCollection } from "#database";
+import { subscribeToWorkspaceEvents, publishWorkspaceEvent } from "#events";
 
-type WorkspaceEvent =
-  | { action: "update"; data: Partial<Workspace> & { id: string } }
-  | { action: "delete"; data: { id: string } };
-
-const publishEvent = createEventPublisher<WorkspaceEvent>((workspaceId) => {
-  return `workspace:${workspaceId}`;
-});
 const authenticatedProcedure = procedure.use(isAuthenticated);
 const authenticatedUserProcedure = procedure.use(isAuthenticatedUser);
 const basePath = "/workspace";
@@ -42,7 +38,7 @@ const workspacesRouter = router({
       };
     }),
   changes: authenticatedProcedure.subscription(({ ctx }) => {
-    return createEventSubscription<WorkspaceEvent>(ctx, `workspace:${ctx.auth.workspaceId}`);
+    return subscribeToWorkspaceEvents(ctx, `${ctx.auth.workspaceId}`);
   }),
   update: authenticatedProcedure
     .meta({
@@ -61,7 +57,7 @@ const workspacesRouter = router({
 
       if (!matchedCount) throw errors.notFound("workspace");
 
-      publishEvent(ctx, `${ctx.auth.workspaceId}`, {
+      publishWorkspaceEvent(ctx, `${ctx.auth.workspaceId}`, {
         action: "update",
         data: input
       });
@@ -94,7 +90,7 @@ const workspacesRouter = router({
     .output(z.void())
     .mutation(async ({ ctx }) => {
       await deleteWorkspace(ctx.auth.workspaceId, ctx.fastify);
-      publishEvent(ctx, `${ctx.auth.workspaceId}`, {
+      publishWorkspaceEvent(ctx, `${ctx.auth.workspaceId}`, {
         action: "delete",
         data: {
           id: `${ctx.auth.workspaceId}`

programming_language: TypeScript
filename: server.ts
change_type: ModificationType.MODIFY
diff: @@ -1,10 +1,4 @@
-import { OAuthPlugin } from "./plugins/oauth";
-import { s3Plugin } from "./plugins/s3";
-import { mailPlugin } from "./plugins/email";
-import { sessionPlugin } from "./plugins/session";
-import { pubSubPlugin } from "./plugins/pub-sub";
 import { envSchema } from "./env";
-import { databasePlugin } from "./plugins/database";
 import createFastify, { FastifyInstance } from "fastify";
 import envPlugin from "@fastify/env";
 import mongoPlugin from "@fastify/mongodb";
@@ -12,10 +6,29 @@ import redisPlugin from "@fastify/redis";
 import jwtPlugin from "@fastify/jwt";
 import cookiePlugin from "@fastify/cookie";
 import zodToJsonSchema from "zod-to-json-schema";
-import { ZodRawShape } from "zod";
-import { gitSyncPlugin, hostConfigPlugin, searchPlugin } from "#plugins";
+import {
+  gitSyncPlugin,
+  hostConfigPlugin,
+  searchPlugin,
+  databasePlugin,
+  pubSubPlugin,
+  sessionPlugin,
+  mailPlugin,
+  s3Plugin,
+  OAuthPlugin
+} from "#plugins";
 
-const createServer = async (envSchemaExtension?: ZodRawShape): Promise<FastifyInstance> => {
+const createServer = async (
+  pluginOptions: Partial<{
+    database: boolean;
+    pubSub: boolean;
+    storage: boolean;
+    auth: boolean;
+    email: boolean;
+    gitSync: boolean;
+    search: boolean;
+  }>
+): Promise<FastifyInstance> => {
   const server = createFastify({
     maxParamLength: 5000,
     logger: false
@@ -25,32 +38,55 @@ const createServer = async (envSchemaExtension?: ZodRawShape): Promise<FastifyIn
   await server
     .register(envPlugin, {
       dotenv: true,
-      schema: zodToJsonSchema(envSchema.extend(envSchemaExtension || {}))
+      schema: zodToJsonSchema(envSchema)
     })
     .register(hostConfigPlugin);
+
   // Data
-  await server
-    .register(mongoPlugin, {
+  if (pluginOptions.database) {
+    await server.register(mongoPlugin, {
       forceClose: true,
       url: server.config.MONGO_URL
-    })
-    .register(redisPlugin, { url: server.config.REDIS_URL })
-    .register(redisPlugin, { url: server.config.REDIS_URL, namespace: "sub" });
-  await server.register(databasePlugin).register(pubSubPlugin).register(s3Plugin);
+    });
+    await server.register(databasePlugin);
+  }
+
+  if (pluginOptions.pubSub) {
+    await server
+      .register(redisPlugin, { url: server.config.REDIS_URL })
+      .register(redisPlugin, { url: server.config.REDIS_URL, namespace: "sub" });
+    await server.register(pubSubPlugin);
+  }
+
+  if (pluginOptions.storage) {
+    await server.register(s3Plugin);
+  }
+
   // Auth
-  await server
-    .register(cookiePlugin, { secret: server.config.SECRET })
-    .register(jwtPlugin, {
-      secret: server.config.SECRET,
-      cookie: { cookieName: "accessToken", signed: true }
-    })
-    .register(sessionPlugin)
-    .register(OAuthPlugin);
+  if (pluginOptions.auth) {
+    await server
+      .register(cookiePlugin, { secret: server.config.SECRET })
+      .register(jwtPlugin, {
+        secret: server.config.SECRET,
+        cookie: { cookieName: "accessToken", signed: true }
+      })
+      .register(sessionPlugin)
+      .register(OAuthPlugin);
+  }
+
   // Email
-  await server.register(mailPlugin);
+  if (pluginOptions.email) {
+    await server.register(mailPlugin);
+  }
+
   // GitHub sync
-  await server.register(gitSyncPlugin);
-  await server.register(searchPlugin);
+  if (pluginOptions.gitSync) {
+    await server.register(gitSyncPlugin);
+  }
+
+  if (pluginOptions.search) {
+    await server.register(searchPlugin);
+  }
 
   return server;
 };

programming_language: TypeScript
filename: input.tsx
change_type: ModificationType.MODIFY
diff: @@ -27,6 +27,7 @@ interface InputProps extends JSX.InputHTMLAttributes<HTMLInputElement> {
   suggestions?: string[];
   textarea?: boolean;
   autoResize?: boolean;
+  suggestionsBoxClass?: string;
   ref?: Ref<HTMLInputElement>[1];
   color?: keyof typeof inputColors;
   adornment?(): JSX.Element;
@@ -205,7 +206,8 @@ const Input: Component<InputProps> = (props) => {
       <Show when={suggestions().length > 0 && focused()}>
         <Card
           class={clsx(
-            `:base-2: absolute z-50 flex flex-col p-1 overflow-hidden transition-all duration-300 transform shadow-2xl w-full`
+            `:base-2: absolute z-50 flex flex-col p-1 overflow-hidden transition-all duration-300 transform shadow-2xl w-full`,
+            props.suggestionsBoxClass
           )}
           ref={setBoxRef}
         >

programming_language: TypeScript
filename: tooltip.tsx
change_type: ModificationType.MODIFY
diff: @@ -76,7 +76,10 @@ const Tooltip: Component<TooltipProps> = (props) => {
     }
   };
 
-  document.body.addEventListener("pointermove", onPointerMove);
+  if (typeof document !== "undefined") {
+    document.body.addEventListener("pointermove", onPointerMove);
+  }
+
   controller.onPositionUpdate(updatePosition);
   onMount(() => {
     const referenceElement = referenceRef();
@@ -118,7 +121,10 @@ const Tooltip: Component<TooltipProps> = (props) => {
   );
   onCleanup(() => {
     cleanupRef()?.();
-    document.body.removeEventListener("pointermove", onPointerMove);
+
+    if (typeof document !== "undefined") {
+      document.body.removeEventListener("pointermove", onPointerMove);
+    }
   });
 
   return (

programming_language: TypeScript
filename: code-block.ts
change_type: ModificationType.MODIFY
diff: @@ -3,6 +3,8 @@ import { Node, mergeAttributes } from "@tiptap/core";
 
 interface CodeBlockAttributes {
   lang?: string;
+  title?: string;
+  meta?: string;
 }
 interface CodeBlockOptions {
   inline: boolean;
@@ -21,19 +23,12 @@ declare module "@tiptap/core" {
 
 const CodeBlock = Node.create<CodeBlockOptions>({
   name: "codeBlock",
-
   content: "text*",
-
   marks: "",
-
   group: "block",
-
   code: true,
-
   atom: true,
-
   isolating: true,
-
   addOptions() {
     return {
       inline: false,
@@ -59,6 +54,18 @@ const CodeBlock = Node.create<CodeBlockOptions>({
           return language.toLowerCase();
         },
         rendered: false
+      },
+      title: {
+        default: null,
+        parseHTML: (element) => {
+          return element.getAttribute("data-title");
+        }
+      },
+      meta: {
+        default: null,
+        parseHTML: (element) => {
+          return element.getAttribute("data-meta");
+        }
       }
     };
   },
@@ -77,7 +84,9 @@ const CodeBlock = Node.create<CodeBlockOptions>({
       [
         "code",
         {
-          class: node.attrs.lang ? `language-${node.attrs.lang}` : null
+          "class": node.attrs.lang ? `language-${node.attrs.lang}` : null,
+          "data-title": node.attrs.title,
+          "data-meta": node.attrs.meta
         },
         0
       ]

programming_language: TypeScript
filename: element.ts
change_type: ModificationType.ADD
diff: @@ -0,0 +1,117 @@
+import { ExtendedRegExpMatchArray, Node, mergeAttributes, wrappingInputRule } from "@tiptap/core";
+import { nodeInputRule } from "#node-input-rule";
+
+interface ElementAttributes {
+  type?: string;
+  props: Record<string, unknown>;
+}
+
+declare module "@tiptap/core" {
+  interface Commands<ReturnType> {
+    Element: {
+      setElement: (attrs?: ElementAttributes) => ReturnType;
+      toggleElement: (attrs?: ElementAttributes) => ReturnType;
+      unsetElement: () => ReturnType;
+    };
+  }
+}
+
+const Element = Node.create({
+  name: "element",
+  content: "block*",
+  group: "block",
+  isolating: true,
+  defining: true,
+  selectable: true,
+  addAttributes() {
+    return {
+      props: {
+        default: {},
+        parseHTML: (element) => {
+          return JSON.parse(element.getAttribute("data-props") || "{}");
+        }
+      },
+      type: {
+        default: "Element",
+        parseHTML: (element) => {
+          return element.getAttribute("data-type");
+        }
+      }
+    };
+  },
+  parseHTML() {
+    return [
+      {
+        tag: "div[data-element=true]"
+      }
+    ];
+  },
+  renderHTML({ node, HTMLAttributes }) {
+    return [
+      "div",
+      mergeAttributes(HTMLAttributes, {
+        "data-element": "true",
+        "data-type": node.attrs.type,
+        "data-props": JSON.stringify(node.attrs.props)
+      }),
+      0
+    ];
+  },
+  addCommands() {
+    return {
+      setElement: (attrs) => {
+        return ({ commands }) => {
+          return commands.insertContent({
+            type: this.name,
+            attrs: {
+              type: "Element",
+              props: {},
+              ...attrs
+            }
+            // content: [{ type: "paragraph" }]
+          });
+        };
+      },
+      toggleElement: (attrs) => {
+        return ({ commands }) => {
+          return commands.toggleWrap(this.name, attrs);
+        };
+      },
+      unsetElement: () => {
+        return ({ commands }) => {
+          return commands.lift(this.name);
+        };
+      }
+    };
+  },
+  addInputRules() {
+    const getAttributes = (input: ExtendedRegExpMatchArray): Record<string, any> => {
+      const [code] = input;
+      const tagRegex = /^<(\w+?)(?:\s|\n|\/|>)/;
+      const [, tag] = tagRegex.exec(code.trim()) || [];
+
+      if (tag && tag !== "undefined") {
+        return { type: tag, props: {} };
+      }
+
+      return {};
+    };
+
+    return [
+      nodeInputRule({
+        find: /^<.*?.+?\/>$/,
+        type: this.type,
+        getAttributes
+      }),
+      wrappingInputRule({
+        find: /^<.*?.+?>$/,
+        type: this.type,
+        joinPredicate: () => false,
+        getAttributes
+      })
+    ];
+  }
+});
+
+export { Element };
+export type { ElementAttributes };

programming_language: TypeScript
filename: embed.ts
change_type: ModificationType.MODIFY
diff: @@ -22,6 +22,7 @@ const Embed = Node.create({
   selectable: true,
   inline: false,
   group: "block",
+  draggable: true,
   addAttributes() {
     return {
       embed: {

programming_language: TypeScript
filename: image.ts
change_type: ModificationType.MODIFY
diff: @@ -25,6 +25,7 @@ declare module "@tiptap/core" {
 
 const Image = Node.create<ImageOptions>({
   name: "image",
+  draggable: true,
   addOptions() {
     return {
       inline: false,

programming_language: TypeScript
filename: index.ts
change_type: ModificationType.MODIFY
diff: @@ -1,5 +1,5 @@
 export * from "./code-block";
-export * from "./wrapper";
+export * from "./element";
 export * from "./task-item";
 export * from "./list-item";
 export * from "./embed";

programming_language: TypeScript
filename: wrapper.ts
change_type: ModificationType.DELETE
diff: @@ -1,94 +0,0 @@
-import { nodeInputRule } from "./node-input-rule";
-import { Node, mergeAttributes, wrappingInputRule } from "@tiptap/core";
-
-interface WrapperAttributes {
-  name?: string;
-}
-interface WrapperOptions {
-  HTMLAttributes: WrapperAttributes;
-}
-
-declare module "@tiptap/core" {
-  interface Commands<ReturnType> {
-    wrapper: {
-      setWrapper: (attrs?: WrapperAttributes) => ReturnType;
-      toggleWrapper: (attrs?: WrapperAttributes) => ReturnType;
-      unsetWrapper: () => ReturnType;
-    };
-  }
-}
-
-const Wrapper = Node.create<WrapperOptions>({
-  name: "wrapper",
-  content: "block+",
-  group: "block",
-  isolating: true,
-  defining: true,
-  addOptions() {
-    return {
-      HTMLAttributes: {}
-    };
-  },
-  addAttributes() {
-    return {
-      key: {
-        default: null,
-        parseHTML: (element) => {
-          return element.getAttribute("data-key");
-        }
-      }
-    };
-  },
-  parseHTML() {
-    return [
-      {
-        tag: "div[data-wrapper=true]"
-      }
-    ];
-  },
-  renderHTML({ node, HTMLAttributes }) {
-    return [
-      "div",
-      mergeAttributes(this.options.HTMLAttributes, HTMLAttributes, {
-        "data-wrapper": "true",
-        "data-key": node.attrs.key
-      }),
-      0
-    ];
-  },
-  addCommands() {
-    return {
-      setWrapper: (attrs) => {
-        return ({ commands }) => {
-          return commands.wrapIn(this.name, attrs);
-        };
-      },
-      toggleWrapper: (attrs) => {
-        return ({ commands }) => {
-          return commands.toggleWrap(this.name, attrs);
-        };
-      },
-      unsetWrapper: () => {
-        return ({ commands }) => {
-          return commands.lift(this.name);
-        };
-      }
-    };
-  },
-  addInputRules() {
-    return [
-      wrappingInputRule({
-        find: /(^:::(.*?)\s$)/,
-        type: this.type,
-        getAttributes: (match) => {
-          const [, , key] = match;
-
-          return { key: key.trim() };
-        }
-      })
-    ];
-  }
-});
-
-export { Wrapper };
-export type { WrapperAttributes, WrapperOptions };

programming_language: unknown
filename: render-email.tsx
change_type: ModificationType.MODIFY
diff: @@ -6,8 +6,6 @@ import { WorkspaceInvite } from "../emails/workspace-invite";
 import { render } from "@react-email/render";
 import * as React from "react";
 
-type RenderEmail = typeof renderEmail;
-
 const templateMap = {
   "magic-link": MagicLink,
   "verify-email-change": VerifyEmailChange,
@@ -15,7 +13,7 @@ const templateMap = {
   "verify-password-change": VerifyPasswordChange,
   "workspace-invite": WorkspaceInvite
 };
-const renderEmail = (<T extends keyof typeof templateMap>(
+const renderEmail = <T extends keyof typeof templateMap>(
   template: T,
   props: Record<string, string>,
   plainText?: boolean
@@ -23,7 +21,9 @@ const renderEmail = (<T extends keyof typeof templateMap>(
   const Template = templateMap[template] as React.FC<Record<string, string>>;
 
   return render(<Template {...props} />, { plainText });
-}) as (test: string) => string;
+};
+
+type RenderEmail = typeof renderEmail;
 
 export { renderEmail };
 export type { RenderEmail };

programming_language: TypeScript
filename: spec.json
change_type: ModificationType.MODIFY
diff: @@ -4,7 +4,6 @@
   "description": "Automatically publish and update articles on Dev.to",
   "permissions": ["contentGroups:read", "contentPieces:read", "webhooks:read", "webhooks:write"],
   "lifecycle": {
-    "on:install": "install",
     "on:uninstall": "uninstall",
     "on:configure": "configure",
     "on:initConfigurationView": "initConfigurationView",

programming_language: JavaScript
filename: spec.json
change_type: ModificationType.MODIFY
diff: @@ -4,7 +4,6 @@
   "description": "Automatically publish and update articles on Hashnode",
   "permissions": ["contentGroups:read", "contentPieces:read", "webhooks:read", "webhooks:write"],
   "lifecycle": {
-    "on:install": "install",
     "on:uninstall": "uninstall",
     "on:configure": "configure",
     "on:initConfigurationView": "initConfigurationView",

programming_language: JavaScript
filename: configure.ts
change_type: ModificationType.ADD
diff: @@ -0,0 +1,23 @@
+import { ExtensionBaseContext } from "@vrite/extensions";
+
+const configure = async (context: ExtensionBaseContext): Promise<void> => {
+  const transformers = await context.client.transformers.list();
+  const mdxTransformer = transformers.find((transformer) => {
+    return (
+      transformer.label === "MDX" &&
+      transformer.input === "https://extensions.vrite.io/mdx/input" &&
+      transformer.output === "https://extensions.vrite.io/mdx/output"
+    );
+  });
+
+  if (!mdxTransformer) {
+    await context.client.transformers.create({
+      input: "https://extensions.vrite.io/mdx/input",
+      output: "https://extensions.vrite.io/mdx/output",
+      maxBatchSize: 100,
+      label: "MDX"
+    });
+  }
+};
+
+export default configure;

programming_language: TypeScript
filename: uninstall.ts
change_type: ModificationType.ADD
diff: @@ -0,0 +1,23 @@
+import { ExtensionGeneralContext } from "@vrite/extensions";
+
+const uninstall = async (context: ExtensionGeneralContext): Promise<void> => {
+  const transformers = await context.client.transformers.list();
+
+  if (transformers.length > 0) {
+    const mdxTransformer = transformers.find((transformer) => {
+      return (
+        transformer.label === "MDX" &&
+        transformer.input === "https://extensions.vrite.io/mdx/input" &&
+        transformer.output === "https://extensions.vrite.io/mdx/output"
+      );
+    });
+
+    if (mdxTransformer) {
+      await context.client.transformers.delete({
+        id: mdxTransformer?.id
+      });
+    }
+  }
+};
+
+export default uninstall;

programming_language: TypeScript
filename: icon-dark.svg
change_type: ModificationType.ADD
diff: @@ -0,0 +1,7 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
+    <path
+        d="M20.3,16.5l-3.9,3.9-4-3.9,1.1-1.1,2.1,2.1V11.8h1.5v5.8l2.1-2.1ZM3.5,15.7l2.7,2.7L9,15.7v4.4h1.5V12L6.2,16.3,2,12v8.1H3.5Z"
+        style="fill:#d2d2d2" />
+    <path d="M28.8,20l-3.1-3.1L22.6,20l-1-1.1,3.1-3.1-3.2-3.2,1.1-1,3.1,3.2,3.2-3.2,1.1,1-3.2,3.2,3.1,3.1Z"
+        style="fill:#f9ac00" />
+</svg>
\ No newline at end of file

programming_language: Markdown
filename: icon.svg
change_type: ModificationType.ADD
diff: @@ -0,0 +1,7 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
+    <path
+        d="M20.3,16.5l-3.9,3.9-4-3.9,1.1-1.1,2.1,2.1V11.8h1.5v5.8l2.1-2.1ZM3.5,15.7l2.7,2.7L9,15.7v4.4h1.5V12L6.2,16.3,2,12v8.1H3.5Z"
+        style="fill:#00000" />
+    <path d="M28.8,20l-3.1-3.1L22.6,20l-1-1.1,3.1-3.1-3.2-3.2,1.1-1,3.1,3.2,3.2-3.2,1.1,1-3.2,3.2,3.1,3.1Z"
+        style="fill:#f9ac00" />
+</svg>
\ No newline at end of file

programming_language: SQL
filename: spec.json
change_type: ModificationType.ADD
diff: @@ -0,0 +1,10 @@
+{
+  "name": "mdx",
+  "displayName": "MDX",
+  "description": "Adds MDX transformers to Git sync",
+  "permissions": ["workspace:write", "workspace:read"],
+  "lifecycle": {
+    "on:uninstall": "uninstall",
+    "on:configure": "configure"
+  }
+}

programming_language: JavaScript
filename: spec.json
change_type: ModificationType.MODIFY
diff: @@ -4,7 +4,6 @@
   "description": "Automatically publish articles to Medium",
   "permissions": ["contentGroups:read", "contentPieces:read", "webhooks:read", "webhooks:write"],
   "lifecycle": {
-    "on:install": "install",
     "on:uninstall": "uninstall",
     "on:configure": "configure",
     "on:initConfigurationView": "initConfigurationView",

programming_language: JavaScript
filename: package.json
change_type: ModificationType.MODIFY
diff: @@ -1,6 +1,6 @@
 {
   "name": "@vrite/sdk",
-  "version": "0.2.0",
+  "version": "0.3.0",
   "private": false,
   "description": "JavaScript SDK and API client for Vrite - headless CMS for technical content",
   "license": "MIT",

programming_language: TypeScript
filename: client.ts
change_type: ModificationType.MODIFY
diff: @@ -1,5 +1,9 @@
 import { createContentGroupsEndpoints, ContentGroupsEndpoints } from "./content-groups";
-import { ContentPiecesEndpoints, createContentPiecesEndpoints } from "./content-pieces";
+import {
+  ContentPiece,
+  ContentPiecesEndpoints,
+  createContentPiecesEndpoints
+} from "./content-pieces";
 import { APIFetcherConfig, createAPIFetcher } from "./request";
 import { UserSettingsEndpoints, createUserSettingsEndpoints } from "./user-settings";
 import { TagsEndpoints, createTagsEndpoints } from "./tags";
@@ -17,6 +21,12 @@ import { VariantsEndpoints, createVariantsEndpoints } from "./variants";
 import { TransformersEndpoints, createTransformersEndpoints } from "./transformers";
 import PolyfilledEventSource from "@sanity/eventsource";
 
+interface SearchResult {
+  contentPieceId: string;
+  contentPiece: Omit<ContentPiece, "locked" | "content" | "coverWidth">;
+  breadcrumb: string[];
+  content: string;
+}
 interface ClientConfig extends APIFetcherConfig {}
 interface Client {
   contentGroups: ContentGroupsEndpoints;
@@ -36,27 +46,21 @@ interface Client {
     query: string;
     limit?: number;
     variantId?: string;
-    contentPieceID?: string;
-  }): Promise<
-    Array<{
-      contentPieceId: string;
-      breadcrumb: string[];
-      content: string;
-    }>
-  >;
+    contentPieceId?: string;
+  }): Promise<SearchResult[]>;
   ask(input: {
     query: string;
     onChunk?(chunk: string, content: string): void;
     onEnd?(content: string): void;
     onError?(error: string): void;
   }): void;
-  reconfigure(config: ClientConfig): void;
+  useSignal(signal: AbortSignal | null): Client;
+  reconfigure(config: ClientConfig): Client;
 }
 
 const createClient = (config: ClientConfig): Client => {
-  const { sendRequest, reconfigure, getConfig } = createAPIFetcher(config);
-
-  return {
+  const { sendRequest, reconfigure, getConfig, getSignal, useSignal } = createAPIFetcher(config);
+  const client: Client = {
     contentGroups: createContentGroupsEndpoints(sendRequest),
     contentPieces: createContentPiecesEndpoints(sendRequest),
     tags: createTagsEndpoints(sendRequest),
@@ -102,10 +106,25 @@ const createClient = (config: ClientConfig): Client => {
         content += chunk;
         input.onChunk?.(chunk, content);
       });
+      getSignal()?.addEventListener("abort", () => {
+        source.close();
+      });
+      useSignal(null);
     },
-    reconfigure
+    useSignal(signal) {
+      useSignal(signal);
+
+      return client;
+    },
+    reconfigure(config) {
+      reconfigure(config);
+
+      return client;
+    }
   };
+
+  return client;
 };
 
 export { createClient };
-export type { Client };
+export type { Client, SearchResult };

programming_language: TypeScript
filename: index.ts
change_type: ModificationType.MODIFY
diff: @@ -1,5 +1,5 @@
 export { createClient } from "./client";
-export type { Client } from "./client";
+export type { Client, SearchResult } from "./client";
 export type { ContentGroup } from "./content-groups";
 export type {
   ContentPiece,

programming_language: TypeScript
filename: request.ts
change_type: ModificationType.MODIFY
diff: @@ -19,13 +19,16 @@ type PaginationParams = {
 interface APIFetcher {
   sendRequest: SendRequest;
   reconfigure: (config: APIFetcherConfig) => void;
+  useSignal: (signal: AbortSignal | null) => void;
   getConfig: () => Required<APIFetcherConfig>;
+  getSignal: () => AbortSignal | null;
 }
 
 const createAPIFetcher = (config: APIFetcherConfig): APIFetcher => {
   let baseURL = config.baseURL || "https://api.vrite.io";
   let extensionId = config.extensionId || "";
   let headers = config.headers || {};
+  let signal: AbortSignal | null = null;
   let { token } = config;
 
   const sendRequest: SendRequest = async (method, path, options) => {
@@ -49,10 +52,13 @@ const createAPIFetcher = (config: APIFetcherConfig): APIFetcher => {
             ...headers
           },
           body: options?.body ? JSON.stringify(options.body) : null,
+          signal,
           method
         }
       );
 
+      signal = null;
+
       let json = null;
 
       try {
@@ -81,6 +87,9 @@ const createAPIFetcher = (config: APIFetcherConfig): APIFetcher => {
     extensionId = config.extensionId || extensionId;
     headers = config.headers || headers;
   };
+  const useSignal = (newSignal: AbortSignal | null): void => {
+    signal = newSignal;
+  };
   const getConfig = (): Required<APIFetcherConfig> => {
     return {
       baseURL,
@@ -89,8 +98,11 @@ const createAPIFetcher = (config: APIFetcherConfig): APIFetcher => {
       headers
     };
   };
+  const getSignal = (): AbortSignal | null => {
+    return signal;
+  };
 
-  return { sendRequest, reconfigure, getConfig };
+  return { sendRequest, reconfigure, useSignal, getConfig, getSignal };
 };
 
 export { createAPIFetcher };

programming_language: TypeScript
filename: content-walker.ts
change_type: ModificationType.MODIFY
diff: @@ -85,7 +85,7 @@ type BlockquoteNode = {
     | ParagraphNode
     | HeadingNode
     | BlockquoteNode
-    | WrapperNode
+    | ElementNode
     | ImageNode
     | CodeBlockNode
     | EmbedNode
@@ -96,16 +96,17 @@ type BlockquoteNode = {
     | TableNode
   >;
 };
-type WrapperNode = {
-  type: "wrapper";
-  attrs?: {
-    key?: string;
+type ElementNode = {
+  type: "element";
+  attrs: {
+    type: string;
+    props: Record<string, any>;
   };
   content?: Array<
     | ParagraphNode
     | HeadingNode
     | BlockquoteNode
-    | WrapperNode
+    | ElementNode
     | ImageNode
     | CodeBlockNode
     | EmbedNode
@@ -126,7 +127,9 @@ type ImageNode = {
 type CodeBlockNode = {
   type: "codeBlock";
   attrs?: {
-    lang: string;
+    lang?: string;
+    meta?: string;
+    title?: string;
   };
   content: TextNode[];
 };
@@ -219,7 +222,7 @@ type DocNode = {
     | ParagraphNode
     | HeadingNode
     | BlockquoteNode
-    | WrapperNode
+    | ElementNode
     | ImageNode
     | CodeBlockNode
     | EmbedNode
@@ -237,7 +240,7 @@ type JSONContentNode = {
   paragraph: ParagraphNode;
   heading: HeadingNode;
   blockquote: BlockquoteNode;
-  wrapper: WrapperNode;
+  element: ElementNode;
   image: ImageNode;
   codeBlock: CodeBlockNode;
   embed: EmbedNode;

programming_language: TypeScript
filename: output-transformers.ts
change_type: ModificationType.MODIFY
diff: @@ -111,7 +111,7 @@ const gfmOutputTransformer = createOutputTransformer<string>((contentNode) => {
   };
   const transformContentNode = (
     nodeWalker: JSONContentNodeWalker<
-      JSONContentNode["listItem" | "taskItem" | "blockquote" | "doc" | "wrapper"]
+      JSONContentNode["listItem" | "taskItem" | "blockquote" | "doc" | "element"]
     >
   ): string => {
     return nodeWalker.children
@@ -151,9 +151,9 @@ const gfmOutputTransformer = createOutputTransformer<string>((contentNode) => {
             return `\n\`\`\`${child.node.attrs?.lang || ""}\n${transformTextNode(
               child as JSONContentNodeWalker<JSONContentNode["codeBlock"]>
             )}\n\`\`\`\n`;
-          case "wrapper":
+          case "element":
             return `\n${transformContentNode(
-              child as JSONContentNodeWalker<JSONContentNode["wrapper"]>
+              child as JSONContentNodeWalker<JSONContentNode["element"]>
             )}\n`;
           case "blockquote":
             return `\n${transformContentNode(
@@ -325,10 +325,10 @@ const htmlOutputTransformer = createOutputTransformer<string>((contentNode) => {
         })} />${(nodeWalker as JSONContentNodeWalker<JSONContentNode["taskItem"]>).children
           .map(transformContentNode)
           .join("")}</label></li>`;
-      case "wrapper":
+      case "element":
         return `<div ${stringifyAttributes({
-          "data-key": nodeWalker.node.attrs?.key
-        })}>${(nodeWalker as JSONContentNodeWalker<JSONContentNode["wrapper"]>).children
+          "data-type": nodeWalker.node.attrs?.type
+        })}>${(nodeWalker as JSONContentNodeWalker<JSONContentNode["element"]>).children
           .map(transformContentNode)
           .join("")}</div>`;
       case "blockquote":

programming_language: TypeScript
filename: pnpm-lock.yaml
change_type: ModificationType.MODIFY
diff: @@ -10,10 +10,10 @@ importers:
     devDependencies:
       '@typescript-eslint/eslint-plugin':
         specifier: ^6.2.0
-        version: 6.2.0(@typescript-eslint/parser@6.2.0)(eslint@8.45.0)(typescript@5.1.6)
+        version: 6.2.0(@typescript-eslint/parser@6.2.0)(eslint@8.45.0)(typescript@5.2.2)
       '@typescript-eslint/parser':
         specifier: ^6.2.0
-        version: 6.2.0(eslint@8.45.0)(typescript@5.1.6)
+        version: 6.2.0(eslint@8.45.0)(typescript@5.2.2)
       eslint:
         specifier: ^8.45.0
         version: 8.45.0
@@ -22,13 +22,13 @@ importers:
         version: 8.8.0(eslint@8.45.0)
       eslint-config-xtrict:
         specifier: ^3.0.1
-        version: 3.0.1(eslint@8.45.0)(prettier@3.0.2)(typescript@5.1.6)
+        version: 3.0.1(eslint@8.45.0)(prettier@3.0.2)(typescript@5.2.2)
       eslint-plugin-import:
         specifier: ^2.27.5
         version: 2.27.5(@typescript-eslint/parser@6.2.0)(eslint@8.45.0)
       eslint-plugin-solid:
         specifier: ^0.12.1
-        version: 0.12.1(eslint@8.45.0)(typescript@5.1.6)
+        version: 0.12.1(eslint@8.45.0)(typescript@5.2.2)
       prettier:
         specifier: ^3.0.2
         version: 3.0.2
@@ -40,7 +40,7 @@ importers:
         version: 1.10.11
       typescript:
         specifier: ^5.1.6
-        version: 5.1.6
+        version: 5.2.2
 
   apps/backend/api:
     dependencies:
@@ -61,7 +61,7 @@ importers:
         version: 4.20.0
       trpc-openapi:
         specifier: ^1.2.0
-        version: 1.2.0(@trpc/server@10.35.0)(zod@3.22.2)
+        version: 1.2.0(@trpc/server@10.35.0)(zod@3.22.4)
     devDependencies:
       '@vrite/scripts':
         specifier: workspace:*
@@ -138,7 +138,7 @@ importers:
         version: 0.32.5
       trpc-openapi:
         specifier: ^1.2.0
-        version: 1.2.0(@trpc/server@10.35.0)(zod@3.22.2)
+        version: 1.2.0(@trpc/server@10.35.0)(zod@3.22.4)
     devDependencies:
       '@vrite/scripts':
         specifier: workspace:*
@@ -183,24 +183,90 @@ importers:
       '@fastify/cors':
         specifier: ^8.3.0
         version: 8.3.0
+      '@prettier/sync':
+        specifier: ^0.3.0
+        version: 0.3.0(prettier@3.0.2)
       '@trpc/server':
         specifier: ^10.35.0
         version: 10.35.0
+      '@types/hast':
+        specifier: ^3.0.1
+        version: 3.0.1
+      '@types/html-to-text':
+        specifier: ^9.0.1
+        version: 9.0.1
+      '@types/js-yaml':
+        specifier: ^4.0.6
+        version: 4.0.6
+      '@types/mdast':
+        specifier: ^4.0.1
+        version: 4.0.1
       '@vrite/backend':
         specifier: workspace:*
         version: link:../../../packages/backend
       '@vrite/sdk':
         specifier: workspace:*
         version: link:../../../packages/sdk/javascript
+      dayjs:
+        specifier: ^1.11.9
+        version: 1.11.9
       fastify:
         specifier: ^4.20.0
         version: 4.20.0
+      hast-util-to-html:
+        specifier: ^9.0.0
+        version: 9.0.0
+      html-to-text:
+        specifier: ^9.0.5
+        version: 9.0.5
+      js-yaml:
+        specifier: ^4.1.0
+        version: 4.1.0
+      mdast-util-from-markdown:
+        specifier: ^2.0.0
+        version: 2.0.0
+      mdast-util-frontmatter:
+        specifier: ^2.0.1
+        version: 2.0.1
+      mdast-util-gfm:
+        specifier: ^3.0.0
+        version: 3.0.0
+      mdast-util-mdx:
+        specifier: ^3.0.0
+        version: 3.0.0
+      mdast-util-to-hast:
+        specifier: ^13.0.2
+        version: 13.0.2
+      micromark-extension-frontmatter:
+        specifier: ^2.0.0
+        version: 2.0.0
+      micromark-extension-gfm:
+        specifier: ^3.0.0
+        version: 3.0.0
+      micromark-extension-mdxjs:
+        specifier: ^2.0.0
+        version: 2.0.0
       openai:
         specifier: ^4.0.0
         version: 4.0.0
+      prettier:
+        specifier: ^3.0.2
+        version: 3.0.2
+      remark:
+        specifier: ^15.0.1
+        version: 15.0.1
+      remark-mdx:
+        specifier: ^2.3.0
+        version: 2.3.0
+      remark-parse:
+        specifier: ^11.0.0
+        version: 11.0.0
       trpc-openapi:
         specifier: ^1.2.0
-        version: 1.2.0(@trpc/server@10.35.0)(zod@3.22.2)
+        version: 1.2.0(@trpc/server@10.35.0)(zod@3.22.4)
+      unist-util-visit:
+        specifier: ^5.0.0
+        version: 5.0.0
     devDependencies:
       '@vrite/scripts':
         specifier: workspace:*
@@ -208,6 +274,9 @@ importers:
 
   apps/docs:
     dependencies:
+      '@astrojs/mdx':
+        specifier: ^1.1.1
+        version: 1.1.1(astro@3.1.0)
       '@astrojs/sitemap':
         specifier: ^3.0.0
         version: 3.0.0
@@ -217,6 +286,9 @@ importers:
       '@mdi/js':
         specifier: ^7.2.96
         version: 7.2.96
+      '@solid-primitives/scheduled':
+        specifier: ^1.4.0
+        version: 1.4.0(solid-js@1.7.11)
       '@types/marked':
         specifier: ^5.0.1
         version: 5.0.1
@@ -226,9 +298,18 @@ importers:
       '@vrite/components':
         specifier: workspace:*
         version: link:../../packages/components
+      '@vrite/sdk':
+        specifier: workspace:*
+        version: link:../../packages/sdk/javascript
       astro:
         specifier: ^3.1.0
         version: 3.1.0(sass@1.64.1)
+      astro-auto-import:
+        specifier: ^0.3.1
+        version: 0.3.1(astro@3.1.0)
+      astro-icon:
+        specifier: ^0.8.1
+        version: 0.8.1
       clsx:
         specifier: ^2.0.0
         version: 2.0.0
@@ -247,21 +328,30 @@ importers:
       plausible-tracker:
         specifier: ^0.3.8
         version: 0.3.8
+      seamless-scroll-polyfill:
+        specifier: ^2.3.4
+        version: 2.3.4
       shiki:
         specifier: ^0.14.4
         version: 0.14.4
       solid-js:
         specifier: ^1.7.11
         version: 1.7.11
+      tinykeys:
+        specifier: ^2.1.0
+        version: 2.1.0
       typescript:
         specifier: ^5.2.2
         version: 5.2.2
       unocss:
         specifier: ^0.55.7
-        version: 0.55.7(postcss@8.4.29)(vite@4.4.9)
+        version: 0.55.7(postcss@8.4.31)(vite@4.4.9)
+      url-slug:
+        specifier: ^4.0.1
+        version: 4.0.1
       vite:
         specifier: ^4.4.9
-        version: 4.4.9(sass@1.64.1)
+        version: 4.4.9(@types/node@20.4.4)(sass@1.64.1)(terser@5.19.2)
     devDependencies:
       '@astrojs/node':
         specifier: ^6.0.0
@@ -283,7 +373,7 @@ importers:
         version: 2.0.2
       '@astrojs/solid-js':
         specifier: ^2.2.1
-        version: 2.2.1(@babel/core@7.22.15)(solid-js@1.7.11)(vite@4.4.9)
+        version: 2.2.1(@babel/core@7.23.0)(solid-js@1.7.11)(vite@4.4.9)
       '@fontsource/nunito':
         specifier: ^5.0.8
         version: 5.0.8
@@ -334,10 +424,10 @@ importers:
         version: 5.2.2
       unocss:
         specifier: ^0.55.7
-        version: 0.55.7(postcss@8.4.29)(vite@4.4.9)
+        version: 0.55.7(postcss@8.4.31)(vite@4.4.9)
       vite:
         specifier: ^4.4.9
-        version: 4.4.9(sass@1.64.1)
+        version: 4.4.9(@types/node@20.4.4)(sass@1.64.1)(terser@5.19.2)
     devDependencies:
       astro-robots-txt:
         specifier: ^0.4.1
@@ -359,28 +449,28 @@ importers:
         version: 2.0.1
       '@motionone/solid':
         specifier: ^10.16.2
-        version: 10.16.2(solid-js@1.7.8)
+        version: 10.16.2(solid-js@1.7.11)
       '@octokit/rest':
         specifier: ^20.0.1
         version: 20.0.1
       '@solid-primitives/active-element':
         specifier: ^2.0.15
-        version: 2.0.15(solid-js@1.7.8)
+        version: 2.0.15(solid-js@1.7.11)
       '@solid-primitives/connectivity':
         specifier: ^0.3.15
-        version: 0.3.15(solid-js@1.7.8)
+        version: 0.3.15(solid-js@1.7.11)
       '@solid-primitives/media':
         specifier: ^2.2.3
-        version: 2.2.3(solid-js@1.7.8)
+        version: 2.2.3(solid-js@1.7.11)
       '@solid-primitives/memo':
         specifier: ^1.3.2
-        version: 1.3.2(solid-js@1.7.8)
+        version: 1.3.2(solid-js@1.7.11)
       '@solid-primitives/scheduled':
         specifier: ^1.4.0
-        version: 1.4.0(solid-js@1.7.8)
+        version: 1.4.0(solid-js@1.7.11)
       '@solidjs/router':
         specifier: ^0.8.2
-        version: 0.8.2(solid-js@1.7.8)
+        version: 0.8.2(solid-js@1.7.11)
       '@tiptap/core':
         specifier: 2.1.8
         version: 2.1.8(@tiptap/pm@2.1.8)
@@ -452,7 +542,7 @@ importers:
         version: link:../../packages/sdk/javascript
       '@vrite/tiptap-solid':
         specifier: 1.0.0
-        version: 1.0.0(@tiptap/core@2.1.8)(@tiptap/pm@2.1.8)(solid-js@1.7.8)
+        version: 1.0.0(@tiptap/core@2.1.8)(@tiptap/pm@2.1.8)(solid-js@1.7.11)
       clsx:
         specifier: ^2.0.0
         version: 2.0.0
@@ -469,8 +559,8 @@ importers:
         specifier: ^6.1.0
         version: 6.1.0
       monaco-editor:
-        specifier: ^0.40.0
-        version: 0.40.0
+        specifier: ^0.43.0
+        version: 0.43.0
       nanoevents:
         specifier: ^8.0.0
         version: 8.0.0
@@ -485,7 +575,7 @@ importers:
         version: 2.3.4
       solid-js:
         specifier: ^1.7.8
-        version: 1.7.8
+        version: 1.7.11
       sortablejs:
         specifier: ^1.15.0
         version: 1.15.0
@@ -500,7 +590,7 @@ importers:
         version: 4.0.1
       y-prosemirror:
         specifier: ^1.2.1
-        version: 1.2.1(prosemirror-model@1.19.2)(prosemirror-state@1.4.3)(prosemirror-view@1.31.4)(y-protocols@1.0.5)(yjs@13.6.7)
+        version: 1.2.1(prosemirror-model@1.19.3)(prosemirror-state@1.4.3)(prosemirror-view@1.32.0)(y-protocols@1.0.5)(yjs@13.6.7)
       yjs:
         specifier: ^13.6.7
         version: 13.6.7
@@ -519,19 +609,19 @@ importers:
         version: 5.19.2
       typescript:
         specifier: ^5.1.6
-        version: 5.1.6
+        version: 5.2.2
       unocss:
         specifier: ^0.55.7
-        version: 0.55.7(postcss@8.4.29)(vite@4.4.7)
+        version: 0.55.7(postcss@8.4.31)(vite@4.4.9)
       vite:
         specifier: ^4.4.7
-        version: 4.4.7(@types/node@20.4.4)(sass@1.64.1)(terser@5.19.2)
+        version: 4.4.9(@types/node@20.4.4)(sass@1.64.1)(terser@5.19.2)
       vite-plugin-solid:
         specifier: ^2.7.0
-        version: 2.7.0(solid-js@1.7.8)(vite@4.4.7)
+        version: 2.7.0(solid-js@1.7.11)(vite@4.4.9)
       vite-tsconfig-paths:
         specifier: ^4.2.0
-        version: 4.2.0(typescript@5.1.6)(vite@4.4.7)
+        version: 4.2.0(typescript@5.2.2)(vite@4.4.9)
 
   packages/backend:
     dependencies:
@@ -579,7 +669,7 @@ importers:
         version: 11.1.0
       '@qdrant/qdrant-js':
         specifier: ^1.4.0
-        version: 1.4.0(typescript@5.1.6)
+        version: 1.4.0(typescript@5.2.2)
       '@sendgrid/mail':
         specifier: ^7.7.0
         version: 7.7.0
@@ -669,13 +759,13 @@ importers:
         version: 1.2.0(@trpc/server@10.35.0)(zod@3.21.4)
       typescript:
         specifier: ^5.1.6
-        version: 5.1.6
+        version: 5.2.2
       url-slug:
         specifier: ^4.0.1
         version: 4.0.1
       weaviate-ts-client:
         specifier: ^1.4.0
-        version: 1.4.0(graphql@16.7.1)
+        version: 1.4.0(graphql@16.8.1)
       yjs:
         specifier: ^13.6.7
         version: 13.6.7
@@ -700,16 +790,16 @@ importers:
         version: 7.2.96
       '@solid-primitives/active-element':
         specifier: ^2.0.15
-        version: 2.0.15(solid-js@1.7.8)
+        version: 2.0.15(solid-js@1.7.11)
       '@solid-primitives/media':
         specifier: ^2.2.3
-        version: 2.2.3(solid-js@1.7.8)
+        version: 2.2.3(solid-js@1.7.11)
       clsx:
         specifier: ^2.0.0
         version: 2.0.0
       solid-js:
         specifier: ^1.7.8
-        version: 1.7.8
+        version: 1.7.11
 
   packages/editor:
     dependencies:
@@ -739,7 +829,7 @@ importers:
         version: 2.1.8(@tiptap/core@2.1.8)
       '@tiptap/extension-code-block-lowlight':
         specifier: ^2.1.8
-        version: 2.1.8(@tiptap/core@2.1.8)(@tiptap/extension-code-block@2.0.3)(@tiptap/pm@2.1.8)
+        version: 2.1.8(@tiptap/core@2.1.8)(@tiptap/extension-code-block@2.1.11)(@tiptap/pm@2.1.8)
       '@tiptap/extension-collaboration':
         specifier: ^2.1.8
         version: 2.1.8(@tiptap/core@2.1.8)(@tiptap/pm@2.1.8)(y-prosemirror@1.0.20)
@@ -829,7 +919,7 @@ importers:
         version: 2.0.0
       solid-js:
         specifier: ^1.7.8
-        version: 1.7.8
+        version: 1.7.11
       url-slug:
         specifier: ^4.0.1
         version: 4.0.1
@@ -906,13 +996,13 @@ importers:
     devDependencies:
       astro:
         specifier: ^2.9.2
-        version: 2.9.2
+        version: 2.10.15
       unbuild:
         specifier: ^1.2.1
         version: 1.2.1
       vite:
         specifier: ^4.4.7
-        version: 4.4.7(@types/node@20.4.4)(sass@1.64.1)(terser@5.19.2)
+        version: 4.4.9(@types/node@20.4.4)(sass@1.64.1)(terser@5.19.2)
 
 packages:
 
@@ -926,7 +1016,7 @@ packages:
     engines: {node: '>=6.0.0'}
     dependencies:
       '@jridgewell/gen-mapping': 0.3.3
-      '@jridgewell/trace-mapping': 0.3.18
+      '@jridgewell/trace-mapping': 0.3.19
 
   /@antfu/install-pkg@0.1.1:
     resolution: {integrity: sha512-LyB/8+bSfa0DFGC06zpCEfs89/XoWZwws5ygEa5D+Xsm3OfI+aXQ86VgVG7Acyef+rSZ5HE7J8rrxzrQeM3PjQ==}
@@ -937,23 +1027,14 @@ packages:
   /@antfu/utils@0.7.6:
     resolution: {integrity: sha512-pvFiLP2BeOKA/ZOS6jxx4XhKzdVLHDhGlFEaZ2flWWYf2xOqVniqpk38I04DFRyz+L0ASggl7SkItTc+ZLju4w==}
 
-  /@astrojs/compiler@1.6.2:
-    resolution: {integrity: sha512-2grH0lSm/Su88ZUd1kF0OdR/CT4ClWKvCwVz4yDdpgLgpzXhs1LdO2V58YfSqnx/z+G5EBWv6yEkp3tDG3GQYQ==}
-    dev: true
-
   /@astrojs/compiler@1.8.2:
     resolution: {integrity: sha512-o/ObKgtMzl8SlpIdzaxFnt7SATKPxu4oIP/1NL+HDJRzxfJcAkOTAb/ZKMRyULbz4q+1t2/DAebs2Z1QairkZw==}
 
-  /@astrojs/compiler@2.1.0:
-    resolution: {integrity: sha512-Mp+qrNhly+27bL/Zq8lGeUY+YrdoU0eDfIlAeGIPrzt0PnI/jGpvPUdCaugv4zbCrDkOUScFfcbeEiYumrdJnw==}
-
-  /@astrojs/internal-helpers@0.1.1:
-    resolution: {integrity: sha512-+LySbvFbjv2nO2m/e78suleQOGEru4Cnx73VsZbrQgB2u7A4ddsQg3P2T0zC0e10jgcT+c6nNlKeLpa6nRhQIg==}
-    dev: true
+  /@astrojs/compiler@2.2.0:
+    resolution: {integrity: sha512-JvmckEJgg8uXUw8Rs6VZDvN7LcweCHOdcxsCXpC+4KMDC9FaB5t9EH/NooSE+hu/rnACEhsXA3FKmf9wnhb7hA==}
 
   /@astrojs/internal-helpers@0.1.2:
     resolution: {integrity: sha512-YXLk1CUDdC9P5bjFZcGjz+cE/ZDceXObDTXn/GCID4r8LjThuexxi+dlJqukmUpkSItzQqgzfWnrPLxSFPejdA==}
-    dev: false
 
   /@astrojs/internal-helpers@0.2.0:
     resolution: {integrity: sha512-NQ4ppp1CM0HNkKbJNM4saVSfmUYzGlRalF6wx7F6T/MYHYSWGuojY89/oFTy4t8VlOGUCUijlsVNNeziWaUo5g==}
@@ -963,18 +1044,18 @@ packages:
     hasBin: true
     dependencies:
       '@astrojs/compiler': 1.8.2
-      '@jridgewell/trace-mapping': 0.3.18
-      '@vscode/emmet-helper': 2.8.9
+      '@jridgewell/trace-mapping': 0.3.19
+      '@vscode/emmet-helper': 2.9.2
       events: 3.3.0
       prettier: 2.8.8
       prettier-plugin-astro: 0.9.1
-      vscode-css-languageservice: 6.2.6
-      vscode-html-languageservice: 5.0.6
+      vscode-css-languageservice: 6.2.9
+      vscode-html-languageservice: 5.1.0
       vscode-languageserver: 8.1.0
-      vscode-languageserver-protocol: 3.17.3
-      vscode-languageserver-textdocument: 1.0.8
-      vscode-languageserver-types: 3.17.3
-      vscode-uri: 3.0.7
+      vscode-languageserver-protocol: 3.17.5
+      vscode-languageserver-textdocument: 1.0.11
+      vscode-languageserver-types: 3.17.5
+      vscode-uri: 3.0.8
 
   /@astrojs/markdown-remark@2.2.1(astro@2.10.15):
     resolution: {integrity: sha512-VF0HRv4GpC1XEMLnsKf6jth7JSmlt9qpqP0josQgA2eSpCIAC/Et+y94mgdBIZVBYH/yFnMoIxgKVe93xfO2GA==}
@@ -997,17 +1078,17 @@ packages:
       vfile: 5.3.7
     transitivePeerDependencies:
       - supports-color
-    dev: false
 
-  /@astrojs/markdown-remark@2.2.1(astro@2.9.2):
-    resolution: {integrity: sha512-VF0HRv4GpC1XEMLnsKf6jth7JSmlt9qpqP0josQgA2eSpCIAC/Et+y94mgdBIZVBYH/yFnMoIxgKVe93xfO2GA==}
+  /@astrojs/markdown-remark@3.2.0(astro@3.1.0):
+    resolution: {integrity: sha512-jigyLfefUZPKgVmmraCkVpdUuFH1R3SrpgQO13axsgwLDBgkggaQpNR5Ag4O9PDualeBtbdt30aYSfvnBKx9Hg==}
     peerDependencies:
-      astro: ^2.5.0
+      astro: ^3.1.0
     dependencies:
-      '@astrojs/prism': 2.1.2
-      astro: 2.9.2
-      github-slugger: 1.5.0
-      import-meta-resolve: 2.2.2
+      '@astrojs/prism': 3.0.0
+      astro: 3.1.0(sass@1.64.1)
+      github-slugger: 2.0.0
+      import-meta-resolve: 3.0.0
+      mdast-util-definitions: 6.0.0
       rehype-raw: 6.1.1
       rehype-stringify: 9.0.4
       remark-gfm: 3.0.1
@@ -1020,12 +1101,11 @@ packages:
       vfile: 5.3.7
     transitivePeerDependencies:
       - supports-color
-    dev: true
 
-  /@astrojs/markdown-remark@3.2.0(astro@3.1.0):
-    resolution: {integrity: sha512-jigyLfefUZPKgVmmraCkVpdUuFH1R3SrpgQO13axsgwLDBgkggaQpNR5Ag4O9PDualeBtbdt30aYSfvnBKx9Hg==}
+  /@astrojs/markdown-remark@3.2.1(astro@3.1.0):
+    resolution: {integrity: sha512-Z4YNMRtgFZeHhB29uCZl0B9MbMZddW9ZKCNucapoysbvygbDFF1gGtqpVnf+Lyv3rUBHwM/J5qWB2MSZuTuz1g==}
     peerDependencies:
-      astro: ^3.1.0
+      astro: ^3.2.3
     dependencies:
       '@astrojs/prism': 3.0.0
       astro: 3.1.0(sass@1.64.1)
@@ -1044,6 +1124,33 @@ packages:
       vfile: 5.3.7
     transitivePeerDependencies:
       - supports-color
+    dev: false
+
+  /@astrojs/mdx@1.1.1(astro@3.1.0):
+    resolution: {integrity: sha512-3dfL12ZqI6NCjx0iVOYVSyljlVgsxds5mOhe78xoCVjyqSpZZsxzz4Dt5WfGxDon2nc2bD6XGiZ2PIy8fmX6NQ==}
+    engines: {node: '>=18.14.1'}
+    peerDependencies:
+      astro: ^3.2.3
+    dependencies:
+      '@astrojs/markdown-remark': 3.2.1(astro@3.1.0)
+      '@mdx-js/mdx': 2.3.0
+      acorn: 8.10.0
+      astro: 3.1.0(sass@1.64.1)
+      es-module-lexer: 1.3.1
+      estree-util-visit: 1.2.1
+      github-slugger: 2.0.0
+      gray-matter: 4.0.3
+      hast-util-to-html: 8.0.4
+      kleur: 4.1.5
+      rehype-raw: 6.1.1
+      remark-gfm: 3.0.1
+      remark-smartypants: 2.0.0
+      source-map: 0.7.4
+      unist-util-visit: 4.1.2
+      vfile: 5.3.7
+    transitivePeerDependencies:
+      - supports-color
+    dev: false
 
   /@astrojs/node@6.0.0(astro@3.1.0):
     resolution: {integrity: sha512-06x5UBt+g0EIUpOdtCdnTxRJhOTLxUnjzmGwIHp9RNBlIEpzd/dJs6pwvfiM2zuPolTLI53T8VOsdw3EMh2V+w==}
@@ -1073,7 +1180,7 @@ packages:
     resolution: {integrity: sha512-dFWtdFwN8kxDiqIxF8T8ODqsUr6hG+EQlFEqm+3oQkhAkucF9QkYLM5Q72mEbYytkL4jvKyHbW1u10T5sWBZew==}
     dependencies:
       sitemap: 7.1.1
-      zod: 3.22.2
+      zod: 3.21.4
     dev: false
 
   /@astrojs/sitemap@3.0.0:
@@ -1083,13 +1190,13 @@ packages:
       zod: 3.21.1
     dev: false
 
-  /@astrojs/solid-js@2.2.1(@babel/core@7.22.15)(solid-js@1.7.11)(vite@4.4.9):
+  /@astrojs/solid-js@2.2.1(@babel/core@7.23.0)(solid-js@1.7.11)(vite@4.4.9):
     resolution: {integrity: sha512-LJRKX1raHePOWE5lL7OjYvtap/S4fQoZLPB0pVw6RKUJtCeRIYD44x5DxFk52dFCkjnlVuWFlQkvtefT8kotcQ==}
     engines: {node: '>=16.12.0'}
     peerDependencies:
       solid-js: ^1.4.3
     dependencies:
-      babel-preset-solid: 1.7.7(@babel/core@7.22.15)
+      babel-preset-solid: 1.7.12(@babel/core@7.23.0)
       solid-js: 1.7.11
       vitefu: 0.2.4(vite@4.4.9)
     transitivePeerDependencies:
@@ -1114,13 +1221,13 @@ packages:
     resolution: {integrity: sha512-4pRhyeQr0MLB5PKYgkdu+YE8sSpMbHL8dUuslBWBIdgcYjtD1SufPMBI8pgXJ+xlwrQJHKKfK2X1KonHYuOS9A==}
     engines: {node: '>=16.12.0'}
     dependencies:
-      ci-info: 3.8.0
+      ci-info: 3.9.0
       debug: 4.3.4
       dlv: 1.1.3
       dset: 3.1.2
       is-docker: 3.0.0
       is-wsl: 2.2.0
-      undici: 5.23.0
+      undici: 5.25.4
       which-pm-runs: 1.1.0
     transitivePeerDependencies:
       - supports-color
@@ -1129,13 +1236,13 @@ packages:
     resolution: {integrity: sha512-7zJMuikRDQ0LLLivteu0+y4pqdgznrChFiRrY3qmKlOEkLWD1T3u1a5M970lvpErP7Vgh4P298JBPjv8LTj+sw==}
     engines: {node: '>=18.14.1'}
     dependencies:
-      ci-info: 3.8.0
+      ci-info: 3.9.0
       debug: 4.3.4
       dlv: 1.1.3
       dset: 3.1.2
       is-docker: 3.0.0
-      is-wsl: 3.0.0
-      undici: 5.23.0
+      is-wsl: 3.1.0
+      undici: 5.25.4
       which-pm-runs: 1.1.0
     transitivePeerDependencies:
       - supports-color
@@ -1143,7 +1250,7 @@ packages:
   /@astrojs/webapi@2.2.0:
     resolution: {integrity: sha512-mHAOApWyjqSe5AQMOUD9rsZJqbMQqe3Wosb1a40JV6Okvyxj1G6GTlthwYadWCymq/lbgwh0PLiY8Fr4eFxtuQ==}
     dependencies:
-      undici: 5.23.0
+      undici: 5.25.4
 
   /@aws-crypto/crc32@3.0.0:
     resolution: {integrity: sha512-IzSgsrxUcsrejQbPVilIKy16kAT52EwB6zSaI+M3xxIhKh5+aldEyvI+z6erM7TCLB2BJsFrtHjp6/4/sr+3dA==}
@@ -1271,7 +1378,7 @@ packages:
       '@smithy/util-utf8': 1.1.0
       '@smithy/util-waiter': 1.1.0
       fast-xml-parser: 4.2.5
-      tslib: 2.5.3
+      tslib: 2.6.2
     transitivePeerDependencies:
       - '@aws-sdk/signature-v4-crt'
       - aws-crt
@@ -1313,7 +1420,7 @@ packages:
       '@smithy/util-defaults-mode-node': 1.1.0
       '@smithy/util-retry': 1.1.0
       '@smithy/util-utf8': 1.1.0
-      tslib: 2.5.3
+      tslib: 2.6.2
     transitivePeerDependencies:
       - aws-crt
     dev: false
@@ -1354,7 +1461,7 @@ packages:
       '@smithy/util-defaults-mode-node': 1.1.0
       '@smithy/util-retry': 1.1.0
       '@smithy/util-utf8': 1.1.0
-      tslib: 2.5.3
+      tslib: 2.6.2
     transitivePeerDependencies:
       - aws-crt
     dev: false
@@ -1399,7 +1506,7 @@ packages:
       '@smithy/util-retry': 1.1.0
       '@smithy/util-utf8': 1.1.0
       fast-xml-parser: 4.2.5
-      tslib: 2.5.3
+      tslib: 2.6.2
     transitivePeerDependencies:
       - aws-crt
     dev: false
@@ -1411,7 +1518,7 @@ packages:
       '@aws-sdk/types': 3.370.0
       '@smithy/property-provider': 1.2.0
       '@smithy/types': 1.2.0
-      tslib: 2.5.3
+      tslib: 2.6.2
     dev: false
 
   /@aws-sdk/credential-provider-ini@3.370.0:
@@ -1427,7 +1534,7 @@ packages:
       '@smithy/property-provider': 1.2.0
       '@smithy/shared-ini-file-loader': 1.1.0
       '@smithy/types': 1.2.0
-      tslib: 2.5.3
+      tslib: 2.6.2
     transitivePeerDependencies:
       - aws-crt
     dev: false
@@ -1446,7 +1553,7 @@ packages:
       '@smithy/property-provider': 1.2.0
       '@smithy/shared-ini-file-loader': 1.1.0
       '@smithy/types': 1.2.0
-      tslib: 2.5.3
+      tslib: 2.6.2
     transitivePeerDependencies:
       - aws-crt
     dev: false
@@ -1459,7 +1566,7 @@ packages:
       '@smithy/property-provider': 1.2.0
       '@smithy/shared-ini-file-loader': 1.1.0
       '@smithy/types': 1.2.0
-      tslib: 2.5.3
+      tslib: 2.6.2
     dev: false
 
   /@aws-sdk/credential-provider-sso@3.370.0:
@@ -1472,7 +1579,7 @@ packages:
       '@smithy/property-provider': 1.2.0
       '@smithy/shared-ini-file-loader': 1.1.0
       '@smithy/types': 1.2.0
-      tslib: 2.5.3
+      tslib: 2.6.2
     transitivePeerDependencies:
       - aws-crt
     dev: false
@@ -1484,7 +1591,7 @@ packages:
       '@aws-sdk/types': 3.370.0
       '@smithy/property-provider': 1.2.0
       '@smithy/types': 1.2.0
-      tslib: 2.5.3
+      tslib: 2.6.2
     dev: false
 
   /@aws-sdk/hash-stream-node@3.374.0:
@@ -1493,7 +1600,7 @@ packages:
     deprecated: This package has moved to @smithy/hash-stream-node
     dependencies:
       '@smithy/hash-stream-node': 1.1.0
-      tslib: 2.5.3
+      tslib: 2.6.2
     dev: false
 
   /@aws-sdk/middleware-bucket-endpoint@3.370.0:
@@ -1505,7 +1612,7 @@ packages:
       '@smithy/protocol-http': 1.2.0
       '@smithy/types': 1.2.0
       '@smithy/util-config-provider': 1.1.0
-      tslib: 2.5.3
+      tslib: 2.6.2
     dev: false
 
   /@aws-sdk/middleware-expect-continue@3.370.0:
@@ -1515,7 +1622,7 @@ packages:
       '@aws-sdk/types': 3.370.0
       '@smithy/protocol-http': 1.2.0
       '@smithy/types': 1.2.0
-      tslib: 2.5.3
+      tslib: 2.6.2
     dev: false
 
   /@aws-sdk/middleware-flexible-checksums@3.374.0:
@@ -1529,7 +1636,7 @@ packages:
       '@smithy/protocol-http': 1.2.0
       '@smithy/types': 1.2.0
       '@smithy/util-utf8': 1.1.0
-      tslib: 2.5.3
+      tslib: 2.6.2
     dev: false
 
   /@aws-sdk/middleware-host-header@3.370.0:
@@ -1539,7 +1646,7 @@ packages:
       '@aws-sdk/types': 3.370.0
       '@smithy/protocol-http': 1.2.0
       '@smithy/types': 1.2.0
-      tslib: 2.5.3
+      tslib: 2.6.2
     dev: false
 
   /@aws-sdk/middleware-location-constraint@3.370.0:
@@ -1548,7 +1655,7 @@ packages:
     dependencies:
       '@aws-sdk/types': 3.370.0
       '@smithy/types': 1.2.0
-      tslib: 2.5.3
+      tslib: 2.6.2
     dev: false
 
   /@aws-sdk/middleware-logger@3.370.0:
@@ -1557,7 +1664,7 @@ packages:
     dependencies:
       '@aws-sdk/types': 3.370.0
       '@smithy/types': 1.2.0
-      tslib: 2.5.3
+      tslib: 2.6.2
     dev: false
 
   /@aws-sdk/middleware-recursion-detection@3.370.0:
@@ -1567,7 +1674,7 @@ packages:
       '@aws-sdk/types': 3.370.0
       '@smithy/protocol-http': 1.2.0
       '@smithy/types': 1.2.0
-      tslib: 2.5.3
+      tslib: 2.6.2
     dev: false
 
   /@aws-sdk/middleware-sdk-s3@3.370.0:
@@ -1578,7 +1685,7 @@ packages:
       '@aws-sdk/util-arn-parser': 3.310.0
       '@smithy/protocol-http': 1.2.0
       '@smithy/types': 1.2.0
-      tslib: 2.5.3
+      tslib: 2.6.2
     dev: false
 
   /@aws-sdk/middleware-sdk-sts@3.370.0:
@@ -1588,7 +1695,7 @@ packages:
       '@aws-sdk/middleware-signing': 3.370.0
       '@aws-sdk/types': 3.370.0
       '@smithy/types': 1.2.0
-      tslib: 2.5.3
+      tslib: 2.6.2
     dev: false
 
   /@aws-sdk/middleware-signing@3.370.0:
@@ -1601,7 +1708,7 @@ packages:
       '@smithy/signature-v4': 1.1.0
       '@smithy/types': 1.2.0
       '@smithy/util-middleware': 1.1.0
-      tslib: 2.5.3
+      tslib: 2.6.2
     dev: false
 
   /@aws-sdk/middleware-ssec@3.370.0:
@@ -1610,7 +1717,7 @@ packages:
     dependencies:
       '@aws-sdk/types': 3.370.0
       '@smithy/types': 1.2.0
-      tslib: 2.5.3
+      tslib: 2.6.2
     dev: false
 
   /@aws-sdk/middleware-user-agent@3.370.0:
@@ -1621,7 +1728,7 @@ packages:
       '@aws-sdk/util-endpoints': 3.370.0
       '@smithy/protocol-http': 1.2.0
       '@smithy/types': 1.2.0
-      tslib: 2.5.3
+      tslib: 2.6.2
     dev: false
 
   /@aws-sdk/s3-request-presigner@3.375.0:
@@ -1635,7 +1742,7 @@ packages:
       '@smithy/protocol-http': 1.2.0
       '@smithy/smithy-client': 1.1.0
       '@smithy/types': 1.2.0
-      tslib: 2.5.3
+      tslib: 2.6.2
     transitivePeerDependencies:
       - '@aws-sdk/signature-v4-crt'
     dev: false
@@ -1653,7 +1760,7 @@ packages:
       '@smithy/protocol-http': 1.2.0
       '@smithy/signature-v4': 1.1.0
       '@smithy/types': 1.2.0
-      tslib: 2.5.3
+      tslib: 2.6.2
     dev: false
 
   /@aws-sdk/token-providers@3.370.0:
@@ -1665,7 +1772,7 @@ packages:
       '@smithy/property-provider': 1.2.0
       '@smithy/shared-ini-file-loader': 1.1.0
       '@smithy/types': 1.2.0
-      tslib: 2.5.3
+      tslib: 2.6.2
     transitivePeerDependencies:
       - aws-crt
     dev: false
@@ -1675,14 +1782,14 @@ packages:
     engines: {node: '>=14.0.0'}
     dependencies:
       '@smithy/types': 1.2.0
-      tslib: 2.5.3
+      tslib: 2.6.2
     dev: false
 
   /@aws-sdk/util-arn-parser@3.310.0:
     resolution: {integrity: sha512-jL8509owp/xB9+Or0pvn3Fe+b94qfklc2yPowZZIFAkFcCSIdkIglz18cPDWnYAcy9JGewpMS1COXKIUhZkJsA==}
     engines: {node: '>=14.0.0'}
     dependencies:
-      tslib: 2.5.3
+      tslib: 2.6.2
     dev: false
 
   /@aws-sdk/util-endpoints@3.370.0:
@@ -1690,7 +1797,7 @@ packages:
     engines: {node: '>=14.0.0'}
     dependencies:
       '@aws-sdk/types': 3.370.0
-      tslib: 2.5.3
+      tslib: 2.6.2
     dev: false
 
   /@aws-sdk/util-format-url@3.370.0:
@@ -1700,14 +1807,14 @@ packages:
       '@aws-sdk/types': 3.370.0
       '@smithy/querystring-builder': 1.1.0
       '@smithy/types': 1.2.0
-      tslib: 2.5.3
+      tslib: 2.6.2
     dev: false
 
   /@aws-sdk/util-locate-window@3.310.0:
     resolution: {integrity: sha512-qo2t/vBTnoXpjKxlsC2e1gBrRm80M3bId27r0BRB2VniSSe7bL1mmzM+/HFtujm0iAxtPM+aLEflLJlJeDPg0w==}
     engines: {node: '>=14.0.0'}
     dependencies:
-      tslib: 2.5.3
+      tslib: 2.6.2
     dev: false
 
   /@aws-sdk/util-user-agent-browser@3.370.0:
@@ -1716,7 +1823,7 @@ packages:
       '@aws-sdk/types': 3.370.0
       '@smithy/types': 1.2.0
       bowser: 2.11.0
-      tslib: 2.5.3
+      tslib: 2.6.2
     dev: false
 
   /@aws-sdk/util-user-agent-node@3.370.0:
@@ -1731,76 +1838,48 @@ packages:
       '@aws-sdk/types': 3.370.0
       '@smithy/node-config-provider': 1.1.0
       '@smithy/types': 1.2.0
-      tslib: 2.5.3
+      tslib: 2.6.2
     dev: false
 
   /@aws-sdk/util-utf8-browser@3.259.0:
     resolution: {integrity: sha512-UvFa/vR+e19XookZF8RzFZBrw2EUkQWxiBW0yYQAhvk3C+QVGl0H3ouca8LDBlBfQKXwmW3huo/59H8rwb1wJw==}
     dependencies:
-      tslib: 2.5.3
+      tslib: 2.6.2
     dev: false
 
   /@aws-sdk/xml-builder@3.310.0:
     resolution: {integrity: sha512-TqELu4mOuSIKQCqj63fGVs86Yh+vBx5nHRpWKNUNhB2nPTpfbziTs5c1X358be3peVWA4wPxW7Nt53KIg1tnNw==}
     engines: {node: '>=14.0.0'}
     dependencies:
-      tslib: 2.5.3
+      tslib: 2.6.2
     dev: false
 
   /@babel/code-frame@7.22.13:
     resolution: {integrity: sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w==}
     engines: {node: '>=6.9.0'}
     dependencies:
-      '@babel/highlight': 7.22.13
+      '@babel/highlight': 7.22.20
       chalk: 2.4.2
 
-  /@babel/code-frame@7.22.5:
-    resolution: {integrity: sha512-Xmwn266vad+6DAqEB2A6V/CcZVp62BbwVmcOJc2RPuwih1kw02TjQvWVWlcKGbBPd+8/0V5DEkOcizRGYsspYQ==}
-    engines: {node: '>=6.9.0'}
-    dependencies:
-      '@babel/highlight': 7.22.13
-
-  /@babel/compat-data@7.22.9:
-    resolution: {integrity: sha512-5UamI7xkUcJ3i9qVDS+KFDEK8/7oJ55/sJMB1Ge7IEapr7KfdfV/HErR+koZwOfd+SgtFKOKRhRakdg++DcJpQ==}
+  /@babel/compat-data@7.22.20:
+    resolution: {integrity: sha512-BQYjKbpXjoXwFW5jGqiizJQQT/aC7pFm9Ok1OWssonuguICi264lbgMzRp2ZMmRSlfkX6DsWDDcsrctK8Rwfiw==}
     engines: {node: '>=6.9.0'}
 
-  /@babel/core@7.22.15:
-    resolution: {integrity: sha512-PtZqMmgRrvj8ruoEOIwVA3yoF91O+Hgw9o7DAUTNBA6Mo2jpu31clx9a7Nz/9JznqetTR6zwfC4L3LAjKQXUwA==}
+  /@babel/core@7.23.0:
+    resolution: {integrity: sha512-97z/ju/Jy1rZmDxybphrBuI+jtJjFVoz7Mr9yUQVVVi+DNZE333uFQeMOqcCIy1x3WYBIbWftUSLmbNXNT7qFQ==}
     engines: {node: '>=6.9.0'}
     dependencies:
       '@ampproject/remapping': 2.2.1
       '@babel/code-frame': 7.22.13
-      '@babel/generator': 7.22.15
+      '@babel/generator': 7.23.0
       '@babel/helper-compilation-targets': 7.22.15
-      '@babel/helper-module-transforms': 7.22.15(@babel/core@7.22.15)
-      '@babel/helpers': 7.22.15
-      '@babel/parser': 7.22.16
+      '@babel/helper-module-transforms': 7.23.0(@babel/core@7.23.0)
+      '@babel/helpers': 7.23.1
+      '@babel/parser': 7.23.0
       '@babel/template': 7.22.15
-      '@babel/traverse': 7.22.15
-      '@babel/types': 7.22.15
-      convert-source-map: 1.9.0
-      debug: 4.3.4
-      gensync: 1.0.0-beta.2
-      json5: 2.2.3
-      semver: 6.3.1
-    transitivePeerDependencies:
-      - supports-color
-
-  /@babel/core@7.22.5:
-    resolution: {integrity: sha512-SBuTAjg91A3eKOvD+bPEz3LlhHZRNu1nFOVts9lzDJTXshHTjII0BAtDS3Y2DAkdZdDKWVZGVwkDfc4Clxn1dg==}
-    engines: {node: '>=6.9.0'}
-    dependencies:
-      '@ampproject/remapping': 2.2.1
-      '@babel/code-frame': 7.22.5
-      '@babel/generator': 7.22.5
-      '@babel/helper-compilation-targets': 7.22.5(@babel/core@7.22.5)
-      '@babel/helper-module-transforms': 7.22.5
-      '@babel/helpers': 7.22.5
-      '@babel/parser': 7.22.5
-      '@babel/template': 7.22.5
-      '@babel/traverse': 7.22.5
-      '@babel/types': 7.22.5
-      convert-source-map: 1.9.0
+      '@babel/traverse': 7.23.0
+      '@babel/types': 7.23.0
+      convert-source-map: 2.0.0
       debug: 4.3.4
       gensync: 1.0.0-beta.2
       json5: 2.2.3
@@ -1808,412 +1887,262 @@ packages:
     transitivePeerDependencies:
       - supports-color
 
-  /@babel/eslint-parser@7.22.5(@babel/core@7.22.5)(eslint@8.45.0):
-    resolution: {integrity: sha512-C69RWYNYtrgIRE5CmTd77ZiLDXqgBipahJc/jHP3sLcAGj6AJzxNIuKNpVnICqbyK7X3pFUfEvL++rvtbQpZkQ==}
+  /@babel/eslint-parser@7.22.15(@babel/core@7.23.0)(eslint@8.45.0):
+    resolution: {integrity: sha512-yc8OOBIQk1EcRrpizuARSQS0TWAcOMpEJ1aafhNznaeYkeL+OhqnDObGFylB8ka8VFF/sZc+S4RzHyO+3LjQxg==}
     engines: {node: ^10.13.0 || ^12.13.0 || >=14.0.0}
     peerDependencies:
-      '@babel/core': '>=7.11.0'
+      '@babel/core': ^7.11.0
       eslint: ^7.5.0 || ^8.0.0
     dependencies:
-      '@babel/core': 7.22.5
+      '@babel/core': 7.23.0
       '@nicolo-ribaudo/eslint-scope-5-internals': 5.1.1-v1
       eslint: 8.45.0
       eslint-visitor-keys: 2.1.0
       semver: 6.3.1
     dev: true
 
-  /@babel/generator@7.22.15:
-    resolution: {integrity: sha512-Zu9oWARBqeVOW0dZOjXc3JObrzuqothQ3y/n1kUtrjCoCPLkXUwMvOo/F/TCfoHMbWIFlWwpZtkZVb9ga4U2pA==}
-    engines: {node: '>=6.9.0'}
-    dependencies:
-      '@babel/types': 7.22.15
-      '@jridgewell/gen-mapping': 0.3.3
-      '@jridgewell/trace-mapping': 0.3.18
-      jsesc: 2.5.2
-
-  /@babel/generator@7.22.5:
-    resolution: {integrity: sha512-+lcUbnTRhd0jOewtFSedLyiPsD5tswKkbgcezOqqWFUVNEwoUTlpPOBmvhG7OXWLR4jMdv0czPGH5XbflnD1EA==}
+  /@babel/generator@7.23.0:
+    resolution: {integrity: sha512-lN85QRR+5IbYrMWM6Y4pE/noaQtg4pNiqeNGX60eqOfo6gtEj6uw/JagelB8vVztSd7R6M5n1+PQkDbHbBRU4g==}
     engines: {node: '>=6.9.0'}
     dependencies:
-      '@babel/types': 7.22.15
+      '@babel/types': 7.23.0
       '@jridgewell/gen-mapping': 0.3.3
-      '@jridgewell/trace-mapping': 0.3.18
+      '@jridgewell/trace-mapping': 0.3.19
       jsesc: 2.5.2
 
   /@babel/helper-annotate-as-pure@7.22.5:
     resolution: {integrity: sha512-LvBTxu8bQSQkcyKOU+a1btnNFQ1dMAd0R6PyW3arXes06F6QLWLIrd681bxRPIXlrMGR3XYnW9JyML7dP3qgxg==}
     engines: {node: '>=6.9.0'}
     dependencies:
-      '@babel/types': 7.22.15
+      '@babel/types': 7.23.0
 
   /@babel/helper-compilation-targets@7.22.15:
     resolution: {integrity: sha512-y6EEzULok0Qvz8yyLkCvVX+02ic+By2UdOhylwUOvOn9dvYc9mKICJuuU1n1XBI02YWsNsnrY1kc6DVbjcXbtw==}
     engines: {node: '>=6.9.0'}
     dependencies:
-      '@babel/compat-data': 7.22.9
-      '@babel/helper-validator-option': 7.22.15
-      browserslist: 4.21.10
-      lru-cache: 5.1.1
-      semver: 6.3.1
-
-  /@babel/helper-compilation-targets@7.22.5(@babel/core@7.22.5):
-    resolution: {integrity: sha512-Ji+ywpHeuqxB8WDxraCiqR0xfhYjiDE/e6k7FuIaANnoOFxAHskHChz4vA1mJC9Lbm01s1PVAGhQY4FUKSkGZw==}
-    engines: {node: '>=6.9.0'}
-    peerDependencies:
-      '@babel/core': ^7.0.0
-    dependencies:
-      '@babel/compat-data': 7.22.9
-      '@babel/core': 7.22.5
+      '@babel/compat-data': 7.22.20
       '@babel/helper-validator-option': 7.22.15
-      browserslist: 4.21.10
+      browserslist: 4.22.1
       lru-cache: 5.1.1
       semver: 6.3.1
 
-  /@babel/helper-create-class-features-plugin@7.22.5(@babel/core@7.22.5):
-    resolution: {integrity: sha512-xkb58MyOYIslxu3gKmVXmjTtUPvBU4odYzbiIQbWwLKIHCsx6UGZGX6F1IznMFVnDdirseUZopzN+ZRt8Xb33Q==}
+  /@babel/helper-create-class-features-plugin@7.22.15(@babel/core@7.23.0):
+    resolution: {integrity: sha512-jKkwA59IXcvSaiK2UN45kKwSC9o+KuoXsBDvHvU/7BecYIp8GQ2UwrVvFgJASUT+hBnwJx6MhvMCuMzwZZ7jlg==}
     engines: {node: '>=6.9.0'}
     peerDependencies:
       '@babel/core': ^7.0.0
     dependencies:
-      '@babel/core': 7.22.5
+      '@babel/core': 7.23.0
       '@babel/helper-annotate-as-pure': 7.22.5
-      '@babel/helper-environment-visitor': 7.22.5
-      '@babel/helper-function-name': 7.22.5
-      '@babel/helper-member-expression-to-functions': 7.22.5
+      '@babel/helper-environment-visitor': 7.22.20
+      '@babel/helper-function-name': 7.23.0
+      '@babel/helper-member-expression-to-functions': 7.23.0
       '@babel/helper-optimise-call-expression': 7.22.5
-      '@babel/helper-replace-supers': 7.22.5
+      '@babel/helper-replace-supers': 7.22.20(@babel/core@7.23.0)
       '@babel/helper-skip-transparent-expression-wrappers': 7.22.5
-      '@babel/helper-split-export-declaration': 7.22.5
+      '@babel/helper-split-export-declaration': 7.22.6
       semver: 6.3.1
-    transitivePeerDependencies:
-      - supports-color
 
-  /@babel/helper-environment-visitor@7.22.5:
-    resolution: {integrity: sha512-XGmhECfVA/5sAt+H+xpSg0mfrHq6FzNr9Oxh7PSEBBRUb/mL7Kz3NICXb194rCqAEdxkhPT1a88teizAFyvk8Q==}
+  /@babel/helper-environment-visitor@7.22.20:
+    resolution: {integrity: sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==}
     engines: {node: '>=6.9.0'}
 
-  /@babel/helper-function-name@7.22.5:
-    resolution: {integrity: sha512-wtHSq6jMRE3uF2otvfuD3DIvVhOsSNshQl0Qrd7qC9oQJzHvOL4qQXlQn2916+CXGywIjpGuIkoyZRRxHPiNQQ==}
+  /@babel/helper-function-name@7.23.0:
+    resolution: {integrity: sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==}
     engines: {node: '>=6.9.0'}
     dependencies:
-      '@babel/template': 7.22.5
-      '@babel/types': 7.22.15
+      '@babel/template': 7.22.15
+      '@babel/types': 7.23.0
 
   /@babel/helper-hoist-variables@7.22.5:
     resolution: {integrity: sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==}
     engines: {node: '>=6.9.0'}
     dependencies:
-      '@babel/types': 7.22.15
+      '@babel/types': 7.23.0
 
-  /@babel/helper-member-expression-to-functions@7.22.5:
-    resolution: {integrity: sha512-aBiH1NKMG0H2cGZqspNvsaBe6wNGjbJjuLy29aU+eDZjSbbN53BaxlpB02xm9v34pLTZ1nIQPFYn2qMZoa5BQQ==}
+  /@babel/helper-member-expression-to-functions@7.23.0:
+    resolution: {integrity: sha512-6gfrPwh7OuT6gZyJZvd6WbTfrqAo7vm4xCzAXOusKqq/vWdKXphTpj5klHKNmRUU6/QRGlBsyU9mAIPaWHlqJA==}
     engines: {node: '>=6.9.0'}
     dependencies:
-      '@babel/types': 7.22.15
+      '@babel/types': 7.23.0
 
   /@babel/helper-module-imports@7.18.6:
     resolution: {integrity: sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA==}
     engines: {node: '>=6.9.0'}
     dependencies:
-      '@babel/types': 7.22.15
+      '@babel/types': 7.23.0
 
   /@babel/helper-module-imports@7.22.15:
     resolution: {integrity: sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w==}
     engines: {node: '>=6.9.0'}
     dependencies:
-      '@babel/types': 7.22.15
-
-  /@babel/helper-module-imports@7.22.5:
-    resolution: {integrity: sha512-8Dl6+HD/cKifutF5qGd/8ZJi84QeAKh+CEe1sBzz8UayBBGg1dAIJrdHOcOM5b2MpzWL2yuotJTtGjETq0qjXg==}
-    engines: {node: '>=6.9.0'}
-    dependencies:
-      '@babel/types': 7.22.15
+      '@babel/types': 7.23.0
 
-  /@babel/helper-module-transforms@7.22.15(@babel/core@7.22.15):
-    resolution: {integrity: sha512-l1UiX4UyHSFsYt17iQ3Se5pQQZZHa22zyIXURmvkmLCD4t/aU+dvNWHatKac/D9Vm9UES7nvIqHs4jZqKviUmQ==}
+  /@babel/helper-module-transforms@7.23.0(@babel/core@7.23.0):
+    resolution: {integrity: sha512-WhDWw1tdrlT0gMgUJSlX0IQvoO1eN279zrAUbVB+KpV2c3Tylz8+GnKOLllCS6Z/iZQEyVYxhZVUdPTqs2YYPw==}
     engines: {node: '>=6.9.0'}
     peerDependencies:
       '@babel/core': ^7.0.0
     dependencies:
-      '@babel/core': 7.22.15
-      '@babel/helper-environment-visitor': 7.22.5
-      '@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.15
-
-  /@babel/helper-module-transforms@7.22.5:
-    resolution: {integrity: sha512-+hGKDt/Ze8GFExiVHno/2dvG5IdstpzCq0y4Qc9OJ25D4q3pKfiIP/4Vp3/JvhDkLKsDK2api3q3fpIgiIF5bw==}
-    engines: {node: '>=6.9.0'}
-    dependencies:
-      '@babel/helper-environment-visitor': 7.22.5
+      '@babel/core': 7.23.0
+      '@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.15
-      '@babel/template': 7.22.15
-      '@babel/traverse': 7.22.15
-      '@babel/types': 7.22.15
-    transitivePeerDependencies:
-      - supports-color
+      '@babel/helper-validator-identifier': 7.22.20
 
   /@babel/helper-optimise-call-expression@7.22.5:
     resolution: {integrity: sha512-HBwaojN0xFRx4yIvpwGqxiV2tUfl7401jlok564NgB9EHS1y6QT17FmKWm4ztqjeVdXLuC4fSvHc5ePpQjoTbw==}
     engines: {node: '>=6.9.0'}
     dependencies:
-      '@babel/types': 7.22.15
+      '@babel/types': 7.23.0
 
   /@babel/helper-plugin-utils@7.22.5:
     resolution: {integrity: sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg==}
     engines: {node: '>=6.9.0'}
 
-  /@babel/helper-replace-supers@7.22.5:
-    resolution: {integrity: sha512-aLdNM5I3kdI/V9xGNyKSF3X/gTyMUBohTZ+/3QdQKAA9vxIiy12E+8E2HoOP1/DjeqU+g6as35QHJNMDDYpuCg==}
+  /@babel/helper-replace-supers@7.22.20(@babel/core@7.23.0):
+    resolution: {integrity: sha512-qsW0In3dbwQUbK8kejJ4R7IHVGwHJlV6lpG6UA7a9hSa2YEiAib+N1T2kr6PEeUT+Fl7najmSOS6SmAwCHK6Tw==}
     engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0
     dependencies:
-      '@babel/helper-environment-visitor': 7.22.5
-      '@babel/helper-member-expression-to-functions': 7.22.5
+      '@babel/core': 7.23.0
+      '@babel/helper-environment-visitor': 7.22.20
+      '@babel/helper-member-expression-to-functions': 7.23.0
       '@babel/helper-optimise-call-expression': 7.22.5
-      '@babel/template': 7.22.15
-      '@babel/traverse': 7.22.15
-      '@babel/types': 7.22.15
-    transitivePeerDependencies:
-      - supports-color
 
   /@babel/helper-simple-access@7.22.5:
     resolution: {integrity: sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==}
     engines: {node: '>=6.9.0'}
     dependencies:
-      '@babel/types': 7.22.15
+      '@babel/types': 7.23.0
 
   /@babel/helper-skip-transparent-expression-wrappers@7.22.5:
     resolution: {integrity: sha512-tK14r66JZKiC43p8Ki33yLBVJKlQDFoA8GYN67lWCDCqoL6EMMSuM9b+Iff2jHaM/RRFYl7K+iiru7hbRqNx8Q==}
     engines: {node: '>=6.9.0'}
     dependencies:
-      '@babel/types': 7.22.15
-
-  /@babel/helper-split-export-declaration@7.22.5:
-    resolution: {integrity: sha512-thqK5QFghPKWLhAV321lxF95yCg2K3Ob5yw+M3VHWfdia0IkPXUtoLH8x/6Fh486QUvzhb8YOWHChTVen2/PoQ==}
-    engines: {node: '>=6.9.0'}
-    dependencies:
-      '@babel/types': 7.22.15
+      '@babel/types': 7.23.0
 
   /@babel/helper-split-export-declaration@7.22.6:
     resolution: {integrity: sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==}
     engines: {node: '>=6.9.0'}
     dependencies:
-      '@babel/types': 7.22.15
+      '@babel/types': 7.23.0
 
   /@babel/helper-string-parser@7.22.5:
     resolution: {integrity: sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==}
     engines: {node: '>=6.9.0'}
 
-  /@babel/helper-validator-identifier@7.22.15:
-    resolution: {integrity: sha512-4E/F9IIEi8WR94324mbDUMo074YTheJmd7eZF5vITTeYchqAi6sYXRLHUVsmkdmY4QjfKTcB2jB7dVP3NaBElQ==}
-    engines: {node: '>=6.9.0'}
-
-  /@babel/helper-validator-identifier@7.22.5:
-    resolution: {integrity: sha512-aJXu+6lErq8ltp+JhkJUfk1MTGyuA4v7f3pA+BJ5HLfNC6nAQ0Cpi9uOquUj8Hehg0aUiHzWQbOVJGao6ztBAQ==}
+  /@babel/helper-validator-identifier@7.22.20:
+    resolution: {integrity: sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==}
     engines: {node: '>=6.9.0'}
 
   /@babel/helper-validator-option@7.22.15:
     resolution: {integrity: sha512-bMn7RmyFjY/mdECUbgn9eoSY4vqvacUnS9i9vGAGttgFWesO6B4CYWA7XlpbWgBt71iv/hfbPlynohStqnu5hA==}
     engines: {node: '>=6.9.0'}
 
-  /@babel/helper-validator-option@7.22.5:
-    resolution: {integrity: sha512-R3oB6xlIVKUnxNUxbmgq7pKjxpru24zlimpE8WK47fACIlM0II/Hm1RS8IaOI7NgCr6LNS+jl5l75m20npAziw==}
-    engines: {node: '>=6.9.0'}
-
-  /@babel/helpers@7.22.15:
-    resolution: {integrity: sha512-7pAjK0aSdxOwR+CcYAqgWOGy5dcfvzsTIfFTb2odQqW47MDfv14UaJDY6eng8ylM2EaeKXdxaSWESbkmaQHTmw==}
+  /@babel/helpers@7.23.1:
+    resolution: {integrity: sha512-chNpneuK18yW5Oxsr+t553UZzzAs3aZnFm4bxhebsNTeshrC95yA7l5yl7GBAG+JG1rF0F7zzD2EixK9mWSDoA==}
     engines: {node: '>=6.9.0'}
     dependencies:
       '@babel/template': 7.22.15
-      '@babel/traverse': 7.22.15
-      '@babel/types': 7.22.15
-    transitivePeerDependencies:
-      - supports-color
-
-  /@babel/helpers@7.22.5:
-    resolution: {integrity: sha512-pSXRmfE1vzcUIDFQcSGA5Mr+GxBV9oiRKDuDxXvWQQBCh8HoIjs/2DlDB7H8smac1IVrB9/xdXj2N3Wol9Cr+Q==}
-    engines: {node: '>=6.9.0'}
-    dependencies:
-      '@babel/template': 7.22.5
-      '@babel/traverse': 7.22.5
-      '@babel/types': 7.22.15
+      '@babel/traverse': 7.23.0
+      '@babel/types': 7.23.0
     transitivePeerDependencies:
       - supports-color
 
-  /@babel/highlight@7.22.13:
-    resolution: {integrity: sha512-C/BaXcnnvBCmHTpz/VGZ8jgtE2aYlW4hxDhseJAWZb7gqGM/qtCK6iZUb0TyKFf7BOUsBH7Q7fkRsDRhg1XklQ==}
+  /@babel/highlight@7.22.20:
+    resolution: {integrity: sha512-dkdMCN3py0+ksCgYmGG8jKeGA/8Tk+gJwSYYlFGxG5lmhfKNoAy004YpLxpS1W2J8m/EK2Ew+yOs9pVRwO89mg==}
     engines: {node: '>=6.9.0'}
     dependencies:
-      '@babel/helper-validator-identifier': 7.22.15
+      '@babel/helper-validator-identifier': 7.22.20
       chalk: 2.4.2
       js-tokens: 4.0.0
 
-  /@babel/parser@7.22.16:
-    resolution: {integrity: sha512-+gPfKv8UWeKKeJTUxe59+OobVcrYHETCsORl61EmSkmgymguYk/X5bp7GuUIXaFsc6y++v8ZxPsLSSuujqDphA==}
+  /@babel/parser@7.23.0:
+    resolution: {integrity: sha512-vvPKKdMemU85V9WE/l5wZEmImpCtLqbnTvqDS2U1fJ96KrxoW7KrXhNsNCblQlg8Ck4b85yxdTyelsMUgFUXiw==}
     engines: {node: '>=6.0.0'}
     hasBin: true
     dependencies:
-      '@babel/types': 7.22.15
+      '@babel/types': 7.23.0
 
-  /@babel/parser@7.22.5:
-    resolution: {integrity: sha512-DFZMC9LJUG9PLOclRC32G63UXwzqS2koQC8dkx+PLdmt1xSePYpbT/NbsrJy8Q/muXz7o/h/d4A7Fuyixm559Q==}
-    engines: {node: '>=6.0.0'}
-    hasBin: true
-    dependencies:
-      '@babel/types': 7.22.15
-
-  /@babel/plugin-proposal-export-namespace-from@7.18.9(@babel/core@7.22.15):
-    resolution: {integrity: sha512-k1NtHyOMvlDDFeb9G5PhUXuGj8m/wiwojgQVEhJ/fsVsMCpLyOP4h0uGEjYJKrRI+EVPlb5Jk+Gt9P97lOGwtA==}
-    engines: {node: '>=6.9.0'}
-    peerDependencies:
-      '@babel/core': ^7.0.0-0
-    dependencies:
-      '@babel/core': 7.22.15
-      '@babel/helper-plugin-utils': 7.22.5
-      '@babel/plugin-syntax-export-namespace-from': 7.8.3(@babel/core@7.22.15)
-    dev: false
-
-  /@babel/plugin-syntax-dynamic-import@7.8.3(@babel/core@7.22.15):
-    resolution: {integrity: sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==}
-    peerDependencies:
-      '@babel/core': ^7.0.0-0
-    dependencies:
-      '@babel/core': 7.22.15
-      '@babel/helper-plugin-utils': 7.22.5
-    dev: false
-
-  /@babel/plugin-syntax-export-namespace-from@7.8.3(@babel/core@7.22.15):
-    resolution: {integrity: sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==}
-    peerDependencies:
-      '@babel/core': ^7.0.0-0
-    dependencies:
-      '@babel/core': 7.22.15
-      '@babel/helper-plugin-utils': 7.22.5
-    dev: false
-
-  /@babel/plugin-syntax-jsx@7.22.5(@babel/core@7.22.15):
-    resolution: {integrity: sha512-gvyP4hZrgrs/wWMaocvxZ44Hw0b3W8Pe+cMxc8V1ULQ07oh8VNbIRaoD1LRZVTvD+0nieDKjfgKg89sD7rrKrg==}
-    engines: {node: '>=6.9.0'}
-    peerDependencies:
-      '@babel/core': ^7.0.0-0
-    dependencies:
-      '@babel/core': 7.22.15
-      '@babel/helper-plugin-utils': 7.22.5
-
-  /@babel/plugin-syntax-jsx@7.22.5(@babel/core@7.22.5):
+  /@babel/plugin-syntax-jsx@7.22.5(@babel/core@7.23.0):
     resolution: {integrity: sha512-gvyP4hZrgrs/wWMaocvxZ44Hw0b3W8Pe+cMxc8V1ULQ07oh8VNbIRaoD1LRZVTvD+0nieDKjfgKg89sD7rrKrg==}
     engines: {node: '>=6.9.0'}
     peerDependencies:
       '@babel/core': ^7.0.0-0
     dependencies:
-      '@babel/core': 7.22.5
+      '@babel/core': 7.23.0
       '@babel/helper-plugin-utils': 7.22.5
 
-  /@babel/plugin-syntax-typescript@7.22.5(@babel/core@7.22.5):
+  /@babel/plugin-syntax-typescript@7.22.5(@babel/core@7.23.0):
     resolution: {integrity: sha512-1mS2o03i7t1c6VzH6fdQ3OA8tcEIxwG18zIPRp+UY1Ihv6W+XZzBCVxExF9upussPXJ0xE9XRHwMoNs1ep/nRQ==}
     engines: {node: '>=6.9.0'}
     peerDependencies:
       '@babel/core': ^7.0.0-0
     dependencies:
-      '@babel/core': 7.22.5
-      '@babel/helper-plugin-utils': 7.22.5
-
-  /@babel/plugin-transform-modules-commonjs@7.22.5(@babel/core@7.22.15):
-    resolution: {integrity: sha512-B4pzOXj+ONRmuaQTg05b3y/4DuFz3WcCNAXPLb2Q0GT0TrGKGxNKV4jwsXts+StaM0LQczZbOpj8o1DLPDJIiA==}
-    engines: {node: '>=6.9.0'}
-    peerDependencies:
-      '@babel/core': ^7.0.0-0
-    dependencies:
-      '@babel/core': 7.22.15
-      '@babel/helper-module-transforms': 7.22.5
+      '@babel/core': 7.23.0
       '@babel/helper-plugin-utils': 7.22.5
-      '@babel/helper-simple-access': 7.22.5
-    transitivePeerDependencies:
-      - supports-color
-    dev: false
 
-  /@babel/plugin-transform-modules-commonjs@7.22.5(@babel/core@7.22.5):
-    resolution: {integrity: sha512-B4pzOXj+ONRmuaQTg05b3y/4DuFz3WcCNAXPLb2Q0GT0TrGKGxNKV4jwsXts+StaM0LQczZbOpj8o1DLPDJIiA==}
+  /@babel/plugin-transform-modules-commonjs@7.23.0(@babel/core@7.23.0):
+    resolution: {integrity: sha512-32Xzss14/UVc7k9g775yMIvkVK8xwKE0DPdP5JTapr3+Z9w4tzeOuLNY6BXDQR6BdnzIlXnCGAzsk/ICHBLVWQ==}
     engines: {node: '>=6.9.0'}
     peerDependencies:
       '@babel/core': ^7.0.0-0
     dependencies:
-      '@babel/core': 7.22.5
-      '@babel/helper-module-transforms': 7.22.5
+      '@babel/core': 7.23.0
+      '@babel/helper-module-transforms': 7.23.0(@babel/core@7.23.0)
       '@babel/helper-plugin-utils': 7.22.5
       '@babel/helper-simple-access': 7.22.5
-    transitivePeerDependencies:
-      - supports-color
-
-  /@babel/plugin-transform-react-jsx@7.22.5(@babel/core@7.22.15):
-    resolution: {integrity: sha512-rog5gZaVbUip5iWDMTYbVM15XQq+RkUKhET/IHR6oizR+JEoN6CAfTTuHcK4vwUyzca30qqHqEpzBOnaRMWYMA==}
-    engines: {node: '>=6.9.0'}
-    peerDependencies:
-      '@babel/core': ^7.0.0-0
-    dependencies:
-      '@babel/core': 7.22.15
-      '@babel/helper-annotate-as-pure': 7.22.5
-      '@babel/helper-module-imports': 7.22.15
-      '@babel/helper-plugin-utils': 7.22.5
-      '@babel/plugin-syntax-jsx': 7.22.5(@babel/core@7.22.15)
-      '@babel/types': 7.22.15
 
-  /@babel/plugin-transform-react-jsx@7.22.5(@babel/core@7.22.5):
-    resolution: {integrity: sha512-rog5gZaVbUip5iWDMTYbVM15XQq+RkUKhET/IHR6oizR+JEoN6CAfTTuHcK4vwUyzca30qqHqEpzBOnaRMWYMA==}
+  /@babel/plugin-transform-react-jsx@7.22.15(@babel/core@7.23.0):
+    resolution: {integrity: sha512-oKckg2eZFa8771O/5vi7XeTvmM6+O9cxZu+kanTU7tD4sin5nO/G8jGJhq8Hvt2Z0kUoEDRayuZLaUlYl8QuGA==}
     engines: {node: '>=6.9.0'}
     peerDependencies:
       '@babel/core': ^7.0.0-0
     dependencies:
-      '@babel/core': 7.22.5
+      '@babel/core': 7.23.0
       '@babel/helper-annotate-as-pure': 7.22.5
       '@babel/helper-module-imports': 7.22.15
       '@babel/helper-plugin-utils': 7.22.5
-      '@babel/plugin-syntax-jsx': 7.22.5(@babel/core@7.22.5)
-      '@babel/types': 7.22.15
-    dev: true
+      '@babel/plugin-syntax-jsx': 7.22.5(@babel/core@7.23.0)
+      '@babel/types': 7.23.0
 
-  /@babel/plugin-transform-typescript@7.22.5(@babel/core@7.22.5):
-    resolution: {integrity: sha512-SMubA9S7Cb5sGSFFUlqxyClTA9zWJ8qGQrppNUm05LtFuN1ELRFNndkix4zUJrC9F+YivWwa1dHMSyo0e0N9dA==}
+  /@babel/plugin-transform-typescript@7.22.15(@babel/core@7.23.0):
+    resolution: {integrity: sha512-1uirS0TnijxvQLnlv5wQBwOX3E1wCFX7ITv+9pBV2wKEk4K+M5tqDaoNXnTH8tjEIYHLO98MwiTWO04Ggz4XuA==}
     engines: {node: '>=6.9.0'}
     peerDependencies:
       '@babel/core': ^7.0.0-0
     dependencies:
-      '@babel/core': 7.22.5
+      '@babel/core': 7.23.0
       '@babel/helper-annotate-as-pure': 7.22.5
-      '@babel/helper-create-class-features-plugin': 7.22.5(@babel/core@7.22.5)
+      '@babel/helper-create-class-features-plugin': 7.22.15(@babel/core@7.23.0)
       '@babel/helper-plugin-utils': 7.22.5
-      '@babel/plugin-syntax-typescript': 7.22.5(@babel/core@7.22.5)
-    transitivePeerDependencies:
-      - supports-color
+      '@babel/plugin-syntax-typescript': 7.22.5(@babel/core@7.23.0)
 
-  /@babel/preset-typescript@7.22.5(@babel/core@7.22.5):
-    resolution: {integrity: sha512-YbPaal9LxztSGhmndR46FmAbkJ/1fAsw293tSU+I5E5h+cnJ3d4GTwyUgGYmOXJYdGA+uNePle4qbaRzj2NISQ==}
+  /@babel/preset-typescript@7.23.0(@babel/core@7.23.0):
+    resolution: {integrity: sha512-6P6VVa/NM/VlAYj5s2Aq/gdVg8FSENCg3wlZ6Qau9AcPaoF5LbN1nyGlR9DTRIw9PpxI94e+ReydsJHcjwAweg==}
     engines: {node: '>=6.9.0'}
     peerDependencies:
       '@babel/core': ^7.0.0-0
     dependencies:
-      '@babel/core': 7.22.5
+      '@babel/core': 7.23.0
       '@babel/helper-plugin-utils': 7.22.5
-      '@babel/helper-validator-option': 7.22.5
-      '@babel/plugin-syntax-jsx': 7.22.5(@babel/core@7.22.5)
-      '@babel/plugin-transform-modules-commonjs': 7.22.5(@babel/core@7.22.5)
-      '@babel/plugin-transform-typescript': 7.22.5(@babel/core@7.22.5)
-    transitivePeerDependencies:
-      - supports-color
+      '@babel/helper-validator-option': 7.22.15
+      '@babel/plugin-syntax-jsx': 7.22.5(@babel/core@7.23.0)
+      '@babel/plugin-transform-modules-commonjs': 7.23.0(@babel/core@7.23.0)
+      '@babel/plugin-transform-typescript': 7.22.15(@babel/core@7.23.0)
 
-  /@babel/runtime@7.22.5:
-    resolution: {integrity: sha512-ecjvYlnAaZ/KVneE/OdKYBYfgXV3Ptu6zQWmgEF7vwKhQnvVS6bjMD2XYgj+SNvQ1GfK/pjgokfPkC/2CO8CuA==}
+  /@babel/runtime@7.23.1:
+    resolution: {integrity: sha512-hC2v6p8ZSI/W0HUzh3V8C5g+NwSKzKPtJwSpTjwl0o297GP9+ZLQSkdvHz46CM3LqyoXxq+5G9komY+eSqSO0g==}
     engines: {node: '>=6.9.0'}
     dependencies:
-      regenerator-runtime: 0.13.11
+      regenerator-runtime: 0.14.0
     dev: false
 
-  /@babel/standalone@7.22.5:
-    resolution: {integrity: sha512-6Lwhzral4YDEbIM3dBC8/w0BMDvOosGBGaJWSORLkerx8byawkmwwzXKUB0jGlI1Zp90+cK2uyTl62UPtLbUjQ==}
+  /@babel/standalone@7.23.1:
+    resolution: {integrity: sha512-a4muOYz1qUaSoybuUKwK90mRG4sf5rBeUbuzpuGLzG32ZDE/Y2YEebHDODFJN+BtyOKi19hrLfq2qbNyKMx0TA==}
     engines: {node: '>=6.9.0'}
     dev: true
 
@@ -2222,88 +2151,57 @@ packages:
     engines: {node: '>=6.9.0'}
     dependencies:
       '@babel/code-frame': 7.22.13
-      '@babel/parser': 7.22.16
-      '@babel/types': 7.22.15
-
-  /@babel/template@7.22.5:
-    resolution: {integrity: sha512-X7yV7eiwAxdj9k94NEylvbVHLiVG1nvzCV2EAowhxLTwODV1jl9UzZ48leOC0sH7OnuHrIkllaBgneUykIcZaw==}
-    engines: {node: '>=6.9.0'}
-    dependencies:
-      '@babel/code-frame': 7.22.5
-      '@babel/parser': 7.22.5
-      '@babel/types': 7.22.15
-
-  /@babel/traverse@7.22.15:
-    resolution: {integrity: sha512-DdHPwvJY0sEeN4xJU5uRLmZjgMMDIvMPniLuYzUVXj/GGzysPl0/fwt44JBkyUIzGJPV8QgHMcQdQ34XFuKTYQ==}
-    engines: {node: '>=6.9.0'}
-    dependencies:
-      '@babel/code-frame': 7.22.13
-      '@babel/generator': 7.22.15
-      '@babel/helper-environment-visitor': 7.22.5
-      '@babel/helper-function-name': 7.22.5
-      '@babel/helper-hoist-variables': 7.22.5
-      '@babel/helper-split-export-declaration': 7.22.6
-      '@babel/parser': 7.22.16
-      '@babel/types': 7.22.15
-      debug: 4.3.4
-      globals: 11.12.0
-    transitivePeerDependencies:
-      - supports-color
+      '@babel/parser': 7.23.0
+      '@babel/types': 7.23.0
 
-  /@babel/traverse@7.22.5:
-    resolution: {integrity: sha512-7DuIjPgERaNo6r+PZwItpjCZEa5vyw4eJGufeLxrPdBXBoLcCJCIasvK6pK/9DVNrLZTLFhUGqaC6X/PA007TQ==}
+  /@babel/traverse@7.23.0:
+    resolution: {integrity: sha512-t/QaEvyIoIkwzpiZ7aoSKK8kObQYeF7T2v+dazAYCb8SXtp58zEVkWW7zAnju8FNKNdr4ScAOEDmMItbyOmEYw==}
     engines: {node: '>=6.9.0'}
     dependencies:
       '@babel/code-frame': 7.22.13
-      '@babel/generator': 7.22.15
-      '@babel/helper-environment-visitor': 7.22.5
-      '@babel/helper-function-name': 7.22.5
+      '@babel/generator': 7.23.0
+      '@babel/helper-environment-visitor': 7.22.20
+      '@babel/helper-function-name': 7.23.0
       '@babel/helper-hoist-variables': 7.22.5
       '@babel/helper-split-export-declaration': 7.22.6
-      '@babel/parser': 7.22.16
-      '@babel/types': 7.22.15
+      '@babel/parser': 7.23.0
+      '@babel/types': 7.23.0
       debug: 4.3.4
       globals: 11.12.0
     transitivePeerDependencies:
       - supports-color
 
-  /@babel/types@7.22.15:
-    resolution: {integrity: sha512-X+NLXr0N8XXmN5ZsaQdm9U2SSC3UbIYq/doL++sueHOTisgZHoKaQtZxGuV2cUPQHMfjKEfg/g6oy7Hm6SKFtA==}
-    engines: {node: '>=6.9.0'}
-    dependencies:
-      '@babel/helper-string-parser': 7.22.5
-      '@babel/helper-validator-identifier': 7.22.15
-      to-fast-properties: 2.0.0
-
-  /@babel/types@7.22.5:
-    resolution: {integrity: sha512-zo3MIHGOkPOfoRXitsgHLjEXmlDaD/5KU1Uzuc9GNiZPhSqVxVRtxuPaSBZDsYZ9qV88AjtMtWW7ww98loJ9KA==}
+  /@babel/types@7.23.0:
+    resolution: {integrity: sha512-0oIyUfKoI3mSqMvsxBdclDwxXKXAUA8v/apZbc+iSyARYou1o8ZGDxbUYyLFoW2arqS2jDGqJuZvv1d/io1axg==}
     engines: {node: '>=6.9.0'}
     dependencies:
       '@babel/helper-string-parser': 7.22.5
-      '@babel/helper-validator-identifier': 7.22.5
+      '@babel/helper-validator-identifier': 7.22.20
       to-fast-properties: 2.0.0
 
-  /@bufbuild/connect-node@0.9.1(@bufbuild/protobuf@1.3.0):
+  /@bufbuild/connect-node@0.9.1(@bufbuild/protobuf@1.3.3):
     resolution: {integrity: sha512-kUMB6QQh8S19LsvweDg057WN3Gbg+zIqSHnRcXh9CBYSN7GWd9dgJPQSgalJFJngjFSW2qnnOmnUkxMyZiWBOw==}
     engines: {node: '>=16.0.0'}
+    deprecated: Connect has moved to its own org @connectrpc and has a stable v1. Run `npx @connectrpc/connect-migrate@latest` to update. See https://github.com/connectrpc/connect-es/releases/tag/v0.13.1 for details.
     peerDependencies:
       '@bufbuild/protobuf': ^1.2.0
     dependencies:
-      '@bufbuild/connect': 0.9.1(@bufbuild/protobuf@1.3.0)
-      '@bufbuild/protobuf': 1.3.0
-      headers-polyfill: 3.1.2
+      '@bufbuild/connect': 0.9.1(@bufbuild/protobuf@1.3.3)
+      '@bufbuild/protobuf': 1.3.3
+      headers-polyfill: 3.3.0
     dev: false
 
-  /@bufbuild/connect@0.9.1(@bufbuild/protobuf@1.3.0):
+  /@bufbuild/connect@0.9.1(@bufbuild/protobuf@1.3.3):
     resolution: {integrity: sha512-4O/PSMLWd3oQkwBuJBGBzFtPsnFC5dTRPGHFNFODna9wZJ6r45ccsOWsA4qXBL7gW2EKw93zRa0KVuge2dCOQQ==}
+    deprecated: Connect has moved to its own org @connectrpc and has a stable v1. Run `npx @connectrpc/connect-migrate@latest` to update. See https://github.com/connectrpc/connect-es/releases/tag/v0.13.1 for details.
     peerDependencies:
       '@bufbuild/protobuf': ^1.2.0
     dependencies:
-      '@bufbuild/protobuf': 1.3.0
+      '@bufbuild/protobuf': 1.3.3
     dev: false
 
-  /@bufbuild/protobuf@1.3.0:
-    resolution: {integrity: sha512-G372ods0pLt46yxVRsnP/e2btVPuuzArcMPFpIDeIwiGPuuglEs9y75iG0HMvZgncsj5TvbYRWqbVyOe3PLCWQ==}
+  /@bufbuild/protobuf@1.3.3:
+    resolution: {integrity: sha512-AoHSiIpTFF97SQgmQni4c+Tyr0CDhkaRaR2qGEJTEbauqQwLRpLrd9yVv//wVHOSxr/b4FJcL54VchhY6710xA==}
     dev: false
 
   /@commander-js/extra-typings@9.4.1(commander@9.4.1):
@@ -2352,8 +2250,8 @@ packages:
     requiresBuild: true
     optional: true
 
-  /@esbuild/android-arm64@0.19.3:
-    resolution: {integrity: sha512-w+Akc0vv5leog550kjJV9Ru+MXMR2VuMrui3C61mnysim0gkFCPOUTAfzTP0qX+HpN9Syu3YA3p1hf3EPqObRw==}
+  /@esbuild/android-arm64@0.19.4:
+    resolution: {integrity: sha512-mRsi2vJsk4Bx/AFsNBqOH2fqedxn5L/moT58xgg51DjX1la64Z3Npicut2VbhvDFO26qjWtPMsVxCd80YTFVeg==}
     engines: {node: '>=12'}
     cpu: [arm64]
     os: [android]
@@ -2394,8 +2292,8 @@ packages:
     requiresBuild: true
     optional: true
 
-  /@esbuild/android-arm@0.19.3:
-    resolution: {integrity: sha512-Lemgw4io4VZl9GHJmjiBGzQ7ONXRfRPHcUEerndjwiSkbxzrpq0Uggku5MxxrXdwJ+pTj1qyw4jwTu7hkPsgIA==}
+  /@esbuild/android-arm@0.19.4:
+    resolution: {integrity: sha512-uBIbiYMeSsy2U0XQoOGVVcpIktjLMEKa7ryz2RLr7L/vTnANNEsPVAh4xOv7ondGz6ac1zVb0F8Jx20rQikffQ==}
     engines: {node: '>=12'}
     cpu: [arm]
     os: [android]
@@ -2427,8 +2325,8 @@ packages:
     requiresBuild: true
     optional: true
 
-  /@esbuild/android-x64@0.19.3:
-    resolution: {integrity: sha512-FKQJKkK5MXcBHoNZMDNUAg1+WcZlV/cuXrWCoGF/TvdRiYS4znA0m5Il5idUwfxrE20bG/vU1Cr5e1AD6IEIjQ==}
+  /@esbuild/android-x64@0.19.4:
+    resolution: {integrity: sha512-4iPufZ1TMOD3oBlGFqHXBpa3KFT46aLl6Vy7gwed0ZSYgHaZ/mihbYb4t7Z9etjkC9Al3ZYIoOaHrU60gcMy7g==}
     engines: {node: '>=12'}
     cpu: [x64]
     os: [android]
@@ -2460,8 +2358,8 @@ packages:
     requiresBuild: true
     optional: true
 
-  /@esbuild/darwin-arm64@0.19.3:
-    resolution: {integrity: sha512-kw7e3FXU+VsJSSSl2nMKvACYlwtvZB8RUIeVShIEY6PVnuZ3c9+L9lWB2nWeeKWNNYDdtL19foCQ0ZyUL7nqGw==}
+  /@esbuild/darwin-arm64@0.19.4:
+    resolution: {integrity: sha512-Lviw8EzxsVQKpbS+rSt6/6zjn9ashUZ7Tbuvc2YENgRl0yZTktGlachZ9KMJUsVjZEGFVu336kl5lBgDN6PmpA==}
     engines: {node: '>=12'}
     cpu: [arm64]
     os: [darwin]
@@ -2493,8 +2391,8 @@ packages:
     requiresBuild: true
     optional: true
 
-  /@esbuild/darwin-x64@0.19.3:
-    resolution: {integrity: sha512-tPfZiwF9rO0jW6Jh9ipi58N5ZLoSjdxXeSrAYypy4psA2Yl1dAMhM71KxVfmjZhJmxRjSnb29YlRXXhh3GqzYw==}
+  /@esbuild/darwin-x64@0.19.4:
+    resolution: {integrity: sha512-YHbSFlLgDwglFn0lAO3Zsdrife9jcQXQhgRp77YiTDja23FrC2uwnhXMNkAucthsf+Psr7sTwYEryxz6FPAVqw==}
     engines: {node: '>=12'}
     cpu: [x64]
     os: [darwin]
@@ -2526,8 +2424,8 @@ packages:
     requiresBuild: true
     optional: true
 
-  /@esbuild/freebsd-arm64@0.19.3:
-    resolution: {integrity: sha512-ERDyjOgYeKe0Vrlr1iLrqTByB026YLPzTytDTz1DRCYM+JI92Dw2dbpRHYmdqn6VBnQ9Bor6J8ZlNwdZdxjlSg==}
+  /@esbuild/freebsd-arm64@0.19.4:
+    resolution: {integrity: sha512-vz59ijyrTG22Hshaj620e5yhs2dU1WJy723ofc+KUgxVCM6zxQESmWdMuVmUzxtGqtj5heHyB44PjV/HKsEmuQ==}
     engines: {node: '>=12'}
     cpu: [arm64]
     os: [freebsd]
@@ -2559,8 +2457,8 @@ packages:
     requiresBuild: true
     optional: true
 
-  /@esbuild/freebsd-x64@0.19.3:
-    resolution: {integrity: sha512-nXesBZ2Ad1qL+Rm3crN7NmEVJ5uvfLFPLJev3x1j3feCQXfAhoYrojC681RhpdOph8NsvKBBwpYZHR7W0ifTTA==}
+  /@esbuild/freebsd-x64@0.19.4:
+    resolution: {integrity: sha512-3sRbQ6W5kAiVQRBWREGJNd1YE7OgzS0AmOGjDmX/qZZecq8NFlQsQH0IfXjjmD0XtUYqr64e0EKNFjMUlPL3Cw==}
     engines: {node: '>=12'}
     cpu: [x64]
     os: [freebsd]
@@ -2592,8 +2490,8 @@ packages:
     requiresBuild: true
     optional: true
 
-  /@esbuild/linux-arm64@0.19.3:
-    resolution: {integrity: sha512-qXvYKmXj8GcJgWq3aGvxL/JG1ZM3UR272SdPU4QSTzD0eymrM7leiZH77pvY3UetCy0k1xuXZ+VPvoJNdtrsWQ==}
+  /@esbuild/linux-arm64@0.19.4:
+    resolution: {integrity: sha512-ZWmWORaPbsPwmyu7eIEATFlaqm0QGt+joRE9sKcnVUG3oBbr/KYdNE2TnkzdQwX6EDRdg/x8Q4EZQTXoClUqqA==}
     engines: {node: '>=12'}
     cpu: [arm64]
     os: [linux]
@@ -2625,8 +2523,8 @@ packages:
     requiresBuild: true
     optional: true
 
-  /@esbuild/linux-arm@0.19.3:
-    resolution: {integrity: sha512-zr48Cg/8zkzZCzDHNxXO/89bf9e+r4HtzNUPoz4GmgAkF1gFAFmfgOdCbR8zMbzFDGb1FqBBhdXUpcTQRYS1cQ==}
+  /@esbuild/linux-arm@0.19.4:
+    resolution: {integrity: sha512-z/4ArqOo9EImzTi4b6Vq+pthLnepFzJ92BnofU1jgNlcVb+UqynVFdoXMCFreTK7FdhqAzH0vmdwW5373Hm9pg==}
     engines: {node: '>=12'}
     cpu: [arm]
     os: [linux]
@@ -2658,8 +2556,8 @@ packages:
     requiresBuild: true
     optional: true
 
-  /@esbuild/linux-ia32@0.19.3:
-    resolution: {integrity: sha512-7XlCKCA0nWcbvYpusARWkFjRQNWNGlt45S+Q18UeS///K6Aw8bB2FKYe9mhVWy/XLShvCweOLZPrnMswIaDXQA==}
+  /@esbuild/linux-ia32@0.19.4:
+    resolution: {integrity: sha512-EGc4vYM7i1GRUIMqRZNCTzJh25MHePYsnQfKDexD8uPTCm9mK56NIL04LUfX2aaJ+C9vyEp2fJ7jbqFEYgO9lQ==}
     engines: {node: '>=12'}
     cpu: [ia32]
     os: [linux]
@@ -2700,8 +2598,8 @@ packages:
     requiresBuild: true
     optional: true
 
-  /@esbuild/linux-loong64@0.19.3:
-    resolution: {integrity: sha512-qGTgjweER5xqweiWtUIDl9OKz338EQqCwbS9c2Bh5jgEH19xQ1yhgGPNesugmDFq+UUSDtWgZ264st26b3de8A==}
+  /@esbuild/linux-loong64@0.19.4:
+    resolution: {integrity: sha512-WVhIKO26kmm8lPmNrUikxSpXcgd6HDog0cx12BUfA2PkmURHSgx9G6vA19lrlQOMw+UjMZ+l3PpbtzffCxFDRg==}
     engines: {node: '>=12'}
     cpu: [loong64]
     os: [linux]
@@ -2733,8 +2631,8 @@ packages:
     requiresBuild: true
     optional: true
 
-  /@esbuild/linux-mips64el@0.19.3:
-    resolution: {integrity: sha512-gy1bFskwEyxVMFRNYSvBauDIWNggD6pyxUksc0MV9UOBD138dKTzr8XnM2R4mBsHwVzeuIH8X5JhmNs2Pzrx+A==}
+  /@esbuild/linux-mips64el@0.19.4:
+    resolution: {integrity: sha512-keYY+Hlj5w86hNp5JJPuZNbvW4jql7c1eXdBUHIJGTeN/+0QFutU3GrS+c27L+NTmzi73yhtojHk+lr2+502Mw==}
     engines: {node: '>=12'}
     cpu: [mips64el]
     os: [linux]
@@ -2766,8 +2664,8 @@ packages:
     requiresBuild: true
     optional: true
 
-  /@esbuild/linux-ppc64@0.19.3:
-    resolution: {integrity: sha512-UrYLFu62x1MmmIe85rpR3qou92wB9lEXluwMB/STDzPF9k8mi/9UvNsG07Tt9AqwPQXluMQ6bZbTzYt01+Ue5g==}
+  /@esbuild/linux-ppc64@0.19.4:
+    resolution: {integrity: sha512-tQ92n0WMXyEsCH4m32S21fND8VxNiVazUbU4IUGVXQpWiaAxOBvtOtbEt3cXIV3GEBydYsY8pyeRMJx9kn3rvw==}
     engines: {node: '>=12'}
     cpu: [ppc64]
     os: [linux]
@@ -2799,8 +2697,8 @@ packages:
     requiresBuild: true
     optional: true
 
-  /@esbuild/linux-riscv64@0.19.3:
-    resolution: {integrity: sha512-9E73TfyMCbE+1AwFOg3glnzZ5fBAFK4aawssvuMgCRqCYzE0ylVxxzjEfut8xjmKkR320BEoMui4o/t9KA96gA==}
+  /@esbuild/linux-riscv64@0.19.4:
+    resolution: {integrity: sha512-tRRBey6fG9tqGH6V75xH3lFPpj9E8BH+N+zjSUCnFOX93kEzqS0WdyJHkta/mmJHn7MBaa++9P4ARiU4ykjhig==}
     engines: {node: '>=12'}
     cpu: [riscv64]
     os: [linux]
@@ -2832,8 +2730,8 @@ packages:
     requiresBuild: true
     optional: true
 
-  /@esbuild/linux-s390x@0.19.3:
-    resolution: {integrity: sha512-LlmsbuBdm1/D66TJ3HW6URY8wO6IlYHf+ChOUz8SUAjVTuaisfuwCOAgcxo3Zsu3BZGxmI7yt//yGOxV+lHcEA==}
+  /@esbuild/linux-s390x@0.19.4:
+    resolution: {integrity: sha512-152aLpQqKZYhThiJ+uAM4PcuLCAOxDsCekIbnGzPKVBRUDlgaaAfaUl5NYkB1hgY6WN4sPkejxKlANgVcGl9Qg==}
     engines: {node: '>=12'}
     cpu: [s390x]
     os: [linux]
@@ -2865,8 +2763,8 @@ packages:
     requiresBuild: true
     optional: true
 
-  /@esbuild/linux-x64@0.19.3:
-    resolution: {integrity: sha512-ogV0+GwEmvwg/8ZbsyfkYGaLACBQWDvO0Kkh8LKBGKj9Ru8VM39zssrnu9Sxn1wbapA2qNS6BiLdwJZGouyCwQ==}
+  /@esbuild/linux-x64@0.19.4:
+    resolution: {integrity: sha512-Mi4aNA3rz1BNFtB7aGadMD0MavmzuuXNTaYL6/uiYIs08U7YMPETpgNn5oue3ICr+inKwItOwSsJDYkrE9ekVg==}
     engines: {node: '>=12'}
     cpu: [x64]
     os: [linux]
@@ -2898,8 +2796,8 @@ packages:
     requiresBuild: true
     optional: true
 
-  /@esbuild/netbsd-x64@0.19.3:
-    resolution: {integrity: sha512-o1jLNe4uzQv2DKXMlmEzf66Wd8MoIhLNO2nlQBHLtWyh2MitDG7sMpfCO3NTcoTMuqHjfufgUQDFRI5C+xsXQw==}
+  /@esbuild/netbsd-x64@0.19.4:
+    resolution: {integrity: sha512-9+Wxx1i5N/CYo505CTT7T+ix4lVzEdz0uCoYGxM5JDVlP2YdDC1Bdz+Khv6IbqmisT0Si928eAxbmGkcbiuM/A==}
     engines: {node: '>=12'}
     cpu: [x64]
     os: [netbsd]
@@ -2931,8 +2829,8 @@ packages:
     requiresBuild: true
     optional: true
 
-  /@esbuild/openbsd-x64@0.19.3:
-    resolution: {integrity: sha512-AZJCnr5CZgZOdhouLcfRdnk9Zv6HbaBxjcyhq0StNcvAdVZJSKIdOiPB9az2zc06ywl0ePYJz60CjdKsQacp5Q==}
+  /@esbuild/openbsd-x64@0.19.4:
+    resolution: {integrity: sha512-MFsHleM5/rWRW9EivFssop+OulYVUoVcqkyOkjiynKBCGBj9Lihl7kh9IzrreDyXa4sNkquei5/DTP4uCk25xw==}
     engines: {node: '>=12'}
     cpu: [x64]
     os: [openbsd]
@@ -2964,8 +2862,8 @@ packages:
     requiresBuild: true
     optional: true
 
-  /@esbuild/sunos-x64@0.19.3:
-    resolution: {integrity: sha512-Acsujgeqg9InR4glTRvLKGZ+1HMtDm94ehTIHKhJjFpgVzZG9/pIcWW/HA/DoMfEyXmANLDuDZ2sNrWcjq1lxw==}
+  /@esbuild/sunos-x64@0.19.4:
+    resolution: {integrity: sha512-6Xq8SpK46yLvrGxjp6HftkDwPP49puU4OF0hEL4dTxqCbfx09LyrbUj/D7tmIRMj5D5FCUPksBbxyQhp8tmHzw==}
     engines: {node: '>=12'}
     cpu: [x64]
     os: [sunos]
@@ -2997,8 +2895,8 @@ packages:
     requiresBuild: true
     optional: true
 
-  /@esbuild/win32-arm64@0.19.3:
-    resolution: {integrity: sha512-FSrAfjVVy7TifFgYgliiJOyYynhQmqgPj15pzLyJk8BUsnlWNwP/IAy6GAiB1LqtoivowRgidZsfpoYLZH586A==}
+  /@esbuild/win32-arm64@0.19.4:
+    resolution: {integrity: sha512-PkIl7Jq4mP6ke7QKwyg4fD4Xvn8PXisagV/+HntWoDEdmerB2LTukRZg728Yd1Fj+LuEX75t/hKXE2Ppk8Hh1w==}
     engines: {node: '>=12'}
     cpu: [arm64]
     os: [win32]
@@ -3030,8 +2928,8 @@ packages:
     requiresBuild: true
     optional: true
 
-  /@esbuild/win32-ia32@0.19.3:
-    resolution: {integrity: sha512-xTScXYi12xLOWZ/sc5RBmMN99BcXp/eEf7scUC0oeiRoiT5Vvo9AycuqCp+xdpDyAU+LkrCqEpUS9fCSZF8J3Q==}
+  /@esbuild/win32-ia32@0.19.4:
+    resolution: {integrity: sha512-ga676Hnvw7/ycdKB53qPusvsKdwrWzEyJ+AtItHGoARszIqvjffTwaaW3b2L6l90i7MO9i+dlAW415INuRhSGg==}
     engines: {node: '>=12'}
     cpu: [ia32]
     os: [win32]
@@ -3063,8 +2961,8 @@ packages:
     requiresBuild: true
     optional: true
 
-  /@esbuild/win32-x64@0.19.3:
-    resolution: {integrity: sha512-FbUN+0ZRXsypPyWE2IwIkVjDkDnJoMJARWOcFZn4KPPli+QnKqF0z1anvfaYe3ev5HFCpRDLLBDHyOALLppWHw==}
+  /@esbuild/win32-x64@0.19.4:
+    resolution: {integrity: sha512-HP0GDNla1T3ZL8Ko/SHAS2GgtjOg+VmWnnYLhuTksr++EnduYB0f3Y2LzHsUwb2iQ13JGoY6G3R8h6Du/WG6uA==}
     engines: {node: '>=12'}
     cpu: [x64]
     os: [win32]
@@ -3078,22 +2976,22 @@ packages:
       eslint: ^6.0.0 || ^7.0.0 || >=8.0.0
     dependencies:
       eslint: 8.45.0
-      eslint-visitor-keys: 3.4.1
+      eslint-visitor-keys: 3.4.3
     dev: true
 
-  /@eslint-community/regexpp@4.6.1:
-    resolution: {integrity: sha512-O7x6dMstWLn2ktjcoiNLDkAGG2EjveHL+Vvc+n0fXumkJYAcSqcVYKtwDU+hDZ0uDUsnUagSYaZrOLAYE8un1A==}
+  /@eslint-community/regexpp@4.9.1:
+    resolution: {integrity: sha512-Y27x+MBLjXa+0JWDhykM3+JE+il3kHKAEqabfEWq3SDhZjLYb6/BHL/JKFnH3fe207JaXkyDo685Oc2Glt6ifA==}
     engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0}
     dev: true
 
-  /@eslint/eslintrc@2.1.0:
-    resolution: {integrity: sha512-Lj7DECXqIVCqnqjjHMPna4vn6GJcMgul/wuS0je9OZ9gsL0zzDpKPVtcG1HaDVc+9y+qgXneTeUMbCqXJNpH1A==}
+  /@eslint/eslintrc@2.1.2:
+    resolution: {integrity: sha512-+wvgpDsrB1YqAMdEUCcnTlpfVBH7Vqn6A/NT3D8WVXFIaKMlErPIZT3oCIAVCOtarRpMtelZLqJeU3t7WY6X6g==}
     engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
     dependencies:
       ajv: 6.12.6
       debug: 4.3.4
       espree: 9.6.1
-      globals: 13.20.0
+      globals: 13.23.0
       ignore: 5.2.4
       import-fresh: 3.3.0
       js-yaml: 4.1.0
@@ -3128,17 +3026,21 @@ packages:
       text-decoding: 1.0.0
     dev: false
 
+  /@fastify/busboy@2.0.0:
+    resolution: {integrity: sha512-JUFJad5lv7jxj926GPgymrWQxxjPYuJNiNjNMzqT+HiuP6Vl3dk5xzG+8sTX96np0ZAluvaMzPsjhHZ5rNuNQQ==}
+    engines: {node: '>=14'}
+
   /@fastify/cookie@8.3.0:
     resolution: {integrity: sha512-P9hY9GO11L20TnZ33XN3i0bt+3x0zaT7S0ohAzWO950E9PB2xnNhLYzPFJIGFi5AVN0yr5+/iZhWxeYvR6KCzg==}
     dependencies:
       cookie: 0.5.0
-      fastify-plugin: 4.5.0
+      fastify-plugin: 4.5.1
     dev: false
 
   /@fastify/cors@8.3.0:
     resolution: {integrity: sha512-oj9xkka2Tg0MrwuKhsSUumcAkfp2YCnKxmFEusi01pjk1YrdDsuSYTHXEelWNW+ilSy/ApZq0c2SvhKrLX0H1g==}
     dependencies:
-      fastify-plugin: 4.5.0
+      fastify-plugin: 4.5.1
       mnemonist: 0.39.5
     dev: false
 
@@ -3150,33 +3052,33 @@ packages:
     resolution: {integrity: sha512-sj1ehQZPD6tty+6bhzZw1uS2K2s6eOB46maJ2fE+AuTYxdHKVVW/AHXqCYGu3nH9kgzdXsheu3/148ZoBeoQOw==}
     dependencies:
       env-schema: 5.2.0
-      fastify-plugin: 4.5.0
+      fastify-plugin: 4.5.1
     dev: false
 
-  /@fastify/error@3.2.1:
-    resolution: {integrity: sha512-scZVbcpPNWw/yyFmzzO7cf1daTeJp53spN2n7dBTHZd+cV7791fcWJCPP1Tfhdbre+8vDiCyQyqqXfQnYMntYQ==}
+  /@fastify/error@3.4.0:
+    resolution: {integrity: sha512-e/mafFwbK3MNqxUcFBLgHhgxsF8UT1m8aj0dAlqEa2nJEgPsRtpHTZ3ObgrgkZ2M1eJHPTwgyUl/tXkvabsZdQ==}
     dev: false
 
   /@fastify/fast-json-stringify-compiler@4.3.0:
     resolution: {integrity: sha512-aZAXGYo6m22Fk1zZzEUKBvut/CIIQe/BapEORnxiD5Qr0kPHqqI69NtEMCme74h+at72sPhbkb4ZrLd1W3KRLA==}
     dependencies:
-      fast-json-stringify: 5.7.0
+      fast-json-stringify: 5.8.0
     dev: false
 
   /@fastify/jwt@7.2.0:
     resolution: {integrity: sha512-ONKobJVfFKaqUU3OEWHnkV0HVyJFfa+kzj8gEODEskhIXcf0Y8Trzsjca/Rl54VOsa5QnSgkZEXUpvChd3eUdQ==}
     dependencies:
-      '@fastify/error': 3.2.1
+      '@fastify/error': 3.4.0
       '@lukeed/ms': 2.0.1
-      fast-jwt: 3.1.1
-      fastify-plugin: 4.5.0
+      fast-jwt: 3.3.1
+      fastify-plugin: 4.5.1
       steed: 1.1.3
     dev: false
 
   /@fastify/mongodb@7.0.0:
     resolution: {integrity: sha512-NbneaY3iA+ZcWJWYObXVd+1tbBRqdA021h/hpyccd/dRMrvaKlGheVdmtGJFsHYw7lsJkTV+bciFrwi97JMYfg==}
     dependencies:
-      fastify-plugin: 4.5.0
+      fastify-plugin: 4.5.1
       mongodb: 5.7.0
     transitivePeerDependencies:
       - '@aws-sdk/credential-providers'
@@ -3191,11 +3093,11 @@ packages:
     dependencies:
       '@fastify/busboy': 1.2.1
       '@fastify/deepmerge': 1.3.0
-      '@fastify/error': 3.2.1
-      '@fastify/swagger': 8.10.0
-      '@fastify/swagger-ui': 1.9.3
+      '@fastify/error': 3.4.0
+      '@fastify/swagger': 8.11.0
+      '@fastify/swagger-ui': 1.10.0
       end-of-stream: 1.4.4
-      fastify-plugin: 4.5.0
+      fastify-plugin: 4.5.1
       secure-json-parse: 2.7.0
       stream-wormhole: 1.1.0
     transitivePeerDependencies:
@@ -3206,7 +3108,7 @@ packages:
     resolution: {integrity: sha512-7a4tE4rL4BHqJiJsXVT6oHrAG9xzQx1kEs41yLCBsJ6CRy6PbBNs+q3iOt12gIY8OrfTAdvknxi1uTLgn08ggg==}
     dependencies:
       '@fastify/cookie': 8.3.0
-      fastify-plugin: 4.5.0
+      fastify-plugin: 4.5.1
       simple-oauth2: 5.0.0
     transitivePeerDependencies:
       - supports-color
@@ -3215,15 +3117,15 @@ packages:
   /@fastify/rate-limit@8.0.3:
     resolution: {integrity: sha512-7wbSKXGKKLI1VkpW2XvS7SFg4n4/uzYt0YA5O2pfCcM6PYaBSV3VhSKGJ9/hJceCSH+zNEDRrWpufqxbcDkTZg==}
     dependencies:
-      fastify-plugin: 4.5.0
+      fastify-plugin: 4.5.1
       ms: 2.1.3
-      tiny-lru: 11.0.1
+      tiny-lru: 11.2.2
     dev: false
 
   /@fastify/redis@6.1.1:
     resolution: {integrity: sha512-NZpHK+d3uJJ+w1iHx5n1woFvrHhhG52XjM9byWvU81KSsQpO0N/OikgQvz83frLV7UD4UQtTUgPvVbLxW0X81w==}
     dependencies:
-      fastify-plugin: 4.5.0
+      fastify-plugin: 4.5.1
       ioredis: 5.3.2
     transitivePeerDependencies:
       - supports-color
@@ -3245,26 +3147,26 @@ packages:
       '@fastify/accept-negotiator': 1.1.0
       '@fastify/send': 2.1.0
       content-disposition: 0.5.4
-      fastify-plugin: 4.5.0
+      fastify-plugin: 4.5.1
       glob: 8.1.0
       p-limit: 3.1.0
-      readable-stream: 4.4.0
+      readable-stream: 4.4.2
     dev: false
 
-  /@fastify/swagger-ui@1.9.3:
-    resolution: {integrity: sha512-YYqce4CydjDIEry6Zo4JLjVPe5rjS8iGnk3fHiIQnth9sFSLeyG0U1DCH+IyYmLddNDg1uWJOuErlVqnu/jI3w==}
+  /@fastify/swagger-ui@1.10.0:
+    resolution: {integrity: sha512-vps8KRDQ8JWQGG9Dh6fCOzAc81Y5a6RnCU/Sumyw3n7+HXJSYExnLLgv4aS9eRFSODtQ8kzZJ//IxAbf0nZ+sQ==}
     dependencies:
       '@fastify/static': 6.10.2
-      fastify-plugin: 4.5.0
+      fastify-plugin: 4.5.1
       openapi-types: 12.1.3
       rfdc: 1.3.0
       yaml: 2.3.2
     dev: false
 
-  /@fastify/swagger@8.10.0:
-    resolution: {integrity: sha512-0o6nd0qWpJbVSv/vbK4bzHSYe7l+PTGPqrQVwWIXVGd7CvXr585SBx+h8EgrMOY80bcOnGreqnjYFOV0osGP5A==}
+  /@fastify/swagger@8.11.0:
+    resolution: {integrity: sha512-K8hAWr3wTBUojjJfNUy0TAl766ga2O/L5mWVbBZ6MImOOB3GYUgqNXC4MKrOejt8Y4Ps4cdKjkgzWLcUtg8SFg==}
     dependencies:
-      fastify-plugin: 4.5.0
+      fastify-plugin: 4.5.1
       json-schema-resolver: 2.0.0
       openapi-types: 12.1.3
       rfdc: 1.3.0
@@ -3276,40 +3178,46 @@ packages:
   /@fastify/view@8.0.0:
     resolution: {integrity: sha512-XfAffgqRj+AtEtkZeAAkMwTtu32Ve6xWkhxWQ9JOwXm2qQM6Fj+xphxnLvqpvQ0hJAYFYGiTOpB5ZS2VI5u00Q==}
     dependencies:
-      fastify-plugin: 4.5.0
+      fastify-plugin: 4.5.1
       hashlru: 2.3.0
     dev: false
 
   /@fastify/websocket@8.2.0:
     resolution: {integrity: sha512-B4tlHFBKCX7tenEG9aUcQEpksW2e0+dgRTaH/05+cro1Xsq1+kSj+9IB9Gep7a0KbHZGrat+zBsOas6lRs5dFQ==}
     dependencies:
-      fastify-plugin: 4.5.0
-      ws: 8.13.0
+      fastify-plugin: 4.5.1
+      ws: 8.14.2
     transitivePeerDependencies:
       - bufferutil
       - utf-8-validate
     dev: false
 
-  /@floating-ui/core@1.3.1:
-    resolution: {integrity: sha512-Bu+AMaXNjrpjh41znzHqaz3r2Nr8hHuHZT6V2LBKMhyMl0FgKA62PNYbqnfgmzOhoWZj70Zecisbo4H1rotP5g==}
+  /@floating-ui/core@1.5.0:
+    resolution: {integrity: sha512-kK1h4m36DQ0UHGj5Ah4db7R0rHemTqqO0QLvUqi1/mUUp3LuAWbWxdxSIf/XsnH9VS6rRVPLJCncjRzUvyCLXg==}
+    dependencies:
+      '@floating-ui/utils': 0.1.6
     dev: false
 
   /@floating-ui/dom@1.4.5:
     resolution: {integrity: sha512-96KnRWkRnuBSSFbj0sFGwwOUd8EkiecINVl0O9wiZlZ64EkpyAOG3Xc2vKKNJmru0Z7RqWNymA+6b8OZqjgyyw==}
     dependencies:
-      '@floating-ui/core': 1.3.1
+      '@floating-ui/core': 1.5.0
+    dev: false
+
+  /@floating-ui/utils@0.1.6:
+    resolution: {integrity: sha512-OfX7E2oUDYxtBvsuS4e/jSn4Q9Qb6DzgeYtsAdkPZ47znpoNsMgZw0+tVijiv3uGNR6dgNlty6r9rzIzHjtd/A==}
     dev: false
 
   /@fontsource/nunito@5.0.8:
     resolution: {integrity: sha512-Sb5uROR+aiS6T0CshbDAkjHmLXyWkWXCkDnx4K8fbRFPfmLpw6vKCu4iwb0+RuJDX519o98H/Qouk6p1umkFEQ==}
     dev: false
 
-  /@graphql-typed-document-node/core@3.2.0(graphql@16.7.1):
+  /@graphql-typed-document-node/core@3.2.0(graphql@16.8.1):
     resolution: {integrity: sha512-mB9oAsNCm9aM3/SOv4YtBMqZbYj10R7dkq8byBqxGY/ncFwhf2oQzMV+LCRlWoDSEBJ3COiR1yeDvMtsoOsuFQ==}
     peerDependencies:
       graphql: ^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0
     dependencies:
-      graphql: 16.7.1
+      graphql: 16.8.1
     dev: false
 
   /@hapi/boom@10.0.1:
@@ -3348,10 +3256,10 @@ packages:
       '@hapi/hoek': 11.0.2
     dev: false
 
-  /@hocuspocus/common@2.5.0:
-    resolution: {integrity: sha512-TpnQAb1Rtff1trwURFWaUEYZwqykaIGo6NNnMr6ZISdDZFWNHMAMUmy7dwJDS9ECnEtcjXhpPxXeLV+MVQXVnw==}
+  /@hocuspocus/common@2.6.1:
+    resolution: {integrity: sha512-s6//HV4D8Oav3uFHZKWcKtKaKPd6j2hidmplFKufgh1dSKeZ6psiNv9SzB3GUYPva7Vw81dWbJ2U8fkOYNqHzg==}
     dependencies:
-      lib0: 0.2.78
+      lib0: 0.2.86
     dev: false
 
   /@hocuspocus/extension-database@2.5.0(y-protocols@1.0.5)(yjs@13.6.7):
@@ -3378,7 +3286,7 @@ packages:
       kleur: 4.1.5
       lodash.debounce: 4.0.8
       redlock: 4.2.0
-      uuid: 9.0.0
+      uuid: 9.0.1
       y-protocols: 1.0.5
       yjs: 13.6.7
     transitivePeerDependencies:
@@ -3393,9 +3301,9 @@ packages:
       y-protocols: ^1.0.5
       yjs: ^13.6.4
     dependencies:
-      '@hocuspocus/common': 2.5.0
+      '@hocuspocus/common': 2.6.1
       '@lifeomic/attempt': 3.0.3
-      lib0: 0.2.78
+      lib0: 0.2.86
       ws: 7.5.9
       y-protocols: 1.0.5
       yjs: 13.6.7
@@ -3410,12 +3318,12 @@ packages:
       y-protocols: ^1.0.5
       yjs: ^13.6.4
     dependencies:
-      '@hocuspocus/common': 2.5.0
+      '@hocuspocus/common': 2.6.1
       async-lock: 1.4.0
       kleur: 4.1.5
-      lib0: 0.2.78
-      uuid: 9.0.0
-      ws: 8.13.0
+      lib0: 0.2.86
+      uuid: 9.0.1
+      ws: 8.14.2
       y-protocols: 1.0.5
       yjs: 13.6.7
     transitivePeerDependencies:
@@ -3432,13 +3340,13 @@ packages:
     dependencies:
       '@tiptap/core': 2.1.8(@tiptap/pm@2.1.8)
       '@tiptap/pm': 2.1.8
-      '@tiptap/starter-kit': 2.0.3(@tiptap/pm@2.1.8)
-      y-prosemirror: 1.2.1(prosemirror-model@1.19.2)(prosemirror-state@1.4.3)(prosemirror-view@1.31.4)(y-protocols@1.0.5)(yjs@13.6.7)
+      '@tiptap/starter-kit': 2.1.11(@tiptap/pm@2.1.8)
+      y-prosemirror: 1.2.1(prosemirror-model@1.19.3)(prosemirror-state@1.4.3)(prosemirror-view@1.32.0)(y-protocols@1.0.5)(yjs@13.6.7)
       yjs: 13.6.7
     dev: false
 
-  /@humanwhocodes/config-array@0.11.10:
-    resolution: {integrity: sha512-KVVjQmNUepDVGXNuoRRdmmEjruj0KfiGSbS8LVc12LMsWDQzRXJ0qdhN8L8uUigKpfEHRhlaQFY0ib1tnUbNeQ==}
+  /@humanwhocodes/config-array@0.11.11:
+    resolution: {integrity: sha512-N2brEuAadi0CcdeMXUkhbZB84eskAc8MEX1By6qEchoVywSgXPIjou4rYsl0V3Hj0ZnuGycGCjdNgockbzeWNA==}
     engines: {node: '>=10.10.0'}
     dependencies:
       '@humanwhocodes/object-schema': 1.2.1
@@ -3460,8 +3368,8 @@ packages:
   /@iconify/types@2.0.0:
     resolution: {integrity: sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg==}
 
-  /@iconify/utils@2.1.9:
-    resolution: {integrity: sha512-mo+A4n3MwLlWlg1SoSO+Dt6pOPWKElk9sSJ6ZpuzbB9OcjxN8RUWxU3ulPwB1nglErWKRam2x4BAohbYF7FiFA==}
+  /@iconify/utils@2.1.11:
+    resolution: {integrity: sha512-M/w3PkN8zQYXi8N6qK/KhnYMfEbbb6Sk8RZVn8g+Pmmu5ybw177RpsaGwpziyHeUsu4etrexYSWq3rwnIqzYCg==}
     dependencies:
       '@antfu/install-pkg': 0.1.1
       '@antfu/utils': 0.7.6
@@ -3498,95 +3406,43 @@ packages:
     dependencies:
       '@jridgewell/set-array': 1.1.2
       '@jridgewell/sourcemap-codec': 1.4.15
-      '@jridgewell/trace-mapping': 0.3.18
+      '@jridgewell/trace-mapping': 0.3.19
 
-  /@jridgewell/resolve-uri@3.1.0:
-    resolution: {integrity: sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==}
+  /@jridgewell/resolve-uri@3.1.1:
+    resolution: {integrity: sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==}
     engines: {node: '>=6.0.0'}
 
   /@jridgewell/set-array@1.1.2:
     resolution: {integrity: sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==}
     engines: {node: '>=6.0.0'}
 
-  /@jridgewell/source-map@0.3.3:
-    resolution: {integrity: sha512-b+fsZXeLYi9fEULmfBrhxn4IrPlINf8fiNarzTof004v3lFdntdwa9PF7vFJqm3mg7s+ScJMxXaE3Acp1irZcg==}
+  /@jridgewell/source-map@0.3.5:
+    resolution: {integrity: sha512-UTYAUj/wviwdsMfzoSJspJxbkH5o1snzwX0//0ENX1u/55kkZZkcTZP6u9bwKGkv+dkk9at4m1Cpt0uY80kcpQ==}
     dependencies:
       '@jridgewell/gen-mapping': 0.3.3
-      '@jridgewell/trace-mapping': 0.3.18
-    dev: true
-
-  /@jridgewell/sourcemap-codec@1.4.14:
-    resolution: {integrity: sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==}
+      '@jridgewell/trace-mapping': 0.3.19
 
   /@jridgewell/sourcemap-codec@1.4.15:
     resolution: {integrity: sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==}
 
-  /@jridgewell/trace-mapping@0.3.18:
-    resolution: {integrity: sha512-w+niJYzMHdd7USdiH2U6869nqhD2nbfZXND5Yp93qIbEmnDNk7PD48o+YchRVpzMU7M6jVCbenTR7PA1FLQ9pA==}
+  /@jridgewell/trace-mapping@0.3.19:
+    resolution: {integrity: sha512-kf37QtfW+Hwx/buWGMPcR60iF9ziHa6r/CZJIHbmcm4+0qrXiVdxegAH0F6yddEVQ7zdkjcGCgCzUu+BcbhQxw==}
     dependencies:
-      '@jridgewell/resolve-uri': 3.1.0
-      '@jridgewell/sourcemap-codec': 1.4.14
+      '@jridgewell/resolve-uri': 3.1.1
+      '@jridgewell/sourcemap-codec': 1.4.15
 
   /@lifeomic/attempt@3.0.3:
     resolution: {integrity: sha512-GlM2AbzrErd/TmLL3E8hAHmb5Q7VhDJp35vIbyPVA5Rz55LZuRr8pwL3qrwwkVNo05gMX1J44gURKb4MHQZo7w==}
     dev: false
 
-  /@linaria/core@4.2.9:
-    resolution: {integrity: sha512-ELcu37VNVOT/PU0L6WDIN+aLzNFyJrqoBYT0CucGOCAmODbojUMCv8oJYRbWzA3N34w1t199dN4UFdfRWFG2rg==}
-    engines: {node: ^12.16.0 || >=13.7.0}
-    dependencies:
-      '@linaria/logger': 4.0.0
-      '@linaria/tags': 4.3.5
-      '@linaria/utils': 4.3.4
-    transitivePeerDependencies:
-      - supports-color
+  /@lukeed/ms@2.0.1:
+    resolution: {integrity: sha512-Xs/4RZltsAL7pkvaNStUQt7netTkyxrS0K+RILcVr3TRMS/ToOg4I6uNfhB9SlGsnWBym4U+EaXq0f0cEMNkHA==}
+    engines: {node: '>=8'}
     dev: false
 
-  /@linaria/logger@4.0.0:
-    resolution: {integrity: sha512-YnBq0JlDWMEkTOK+tMo5yEVR0f5V//6qMLToGcLhTyM9g9i+IDFn51Z+5q2hLk7RdG4NBPgbcCXYi2w4RKsPeg==}
-    engines: {node: ^12.16.0 || >=13.7.0}
-    dependencies:
-      debug: 4.3.4
-      picocolors: 1.0.0
-    transitivePeerDependencies:
-      - supports-color
-    dev: false
-
-  /@linaria/tags@4.3.5:
-    resolution: {integrity: sha512-PgaIi8Vv89YOjc6rpKL/uPg2w4k0rAwAYxcqeXqzKqsEAste5rgB8xp1/KUOG0oAOkPd3MRL6Duj+m0ZwJ3g+g==}
-    engines: {node: ^12.16.0 || >=13.7.0}
-    dependencies:
-      '@babel/generator': 7.22.15
-      '@linaria/logger': 4.0.0
-      '@linaria/utils': 4.3.4
-    transitivePeerDependencies:
-      - supports-color
-    dev: false
-
-  /@linaria/utils@4.3.4:
-    resolution: {integrity: sha512-vt6WJG54n+KANaqxOfzIIU7aSfFHEWFbnGLsgxL7nASHqO0zezrNA2y2Rrp80zSeTW+wSpbmDM4uJyC9UW1qoA==}
-    engines: {node: ^12.16.0 || >=13.7.0}
-    dependencies:
-      '@babel/core': 7.22.15
-      '@babel/plugin-proposal-export-namespace-from': 7.18.9(@babel/core@7.22.15)
-      '@babel/plugin-syntax-dynamic-import': 7.8.3(@babel/core@7.22.15)
-      '@babel/plugin-transform-modules-commonjs': 7.22.5(@babel/core@7.22.15)
-      '@babel/traverse': 7.22.15
-      '@babel/types': 7.22.15
-      '@linaria/logger': 4.0.0
-      babel-merge: 3.0.0(@babel/core@7.22.15)
-    transitivePeerDependencies:
-      - supports-color
-    dev: false
-
-  /@lukeed/ms@2.0.1:
-    resolution: {integrity: sha512-Xs/4RZltsAL7pkvaNStUQt7netTkyxrS0K+RILcVr3TRMS/ToOg4I6uNfhB9SlGsnWBym4U+EaXq0f0cEMNkHA==}
-    engines: {node: '>=8'}
-    dev: false
-
-  /@manypkg/find-root@2.1.0:
-    resolution: {integrity: sha512-NEYRVlZCJYhRTqQURhv+WBpDcvmsp/M423Wcdvggv8lYJYD4GtqnTMLrQaTjA10fYt/PIc3tSdwV+wxJnWqPfQ==}
-    engines: {node: '>=14.18.0'}
+  /@manypkg/find-root@2.1.0:
+    resolution: {integrity: sha512-NEYRVlZCJYhRTqQURhv+WBpDcvmsp/M423Wcdvggv8lYJYD4GtqnTMLrQaTjA10fYt/PIc3tSdwV+wxJnWqPfQ==}
+    engines: {node: '>=14.18.0'}
     dependencies:
       '@manypkg/tools': 1.1.0
       '@types/node': 12.20.55
@@ -3608,68 +3464,92 @@ packages:
     resolution: {integrity: sha512-paR9M9ZT7rKbh2boksNUynuSZMHhqRYnEZOm/KrZTjQ4/FzyhjLHuvw/8XYzP+E7fS4+/Ms/82EN1pl/OFsiIA==}
     dev: false
 
+  /@mdx-js/mdx@2.3.0:
+    resolution: {integrity: sha512-jLuwRlz8DQfQNiUCJR50Y09CGPq3fLtmtUQfVrj79E0JWu3dvsVcxVIcfhR5h0iXu+/z++zDrYeiJqifRynJkA==}
+    dependencies:
+      '@types/estree-jsx': 1.0.1
+      '@types/mdx': 2.0.8
+      estree-util-build-jsx: 2.2.2
+      estree-util-is-identifier-name: 2.1.0
+      estree-util-to-js: 1.2.0
+      estree-walker: 3.0.3
+      hast-util-to-estree: 2.3.3
+      markdown-extensions: 1.1.1
+      periscopic: 3.1.0
+      remark-mdx: 2.3.0
+      remark-parse: 10.0.2
+      remark-rehype: 10.1.0
+      unified: 10.1.2
+      unist-util-position-from-estree: 1.1.2
+      unist-util-stringify-position: 3.0.3
+      unist-util-visit: 4.1.2
+      vfile: 5.3.7
+    transitivePeerDependencies:
+      - supports-color
+    dev: false
+
   /@microsoft/fetch-event-source@2.0.1:
     resolution: {integrity: sha512-W6CLUJ2eBMw3Rec70qrsEW0jOm/3twwJv21mrmj2yORiaVmVYGS4sSS5yUwvQc1ZlDLYGPnClVWmUUMagKNsfA==}
     dev: false
 
-  /@motionone/animation@10.15.1:
-    resolution: {integrity: sha512-mZcJxLjHor+bhcPuIFErMDNyrdb2vJur8lSfMCsuCB4UyV8ILZLvK+t+pg56erv8ud9xQGK/1OGPt10agPrCyQ==}
+  /@motionone/animation@10.16.3:
+    resolution: {integrity: sha512-QUGWpLbMFLhyqKlngjZhjtxM8IqiJQjLK0DF+XOF6od9nhSvlaeEpOY/UMCRVcZn/9Tr2rZO22EkuCIjYdI74g==}
     dependencies:
-      '@motionone/easing': 10.15.1
-      '@motionone/types': 10.15.1
-      '@motionone/utils': 10.15.1
-      tslib: 2.5.3
+      '@motionone/easing': 10.16.3
+      '@motionone/types': 10.16.3
+      '@motionone/utils': 10.16.3
+      tslib: 2.6.2
     dev: false
 
-  /@motionone/dom@10.16.2:
-    resolution: {integrity: sha512-bnuHdNbge1FutZXv+k7xub9oPWcF0hsu8y1HTH/qg6av58YI0VufZ3ngfC7p2xhMJMnoh0LXFma2EGTgPeCkeg==}
+  /@motionone/dom@10.16.4:
+    resolution: {integrity: sha512-HPHlVo/030qpRj9R8fgY50KTN4Ko30moWRTA3L3imrsRBmob93cTYmodln49HYFbQm01lFF7X523OkKY0DX6UA==}
     dependencies:
-      '@motionone/animation': 10.15.1
-      '@motionone/generators': 10.15.1
-      '@motionone/types': 10.15.1
-      '@motionone/utils': 10.15.1
+      '@motionone/animation': 10.16.3
+      '@motionone/generators': 10.16.4
+      '@motionone/types': 10.16.3
+      '@motionone/utils': 10.16.3
       hey-listen: 1.0.8
-      tslib: 2.5.3
+      tslib: 2.6.2
     dev: false
 
-  /@motionone/easing@10.15.1:
-    resolution: {integrity: sha512-6hIHBSV+ZVehf9dcKZLT7p5PEKHGhDwky2k8RKkmOvUoYP3S+dXsKupyZpqx5apjd9f+php4vXk4LuS+ADsrWw==}
+  /@motionone/easing@10.16.3:
+    resolution: {integrity: sha512-HWTMZbTmZojzwEuKT/xCdvoMPXjYSyQvuVM6jmM0yoGU6BWzsmYMeB4bn38UFf618fJCNtP9XeC/zxtKWfbr0w==}
     dependencies:
-      '@motionone/utils': 10.15.1
-      tslib: 2.5.3
+      '@motionone/utils': 10.16.3
+      tslib: 2.6.2
     dev: false
 
-  /@motionone/generators@10.15.1:
-    resolution: {integrity: sha512-67HLsvHJbw6cIbLA/o+gsm7h+6D4Sn7AUrB/GPxvujse1cGZ38F5H7DzoH7PhX+sjvtDnt2IhFYF2Zp1QTMKWQ==}
+  /@motionone/generators@10.16.4:
+    resolution: {integrity: sha512-geFZ3w0Rm0ZXXpctWsSf3REGywmLLujEjxPYpBR0j+ymYwof0xbV6S5kGqqsDKgyWKVWpUInqQYvQfL6fRbXeg==}
     dependencies:
-      '@motionone/types': 10.15.1
-      '@motionone/utils': 10.15.1
-      tslib: 2.5.3
+      '@motionone/types': 10.16.3
+      '@motionone/utils': 10.16.3
+      tslib: 2.6.2
     dev: false
 
-  /@motionone/solid@10.16.2(solid-js@1.7.8):
+  /@motionone/solid@10.16.2(solid-js@1.7.11):
     resolution: {integrity: sha512-0bl1KRDWc6BRcKXzRZR2KdRzIIN86SfSe8mcfKPwHYQDzdOEohRcYUsDaYlwWuwU07VCngOHZEPgFCofDJ80zw==}
     peerDependencies:
       solid-js: ^1.5.0
     dependencies:
-      '@motionone/dom': 10.16.2
-      '@motionone/utils': 10.15.1
-      '@solid-primitives/props': 3.1.6(solid-js@1.7.8)
-      '@solid-primitives/refs': 1.0.4(solid-js@1.7.8)
-      '@solid-primitives/transition-group': 1.0.2(solid-js@1.7.8)
-      solid-js: 1.7.8
+      '@motionone/dom': 10.16.4
+      '@motionone/utils': 10.16.3
+      '@solid-primitives/props': 3.1.8(solid-js@1.7.11)
+      '@solid-primitives/refs': 1.0.5(solid-js@1.7.11)
+      '@solid-primitives/transition-group': 1.0.3(solid-js@1.7.11)
+      solid-js: 1.7.11
     dev: false
 
-  /@motionone/types@10.15.1:
-    resolution: {integrity: sha512-iIUd/EgUsRZGrvW0jqdst8st7zKTzS9EsKkP+6c6n4MPZoQHwiHuVtTQLD6Kp0bsBLhNzKIBlHXponn/SDT4hA==}
+  /@motionone/types@10.16.3:
+    resolution: {integrity: sha512-W4jkEGFifDq73DlaZs3HUfamV2t1wM35zN/zX7Q79LfZ2sc6C0R1baUHZmqc/K5F3vSw3PavgQ6HyHLd/MXcWg==}
     dev: false
 
-  /@motionone/utils@10.15.1:
-    resolution: {integrity: sha512-p0YncgU+iklvYr/Dq4NobTRdAPv9PveRDUXabPEeOjBLSO/1FNB2phNTZxOxpi1/GZwYpAoECEa0Wam+nsmhSw==}
+  /@motionone/utils@10.16.3:
+    resolution: {integrity: sha512-WNWDksJIxQkaI9p9Z9z0+K27xdqISGNFy1SsWVGaiedTHq0iaT6iZujby8fT/ZnZxj1EOaxJtSfUPCFNU5CRoA==}
     dependencies:
-      '@motionone/types': 10.15.1
+      '@motionone/types': 10.16.3
       hey-listen: 1.0.8
-      tslib: 2.5.3
+      tslib: 2.6.2
     dev: false
 
   /@nicolo-ribaudo/eslint-scope-5-internals@5.1.1-v1:
@@ -3696,65 +3576,65 @@ packages:
       '@nodelib/fs.scandir': 2.1.5
       fastq: 1.15.0
 
-  /@octokit/app@14.0.0:
-    resolution: {integrity: sha512-g/zDXttroZ9Se08shK0d0d/j0cgSA+h4WV7qGUevNEM0piNBkIlfb4Fm6bSwCNAZhNf72mBgERmYOoxicPkqdw==}
+  /@octokit/app@14.0.1:
+    resolution: {integrity: sha512-4opdXcWBVhzd6FOxlaxDKXXqi9Vz2hsDSWQGNo49HbYFAX11UqMpksMjEdfvHy0x19Pse8Nvn+R6inNb/V398w==}
     engines: {node: '>= 18'}
     dependencies:
-      '@octokit/auth-app': 6.0.0
-      '@octokit/auth-unauthenticated': 5.0.0
-      '@octokit/core': 5.0.0
+      '@octokit/auth-app': 6.0.1
+      '@octokit/auth-unauthenticated': 5.0.1
+      '@octokit/core': 5.0.1
       '@octokit/oauth-app': 6.0.0
-      '@octokit/plugin-paginate-rest': 8.0.0(@octokit/core@5.0.0)
-      '@octokit/types': 11.1.0
+      '@octokit/plugin-paginate-rest': 9.0.0(@octokit/core@5.0.1)
+      '@octokit/types': 12.0.0
       '@octokit/webhooks': 12.0.3
     dev: false
 
-  /@octokit/auth-app@6.0.0:
-    resolution: {integrity: sha512-OKct7Rukf3g9DjpzcpdacQsdmd6oPrJ7fZND22JkjzhDvfhttUOnmh+qPS4kHhaNNyTxqSThnfrUWvkqNLd1nw==}
+  /@octokit/auth-app@6.0.1:
+    resolution: {integrity: sha512-tjCD4nzQNZgmLH62+PSnTF6eGerisFgV4v6euhqJik6yWV96e1ZiiGj+NXIqbgnpjLmtnBqVUrNyGKu3DoGEGA==}
     engines: {node: '>= 18'}
     dependencies:
-      '@octokit/auth-oauth-app': 7.0.0
-      '@octokit/auth-oauth-user': 4.0.0
-      '@octokit/request': 8.1.1
-      '@octokit/request-error': 5.0.0
-      '@octokit/types': 11.1.0
+      '@octokit/auth-oauth-app': 7.0.1
+      '@octokit/auth-oauth-user': 4.0.1
+      '@octokit/request': 8.1.3
+      '@octokit/request-error': 5.0.1
+      '@octokit/types': 12.0.0
       deprecation: 2.3.1
-      lru-cache: 10.0.0
+      lru-cache: 10.0.1
       universal-github-app-jwt: 1.1.1
       universal-user-agent: 6.0.0
     dev: false
 
-  /@octokit/auth-oauth-app@7.0.0:
-    resolution: {integrity: sha512-8JvJEXGoEqrbzLwt3SwIUvkDd+1wrM8up0KawvDIElB8rbxPbvWppGO0SLKAWSJ0q8ILcVq+mWck6pDcZ3a9KA==}
+  /@octokit/auth-oauth-app@7.0.1:
+    resolution: {integrity: sha512-RE0KK0DCjCHXHlQBoubwlLijXEKfhMhKm9gO56xYvFmP1QTMb+vvwRPmQLLx0V+5AvV9N9I3lr1WyTzwL3rMDg==}
     engines: {node: '>= 18'}
     dependencies:
-      '@octokit/auth-oauth-device': 6.0.0
-      '@octokit/auth-oauth-user': 4.0.0
-      '@octokit/request': 8.1.1
-      '@octokit/types': 11.1.0
+      '@octokit/auth-oauth-device': 6.0.1
+      '@octokit/auth-oauth-user': 4.0.1
+      '@octokit/request': 8.1.3
+      '@octokit/types': 12.0.0
       '@types/btoa-lite': 1.0.0
       btoa-lite: 1.0.0
       universal-user-agent: 6.0.0
     dev: false
 
-  /@octokit/auth-oauth-device@6.0.0:
-    resolution: {integrity: sha512-Zgf/LKhwWk54rJaTGYVYtbKgUty+ouil6VQeRd+pCw7Gd0ECoSWaZuHK6uDGC/HtnWHjpSWFhzxPauDoHcNRtg==}
+  /@octokit/auth-oauth-device@6.0.1:
+    resolution: {integrity: sha512-yxU0rkL65QkjbqQedgVx3gmW7YM5fF+r5uaSj9tM/cQGVqloXcqP2xK90eTyYvl29arFVCW8Vz4H/t47mL0ELw==}
     engines: {node: '>= 18'}
     dependencies:
       '@octokit/oauth-methods': 4.0.0
-      '@octokit/request': 8.1.1
-      '@octokit/types': 11.1.0
+      '@octokit/request': 8.1.3
+      '@octokit/types': 12.0.0
       universal-user-agent: 6.0.0
     dev: false
 
-  /@octokit/auth-oauth-user@4.0.0:
-    resolution: {integrity: sha512-VOm5aIkVGHaOhIvsF/4YmSjoYDzzrKbbYkdSEO0KqHK7I8SlO3ZndSikQ1fBlNPUEH0ve2BOTxLrVvI1qBf9/Q==}
+  /@octokit/auth-oauth-user@4.0.1:
+    resolution: {integrity: sha512-N94wWW09d0hleCnrO5wt5MxekatqEJ4zf+1vSe8MKMrhZ7gAXKFOKrDEZW2INltvBWJCyDUELgGRv8gfErH1Iw==}
     engines: {node: '>= 18'}
     dependencies:
-      '@octokit/auth-oauth-device': 6.0.0
+      '@octokit/auth-oauth-device': 6.0.1
       '@octokit/oauth-methods': 4.0.0
-      '@octokit/request': 8.1.1
-      '@octokit/types': 11.1.0
+      '@octokit/request': 8.1.3
+      '@octokit/types': 12.0.0
       btoa-lite: 1.0.0
       universal-user-agent: 6.0.0
     dev: false
@@ -3769,12 +3649,12 @@ packages:
     engines: {node: '>= 18'}
     dev: false
 
-  /@octokit/auth-unauthenticated@5.0.0:
-    resolution: {integrity: sha512-AjOI6FNB2dweJ85p6rf7D4EhE4y6VBcwYfX/7KJkR5Q9fD9ET6NABAjajUTSNFfCxmNIaQgISggZ3pkgwtTqsA==}
+  /@octokit/auth-unauthenticated@5.0.1:
+    resolution: {integrity: sha512-oxeWzmBFxWd+XolxKTc4zr+h3mt+yofn4r7OfoIkR/Cj/o70eEGmPsFbueyJE2iBAGpjgTnEOKM3pnuEGVmiqg==}
     engines: {node: '>= 18'}
     dependencies:
-      '@octokit/request-error': 5.0.0
-      '@octokit/types': 11.1.0
+      '@octokit/request-error': 5.0.1
+      '@octokit/types': 12.0.0
     dev: false
 
   /@octokit/core@4.2.4:
@@ -3792,15 +3672,15 @@ packages:
       - encoding
     dev: false
 
-  /@octokit/core@5.0.0:
-    resolution: {integrity: sha512-YbAtMWIrbZ9FCXbLwT9wWB8TyLjq9mxpKdgB3dUNxQcIVTf9hJ70gRPwAcqGZdY6WdJPZ0I7jLaaNDCiloGN2A==}
+  /@octokit/core@5.0.1:
+    resolution: {integrity: sha512-lyeeeZyESFo+ffI801SaBKmCfsvarO+dgV8/0gD8u1d87clbEdWsP5yC+dSj3zLhb2eIf5SJrn6vDz9AheETHw==}
     engines: {node: '>= 18'}
     dependencies:
       '@octokit/auth-token': 4.0.0
-      '@octokit/graphql': 7.0.1
-      '@octokit/request': 8.1.1
-      '@octokit/request-error': 5.0.0
-      '@octokit/types': 11.1.0
+      '@octokit/graphql': 7.0.2
+      '@octokit/request': 8.1.3
+      '@octokit/request-error': 5.0.1
+      '@octokit/types': 12.0.0
       before-after-hook: 2.2.3
       universal-user-agent: 6.0.0
     dev: false
@@ -3814,11 +3694,11 @@ packages:
       universal-user-agent: 6.0.0
     dev: false
 
-  /@octokit/endpoint@9.0.0:
-    resolution: {integrity: sha512-szrQhiqJ88gghWY2Htt8MqUDO6++E/EIXqJ2ZEp5ma3uGS46o7LZAzSLt49myB7rT+Hfw5Y6gO3LmOxGzHijAQ==}
+  /@octokit/endpoint@9.0.1:
+    resolution: {integrity: sha512-hRlOKAovtINHQPYHZlfyFwaM8OyetxeoC81lAkBy34uLb8exrZB50SQdeW3EROqiY9G9yxQTpp5OHTV54QD+vA==}
     engines: {node: '>= 18'}
     dependencies:
-      '@octokit/types': 11.1.0
+      '@octokit/types': 12.0.0
       is-plain-object: 5.0.0
       universal-user-agent: 6.0.0
     dev: false
@@ -3834,12 +3714,12 @@ packages:
       - encoding
     dev: false
 
-  /@octokit/graphql@7.0.1:
-    resolution: {integrity: sha512-T5S3oZ1JOE58gom6MIcrgwZXzTaxRnxBso58xhozxHpOqSTgDS6YNeEUvZ/kRvXgPrRz/KHnZhtb7jUMRi9E6w==}
+  /@octokit/graphql@7.0.2:
+    resolution: {integrity: sha512-OJ2iGMtj5Tg3s6RaXH22cJcxXRi7Y3EBqbHTBRq+PQAqfaS8f/236fUrWhfSn8P4jovyzqucxme7/vWSSZBX2Q==}
     engines: {node: '>= 18'}
     dependencies:
-      '@octokit/request': 8.1.1
-      '@octokit/types': 11.1.0
+      '@octokit/request': 8.1.3
+      '@octokit/types': 12.0.0
       universal-user-agent: 6.0.0
     dev: false
 
@@ -3847,13 +3727,13 @@ packages:
     resolution: {integrity: sha512-bNMkS+vJ6oz2hCyraT9ZfTpAQ8dZNqJJQVNaKjPLx4ue5RZiFdU1YWXguOPR8AaSHS+lKe+lR3abn2siGd+zow==}
     engines: {node: '>= 18'}
     dependencies:
-      '@octokit/auth-oauth-app': 7.0.0
-      '@octokit/auth-oauth-user': 4.0.0
-      '@octokit/auth-unauthenticated': 5.0.0
-      '@octokit/core': 5.0.0
+      '@octokit/auth-oauth-app': 7.0.1
+      '@octokit/auth-oauth-user': 4.0.1
+      '@octokit/auth-unauthenticated': 5.0.1
+      '@octokit/core': 5.0.1
       '@octokit/oauth-authorization-url': 6.0.2
       '@octokit/oauth-methods': 4.0.0
-      '@types/aws-lambda': 8.10.119
+      '@types/aws-lambda': 8.10.124
       universal-user-agent: 6.0.0
     dev: false
 
@@ -3867,14 +3747,18 @@ packages:
     engines: {node: '>= 18'}
     dependencies:
       '@octokit/oauth-authorization-url': 6.0.2
-      '@octokit/request': 8.1.1
-      '@octokit/request-error': 5.0.0
+      '@octokit/request': 8.1.3
+      '@octokit/request-error': 5.0.1
       '@octokit/types': 11.1.0
       btoa-lite: 1.0.0
     dev: false
 
-  /@octokit/openapi-types@18.0.0:
-    resolution: {integrity: sha512-V8GImKs3TeQRxRtXFpG2wl19V7444NIOTDF24AWuIbmNaNYOQMWRbjcGDXV5B+0n887fgDcuMNOmlul+k+oJtw==}
+  /@octokit/openapi-types@18.1.1:
+    resolution: {integrity: sha512-VRaeH8nCDtF5aXWnjPuEMIYf1itK/s3JYyJcWFJT8X9pSNnBtriDf7wlEWsGuhPLl4QIH4xM8fqTXDwJ3Mu6sw==}
+    dev: false
+
+  /@octokit/openapi-types@19.0.0:
+    resolution: {integrity: sha512-PclQ6JGMTE9iUStpzMkwLCISFn/wDeRjkZFIKALpvJQNBGwDoYYi2fFvuHwssoQ1rXI5mfh6jgTgWuddeUzfWw==}
     dev: false
 
   /@octokit/plugin-paginate-rest@6.1.2(@octokit/core@4.2.4):
@@ -3888,16 +3772,26 @@ packages:
       '@octokit/types': 9.3.2
     dev: false
 
-  /@octokit/plugin-paginate-rest@8.0.0(@octokit/core@5.0.0):
+  /@octokit/plugin-paginate-rest@8.0.0(@octokit/core@5.0.1):
     resolution: {integrity: sha512-2xZ+baZWUg+qudVXnnvXz7qfrTmDeYPCzangBVq/1gXxii/OiS//4shJp9dnCCvj1x+JAm9ji1Egwm1BA47lPQ==}
     engines: {node: '>= 18'}
     peerDependencies:
       '@octokit/core': '>=5'
     dependencies:
-      '@octokit/core': 5.0.0
+      '@octokit/core': 5.0.1
       '@octokit/types': 11.1.0
     dev: false
 
+  /@octokit/plugin-paginate-rest@9.0.0(@octokit/core@5.0.1):
+    resolution: {integrity: sha512-oIJzCpttmBTlEhBmRvb+b9rlnGpmFgDtZ0bB6nq39qIod6A5DP+7RkVLMOixIgRCYSHDTeayWqmiJ2SZ6xgfdw==}
+    engines: {node: '>= 18'}
+    peerDependencies:
+      '@octokit/core': '>=5'
+    dependencies:
+      '@octokit/core': 5.0.1
+      '@octokit/types': 12.0.0
+    dev: false
+
   /@octokit/plugin-request-log@1.0.4(@octokit/core@4.2.4):
     resolution: {integrity: sha512-mLUsMkgP7K/cnFEw07kWqXGF5LKrOkD+lhCrKvPHXWDywAwuDUeDwWBpc69XK3pNX0uKiVt8g5z96PJ6z9xCFA==}
     peerDependencies:
@@ -3906,13 +3800,13 @@ packages:
       '@octokit/core': 4.2.4
     dev: false
 
-  /@octokit/plugin-request-log@4.0.0(@octokit/core@5.0.0):
+  /@octokit/plugin-request-log@4.0.0(@octokit/core@5.0.1):
     resolution: {integrity: sha512-2uJI1COtYCq8Z4yNSnM231TgH50bRkheQ9+aH8TnZanB6QilOnx8RMD2qsnamSOXtDj0ilxvevf5fGsBhBBzKA==}
     engines: {node: '>= 18'}
     peerDependencies:
       '@octokit/core': '>=5'
     dependencies:
-      '@octokit/core': 5.0.0
+      '@octokit/core': 5.0.1
     dev: false
 
   /@octokit/plugin-rest-endpoint-methods@7.2.3(@octokit/core@4.2.4):
@@ -3925,35 +3819,35 @@ packages:
       '@octokit/types': 10.0.0
     dev: false
 
-  /@octokit/plugin-rest-endpoint-methods@9.0.0(@octokit/core@5.0.0):
+  /@octokit/plugin-rest-endpoint-methods@9.0.0(@octokit/core@5.0.1):
     resolution: {integrity: sha512-KquMF/VB1IkKNiVnzJKspY5mFgGyLd7HzdJfVEGTJFzqu9BRFNWt+nwTCMuUiWc72gLQhRWYubTwOkQj+w/1PA==}
     engines: {node: '>= 18'}
     peerDependencies:
       '@octokit/core': '>=5'
     dependencies:
-      '@octokit/core': 5.0.0
+      '@octokit/core': 5.0.1
       '@octokit/types': 11.1.0
     dev: false
 
-  /@octokit/plugin-retry@6.0.0(@octokit/core@5.0.0):
-    resolution: {integrity: sha512-a1/A4A+PB1QoAHQfLJxGHhLfSAT03bR1jJz3GgQJZvty2ozawFWs93MiBQXO7SL2YbO7CIq0Goj4qLOBj8JeMQ==}
+  /@octokit/plugin-retry@6.0.1(@octokit/core@5.0.1):
+    resolution: {integrity: sha512-SKs+Tz9oj0g4p28qkZwl/topGcb0k0qPNX/i7vBKmDsjoeqnVfFUquqrE/O9oJY7+oLzdCtkiWSXLpLjvl6uog==}
     engines: {node: '>= 18'}
     peerDependencies:
       '@octokit/core': '>=5'
     dependencies:
-      '@octokit/core': 5.0.0
-      '@octokit/request-error': 5.0.0
-      '@octokit/types': 11.1.0
+      '@octokit/core': 5.0.1
+      '@octokit/request-error': 5.0.1
+      '@octokit/types': 12.0.0
       bottleneck: 2.19.5
     dev: false
 
-  /@octokit/plugin-throttling@7.0.0(@octokit/core@5.0.0):
+  /@octokit/plugin-throttling@7.0.0(@octokit/core@5.0.1):
     resolution: {integrity: sha512-KL2k/d0uANc8XqP5S64YcNFCudR3F5AaKO39XWdUtlJIjT9Ni79ekWJ6Kj5xvAw87udkOMEPcVf9xEge2+ahew==}
     engines: {node: '>= 18'}
     peerDependencies:
       '@octokit/core': ^5.0.0
     dependencies:
-      '@octokit/core': 5.0.0
+      '@octokit/core': 5.0.1
       '@octokit/types': 11.1.0
       bottleneck: 2.19.5
     dev: false
@@ -3967,11 +3861,11 @@ packages:
       once: 1.4.0
     dev: false
 
-  /@octokit/request-error@5.0.0:
-    resolution: {integrity: sha512-1ue0DH0Lif5iEqT52+Rf/hf0RmGO9NWFjrzmrkArpG9trFfDM/efx00BJHdLGuro4BR/gECxCU2Twf5OKrRFsQ==}
+  /@octokit/request-error@5.0.1:
+    resolution: {integrity: sha512-X7pnyTMV7MgtGmiXBwmO6M5kIPrntOXdyKZLigNfQWSEQzVxR4a4vo49vJjTWX70mPndj8KhfT4Dx+2Ng3vnBQ==}
     engines: {node: '>= 18'}
     dependencies:
-      '@octokit/types': 11.1.0
+      '@octokit/types': 12.0.0
       deprecation: 2.3.1
       once: 1.4.0
     dev: false
@@ -3984,19 +3878,19 @@ packages:
       '@octokit/request-error': 3.0.3
       '@octokit/types': 9.3.2
       is-plain-object: 5.0.0
-      node-fetch: 2.6.12
+      node-fetch: 2.7.0
       universal-user-agent: 6.0.0
     transitivePeerDependencies:
       - encoding
     dev: false
 
-  /@octokit/request@8.1.1:
-    resolution: {integrity: sha512-8N+tdUz4aCqQmXl8FpHYfKG9GelDFd7XGVzyN8rc6WxVlYcfpHECnuRkgquzz+WzvHTK62co5di8gSXnzASZPQ==}
+  /@octokit/request@8.1.3:
+    resolution: {integrity: sha512-iUvXP4QmysS8kyE/a4AGwR0A+tHDVxgW6TmPd2ci8/Xc8KjlBtTKSDpZlUT5Y4S4Nu+eM8LvbOYjVAp/sz3Gpg==}
     engines: {node: '>= 18'}
     dependencies:
-      '@octokit/endpoint': 9.0.0
-      '@octokit/request-error': 5.0.0
-      '@octokit/types': 11.1.0
+      '@octokit/endpoint': 9.0.1
+      '@octokit/request-error': 5.0.1
+      '@octokit/types': 12.0.0
       is-plain-object: 5.0.0
       universal-user-agent: 6.0.0
     dev: false
@@ -4017,10 +3911,10 @@ packages:
     resolution: {integrity: sha512-wROV21RwHQIMNb2Dgd4+pY+dVy1Dwmp85pBrgr6YRRDYRBu9Gb+D73f4Bl2EukZSj5hInq2Tui9o7gAQpc2k2Q==}
     engines: {node: '>= 18'}
     dependencies:
-      '@octokit/core': 5.0.0
-      '@octokit/plugin-paginate-rest': 8.0.0(@octokit/core@5.0.0)
-      '@octokit/plugin-request-log': 4.0.0(@octokit/core@5.0.0)
-      '@octokit/plugin-rest-endpoint-methods': 9.0.0(@octokit/core@5.0.0)
+      '@octokit/core': 5.0.1
+      '@octokit/plugin-paginate-rest': 8.0.0(@octokit/core@5.0.1)
+      '@octokit/plugin-request-log': 4.0.0(@octokit/core@5.0.1)
+      '@octokit/plugin-rest-endpoint-methods': 9.0.0(@octokit/core@5.0.1)
     dev: false
 
   /@octokit/tsconfig@1.0.2:
@@ -4030,19 +3924,25 @@ packages:
   /@octokit/types@10.0.0:
     resolution: {integrity: sha512-Vm8IddVmhCgU1fxC1eyinpwqzXPEYu0NrYzD3YZjlGjyftdLBTeqNblRC0jmJmgxbJIsQlyogVeGnrNaaMVzIg==}
     dependencies:
-      '@octokit/openapi-types': 18.0.0
+      '@octokit/openapi-types': 18.1.1
     dev: false
 
   /@octokit/types@11.1.0:
     resolution: {integrity: sha512-Fz0+7GyLm/bHt8fwEqgvRBWwIV1S6wRRyq+V6exRKLVWaKGsuy6H9QFYeBVDV7rK6fO3XwHgQOPxv+cLj2zpXQ==}
     dependencies:
-      '@octokit/openapi-types': 18.0.0
+      '@octokit/openapi-types': 18.1.1
+    dev: false
+
+  /@octokit/types@12.0.0:
+    resolution: {integrity: sha512-EzD434aHTFifGudYAygnFlS1Tl6KhbTynEWELQXIbTY8Msvb5nEqTZIm7sbPEt4mQYLZwu3zPKVdeIrw0g7ovg==}
+    dependencies:
+      '@octokit/openapi-types': 19.0.0
     dev: false
 
   /@octokit/types@9.3.2:
     resolution: {integrity: sha512-D4iHGTdAnEEVsB8fl95m1hiz7D5YiRdQ9b/OEb3BYRVwbLsGHcRVPz+u+BgRLNk0Q0/4iZCBqDN96j2XNxfXrA==}
     dependencies:
-      '@octokit/openapi-types': 18.0.0
+      '@octokit/openapi-types': 18.1.1
     dev: false
 
   /@octokit/webhooks-methods@4.0.0:
@@ -4058,7 +3958,7 @@ packages:
     resolution: {integrity: sha512-8iG+/yza7hwz1RrQ7i7uGpK2/tuItZxZq1aTmeg2TNp2xTUB8F8lZF/FcZvyyAxT8tpDMF74TjFGCDACkf1kAQ==}
     engines: {node: '>= 18'}
     dependencies:
-      '@octokit/request-error': 5.0.0
+      '@octokit/request-error': 5.0.1
       '@octokit/webhooks-methods': 4.0.0
       '@octokit/webhooks-types': 7.1.0
       aggregate-error: 3.1.0
@@ -4075,8 +3975,8 @@ packages:
     dev: false
     optional: true
 
-  /@pkgr/utils@2.4.1:
-    resolution: {integrity: sha512-JOqwkgFEyi+OROIyq7l4Jy28h/WwhDnG/cPkXG2Z1iFbubB6jsHW1NDvmyOzTBxHr3yg68YGirmh1JUgMqa+9w==}
+  /@pkgr/utils@2.4.2:
+    resolution: {integrity: sha512-POgTXhjrTfbTV63DiFXav4lBHiICLKKwDeaKn9Nphwj7WH6m0hMMCaJkMyRWjgtPFyRKRVoMXXjczsTQRDEhYw==}
     engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0}
     dependencies:
       cross-spawn: 7.0.3
@@ -4084,15 +3984,23 @@ packages:
       is-glob: 4.0.3
       open: 9.1.0
       picocolors: 1.0.0
-      tslib: 2.5.3
+      tslib: 2.6.2
 
-  /@polka/url@1.0.0-next.21:
-    resolution: {integrity: sha512-a5Sab1C4/icpTZVzZc5Ghpz88yQtGOyNqYXcZgOssB2uuAr+wF/MvN6bgtW32q7HHrvBki+BsZ0OuNv6EV3K9g==}
+  /@polka/url@1.0.0-next.23:
+    resolution: {integrity: sha512-C16M+IYz0rgRhWZdCmK+h58JMv8vijAA61gmz2rspCSwKwzBebpdcsiUmwrtJRdphuY30i6BSLEOP8ppbNLyLg==}
 
   /@popperjs/core@2.11.8:
     resolution: {integrity: sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==}
     dev: false
 
+  /@prettier/sync@0.3.0(prettier@3.0.2):
+    resolution: {integrity: sha512-3dcmCyAxIcxy036h1I7MQU/uEEBq8oLwf1CE3xeze+MPlgkdlb/+w6rGR/1dhp6Hqi17fRS6nvwnOzkESxEkOw==}
+    peerDependencies:
+      prettier: ^3.0.0
+    dependencies:
+      prettier: 3.0.2
+    dev: false
+
   /@proload/core@0.3.3:
     resolution: {integrity: sha512-7dAFWsIK84C90AMl24+N/ProHKm4iw0akcnoKjRvbfHifJZBLhaDsDus1QJmhG12lXj4e/uB/8mB/0aduCW+NQ==}
     dependencies:
@@ -4109,19 +4017,19 @@ packages:
       tsm: 2.3.0
     dev: true
 
-  /@qdrant/js-client-grpc@1.4.0(typescript@5.1.6):
+  /@qdrant/js-client-grpc@1.4.0(typescript@5.2.2):
     resolution: {integrity: sha512-Ue30STJz6pHrlvSbox3+7vqU/tSZUywQWeqahDP0TvyxtaOtV1D4nsFkshk5kMpWzPNircNglA7gNdQlnVPxVw==}
     engines: {node: '>=18.0.0', pnpm: '>=8'}
     peerDependencies:
       typescript: '>=4.1'
     dependencies:
-      '@bufbuild/connect': 0.9.1(@bufbuild/protobuf@1.3.0)
-      '@bufbuild/connect-node': 0.9.1(@bufbuild/protobuf@1.3.0)
-      '@bufbuild/protobuf': 1.3.0
-      typescript: 5.1.6
+      '@bufbuild/connect': 0.9.1(@bufbuild/protobuf@1.3.3)
+      '@bufbuild/connect-node': 0.9.1(@bufbuild/protobuf@1.3.3)
+      '@bufbuild/protobuf': 1.3.3
+      typescript: 5.2.2
     dev: false
 
-  /@qdrant/js-client-rest@1.4.0(typescript@5.1.6):
+  /@qdrant/js-client-rest@1.4.0(typescript@5.2.2):
     resolution: {integrity: sha512-I3pCKnaVdqiVpZ9+XtEjCx7IQSJnerXffD/g8mj/fZsOOJH3IFM+nF2izOfVIByufAArW+drGcAPrxHedba99w==}
     engines: {node: '>=18.0.0', pnpm: '>=8'}
     peerDependencies:
@@ -4129,8 +4037,8 @@ packages:
     dependencies:
       '@qdrant/openapi-typescript-fetch': 1.2.1
       '@sevinf/maybe': 0.5.0
-      typescript: 5.1.6
-      undici: 5.22.1
+      typescript: 5.2.2
+      undici: 5.25.4
     dev: false
 
   /@qdrant/openapi-typescript-fetch@1.2.1:
@@ -4138,15 +4046,15 @@ packages:
     engines: {node: '>=12.0.0', pnpm: '>=8'}
     dev: false
 
-  /@qdrant/qdrant-js@1.4.0(typescript@5.1.6):
+  /@qdrant/qdrant-js@1.4.0(typescript@5.2.2):
     resolution: {integrity: sha512-3bqyvmclwCYSQyvp6X2rwTVeXE/3wXp2Y2DUsVWg/uY0FO6jdCKYjqqMmu1wR9UpmLpaFrLqVVPt+nEntTiuAg==}
     engines: {node: '>=18.0.0', pnpm: '>=8'}
     peerDependencies:
       typescript: '>=4.1'
     dependencies:
-      '@qdrant/js-client-grpc': 1.4.0(typescript@5.1.6)
-      '@qdrant/js-client-rest': 1.4.0(typescript@5.1.6)
-      typescript: 5.1.6
+      '@qdrant/js-client-grpc': 1.4.0(typescript@5.2.2)
+      '@qdrant/js-client-rest': 1.4.0(typescript@5.2.2)
+      typescript: 5.2.2
     dev: false
 
   /@radix-ui/react-compose-refs@1.0.0(react@18.2.0):
@@ -4154,7 +4062,7 @@ packages:
     peerDependencies:
       react: ^16.8 || ^17.0 || ^18.0
     dependencies:
-      '@babel/runtime': 7.22.5
+      '@babel/runtime': 7.23.1
       react: 18.2.0
     dev: false
 
@@ -4163,7 +4071,7 @@ packages:
     peerDependencies:
       react: ^16.8 || ^17.0 || ^18.0
     dependencies:
-      '@babel/runtime': 7.22.5
+      '@babel/runtime': 7.23.1
       '@radix-ui/react-compose-refs': 1.0.0(react@18.2.0)
       react: 18.2.0
     dev: false
@@ -4326,20 +4234,16 @@ packages:
       react: 18.2.0
     dev: false
 
-  /@remirror/core-constants@2.0.1:
-    resolution: {integrity: sha512-ZR4aihtnnT9lMbhh5DEbsriJRlukRXmLZe7HmM+6ufJNNUDoazc75UX26xbgQlNUqgAqMcUdGFAnPc1JwgAdLQ==}
-    dependencies:
-      '@babel/runtime': 7.22.5
+  /@remirror/core-constants@2.0.2:
+    resolution: {integrity: sha512-dyHY+sMF0ihPus3O27ODd4+agdHMEmuRdyiZJ2CCWjPV5UFmn17ZbElvk6WOGVE4rdCJKZQCrPV2BcikOMLUGQ==}
     dev: false
 
-  /@remirror/core-helpers@2.0.3:
-    resolution: {integrity: sha512-LqIPF4stGG69l9qu/FFicv9d9B+YaItzgDMC5A0CEvDQfKkGD3BfabLmfpnuWbsc06oKGdTduilgWcALLZoYLg==}
+  /@remirror/core-helpers@3.0.0:
+    resolution: {integrity: sha512-tusEgQJIqg4qKj6HSBUFcyRnWnziw3neh4T9wOmsPGHFC3w9kl5KSrDb9UAgE8uX6y32FnS7vJ955mWOl3n50A==}
     dependencies:
-      '@babel/runtime': 7.22.5
-      '@linaria/core': 4.2.9
-      '@remirror/core-constants': 2.0.1
+      '@remirror/core-constants': 2.0.2
       '@remirror/types': 1.0.1
-      '@types/object.omit': 3.0.0
+      '@types/object.omit': 3.0.1
       '@types/object.pick': 1.3.2
       '@types/throttle-debounce': 2.1.0
       case-anything: 2.1.13
@@ -4350,8 +4254,6 @@ packages:
       object.omit: 3.0.0
       object.pick: 1.3.0
       throttle-debounce: 3.0.1
-    transitivePeerDependencies:
-      - supports-color
     dev: false
 
   /@remirror/types@1.0.1:
@@ -4360,20 +4262,20 @@ packages:
       type-fest: 2.19.0
     dev: false
 
-  /@rollup/plugin-alias@5.0.0(rollup@3.26.2):
-    resolution: {integrity: sha512-l9hY5chSCjuFRPsnRm16twWBiSApl2uYFLsepQYwtBuAxNMQ/1dJqADld40P0Jkqm65GRTLy/AC6hnpVebtLsA==}
+  /@rollup/plugin-alias@5.0.1(rollup@3.29.4):
+    resolution: {integrity: sha512-JObvbWdOHoMy9W7SU0lvGhDtWq9PllP5mjpAy+TUslZG/WzOId9u80Hsqq1vCUn9pFJ0cxpdcnAv+QzU2zFH3Q==}
     engines: {node: '>=14.0.0'}
     peerDependencies:
-      rollup: ^1.20.0||^2.0.0||^3.0.0
+      rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0
     peerDependenciesMeta:
       rollup:
         optional: true
     dependencies:
-      rollup: 3.26.2
+      rollup: 3.29.4
       slash: 4.0.0
     dev: true
 
-  /@rollup/plugin-commonjs@24.1.0(rollup@3.26.2):
+  /@rollup/plugin-commonjs@24.1.0(rollup@3.29.4):
     resolution: {integrity: sha512-eSL45hjhCWI0jCCXcNtLVqM5N1JlBGvlFfY0m6oOYnLCJ6N0qEXoZql4sY2MOUArzhH4SA/qBpTxvvZp2Sc+DQ==}
     engines: {node: '>=14.0.0'}
     peerDependencies:
@@ -4382,88 +4284,73 @@ packages:
       rollup:
         optional: true
     dependencies:
-      '@rollup/pluginutils': 5.0.4(rollup@3.26.2)
+      '@rollup/pluginutils': 5.0.5(rollup@3.29.4)
       commondir: 1.0.1
       estree-walker: 2.0.2
       glob: 8.1.0
       is-reference: 1.2.1
       magic-string: 0.27.0
-      rollup: 3.26.2
+      rollup: 3.29.4
     dev: true
 
-  /@rollup/plugin-json@6.0.0(rollup@3.26.2):
-    resolution: {integrity: sha512-i/4C5Jrdr1XUarRhVu27EEwjt4GObltD7c+MkCIpO2QIbojw8MUs+CCTqOphQi3Qtg1FLmYt+l+6YeoIf51J7w==}
+  /@rollup/plugin-json@6.0.1(rollup@3.29.4):
+    resolution: {integrity: sha512-RgVfl5hWMkxN1h/uZj8FVESvPuBJ/uf6ly6GTj0GONnkfoBN5KC0MSz+PN2OLDgYXMhtG0mWpTrkiOjoxAIevw==}
     engines: {node: '>=14.0.0'}
     peerDependencies:
-      rollup: ^1.20.0||^2.0.0||^3.0.0
+      rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0
     peerDependenciesMeta:
       rollup:
         optional: true
     dependencies:
-      '@rollup/pluginutils': 5.0.4(rollup@3.26.2)
-      rollup: 3.26.2
+      '@rollup/pluginutils': 5.0.5(rollup@3.29.4)
+      rollup: 3.29.4
     dev: true
 
-  /@rollup/plugin-node-resolve@15.1.0(rollup@3.26.2):
-    resolution: {integrity: sha512-xeZHCgsiZ9pzYVgAo9580eCGqwh/XCEUM9q6iQfGNocjgkufHAqC3exA+45URvhiYV8sBF9RlBai650eNs7AsA==}
+  /@rollup/plugin-node-resolve@15.2.2(rollup@3.29.4):
+    resolution: {integrity: sha512-f64bU4OKqV0yihtxFemmuf0oj37pToCFMISCA+sJbbIAl5wcpbRO9XgWNWb1tDiWQJUcPxo6V0l59hcuZOQ3kw==}
     engines: {node: '>=14.0.0'}
     peerDependencies:
-      rollup: ^2.78.0||^3.0.0
+      rollup: ^2.78.0||^3.0.0||^4.0.0
     peerDependenciesMeta:
       rollup:
         optional: true
     dependencies:
-      '@rollup/pluginutils': 5.0.4(rollup@3.26.2)
+      '@rollup/pluginutils': 5.0.5(rollup@3.29.4)
       '@types/resolve': 1.20.2
       deepmerge: 4.3.1
       is-builtin-module: 3.2.1
       is-module: 1.0.0
-      resolve: 1.22.2
-      rollup: 3.26.2
+      resolve: 1.22.6
+      rollup: 3.29.4
     dev: true
 
-  /@rollup/plugin-replace@5.0.2(rollup@3.26.2):
-    resolution: {integrity: sha512-M9YXNekv/C/iHHK+cvORzfRYfPbq0RDD8r0G+bMiTXjNGKulPnCT9O3Ss46WfhI6ZOCgApOP7xAdmCQJ+U2LAA==}
+  /@rollup/plugin-replace@5.0.3(rollup@3.29.4):
+    resolution: {integrity: sha512-je7fu05B800IrMlWjb2wzJcdXzHYW46iTipfChnBDbIbDXhASZs27W1B58T2Yf45jZtJUONegpbce+9Ut2Ti/Q==}
     engines: {node: '>=14.0.0'}
     peerDependencies:
-      rollup: ^1.20.0||^2.0.0||^3.0.0
+      rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0
     peerDependenciesMeta:
       rollup:
         optional: true
     dependencies:
-      '@rollup/pluginutils': 5.0.4(rollup@3.26.2)
+      '@rollup/pluginutils': 5.0.5(rollup@3.29.4)
       magic-string: 0.27.0
-      rollup: 3.26.2
-    dev: true
-
-  /@rollup/pluginutils@5.0.2(rollup@3.26.2):
-    resolution: {integrity: sha512-pTd9rIsP92h+B6wWwFbW8RkZv4hiR/xKsqre4SIuAOaOEQRxi0lqLke9k2/7WegC85GgUs9pjmOjCUi3In4vwA==}
-    engines: {node: '>=14.0.0'}
-    peerDependencies:
-      rollup: ^1.20.0||^2.0.0||^3.0.0
-    peerDependenciesMeta:
-      rollup:
-        optional: true
-    dependencies:
-      '@types/estree': 1.0.1
-      estree-walker: 2.0.2
-      picomatch: 2.3.1
-      rollup: 3.26.2
+      rollup: 3.29.4
     dev: true
 
-  /@rollup/pluginutils@5.0.4(rollup@3.26.2):
-    resolution: {integrity: sha512-0KJnIoRI8A+a1dqOYLxH8vBf8bphDmty5QvIm2hqm7oFCFYKCAZWWd2hXgMibaPsNDhI0AtpYfQZJG47pt/k4g==}
+  /@rollup/pluginutils@5.0.5(rollup@3.29.4):
+    resolution: {integrity: sha512-6aEYR910NyP73oHiJglti74iRyOwgFU4x3meH/H8OJx6Ry0j6cOVZ5X/wTvub7G7Ao6qaHBEaNsV3GLJkSsF+Q==}
     engines: {node: '>=14.0.0'}
     peerDependencies:
-      rollup: ^1.20.0||^2.0.0||^3.0.0
+      rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0
     peerDependenciesMeta:
       rollup:
         optional: true
     dependencies:
-      '@types/estree': 1.0.1
+      '@types/estree': 1.0.2
       estree-walker: 2.0.2
       picomatch: 2.3.1
-      rollup: 3.26.2
+      rollup: 3.29.4
 
   /@sanity/eventsource@5.0.0:
     resolution: {integrity: sha512-0ewT+BDzfiamHwitUfRcwsl/RREHjWv6VNZvQ8Q4OnnNKXfEEGXbWmqzof0okOTkp4XELgyliht4Qj28o9AU2g==}
@@ -4538,20 +4425,20 @@ packages:
     engines: {node: '>=14.0.0'}
     dependencies:
       '@smithy/types': 1.2.0
-      tslib: 2.5.3
+      tslib: 2.6.2
     dev: false
 
   /@smithy/chunked-blob-reader-native@1.1.0:
     resolution: {integrity: sha512-RCJRL4+T54deVRYxuQT4lRsVPO60mqbfm7Mc5cyo9KeKsVpHTjtSKsMDP7ancRnzh9WLb6zeUJ/KWZ7K9Pvozw==}
     dependencies:
       '@smithy/util-base64': 1.1.0
-      tslib: 2.5.3
+      tslib: 2.6.2
     dev: false
 
   /@smithy/chunked-blob-reader@1.1.0:
     resolution: {integrity: sha512-yU3BNPaWxWqV5z64vJ2sanu0j9BPzD1bxVm8Ab9MZ9AZc2lZQgoYOlPgKrrG2adRXpXddxFGuoJGgmNL8bIvgw==}
     dependencies:
-      tslib: 2.5.3
+      tslib: 2.6.2
     dev: false
 
   /@smithy/config-resolver@1.1.0:
@@ -4561,7 +4448,7 @@ packages:
       '@smithy/types': 1.2.0
       '@smithy/util-config-provider': 1.1.0
       '@smithy/util-middleware': 1.1.0
-      tslib: 2.5.3
+      tslib: 2.6.2
     dev: false
 
   /@smithy/credential-provider-imds@1.1.0:
@@ -4572,7 +4459,7 @@ packages:
       '@smithy/property-provider': 1.2.0
       '@smithy/types': 1.2.0
       '@smithy/url-parser': 1.1.0
-      tslib: 2.5.3
+      tslib: 2.6.2
     dev: false
 
   /@smithy/eventstream-codec@1.1.0:
@@ -4581,7 +4468,7 @@ packages:
       '@aws-crypto/crc32': 3.0.0
       '@smithy/types': 1.2.0
       '@smithy/util-hex-encoding': 1.1.0
-      tslib: 2.5.3
+      tslib: 2.6.2
     dev: false
 
   /@smithy/eventstream-serde-browser@1.1.0:
@@ -4590,7 +4477,7 @@ packages:
     dependencies:
       '@smithy/eventstream-serde-universal': 1.1.0
       '@smithy/types': 1.2.0
-      tslib: 2.5.3
+      tslib: 2.6.2
     dev: false
 
   /@smithy/eventstream-serde-config-resolver@1.1.0:
@@ -4598,7 +4485,7 @@ packages:
     engines: {node: '>=14.0.0'}
     dependencies:
       '@smithy/types': 1.2.0
-      tslib: 2.5.3
+      tslib: 2.6.2
     dev: false
 
   /@smithy/eventstream-serde-node@1.1.0:
@@ -4607,7 +4494,7 @@ packages:
     dependencies:
       '@smithy/eventstream-serde-universal': 1.1.0
       '@smithy/types': 1.2.0
-      tslib: 2.5.3
+      tslib: 2.6.2
     dev: false
 
   /@smithy/eventstream-serde-universal@1.1.0:
@@ -4616,7 +4503,7 @@ packages:
     dependencies:
       '@smithy/eventstream-codec': 1.1.0
       '@smithy/types': 1.2.0
-      tslib: 2.5.3
+      tslib: 2.6.2
     dev: false
 
   /@smithy/fetch-http-handler@1.1.0:
@@ -4626,7 +4513,7 @@ packages:
       '@smithy/querystring-builder': 1.1.0
       '@smithy/types': 1.2.0
       '@smithy/util-base64': 1.1.0
-      tslib: 2.5.3
+      tslib: 2.6.2
     dev: false
 
   /@smithy/hash-blob-browser@1.1.0:
@@ -4635,7 +4522,7 @@ packages:
       '@smithy/chunked-blob-reader': 1.1.0
       '@smithy/chunked-blob-reader-native': 1.1.0
       '@smithy/types': 1.2.0
-      tslib: 2.5.3
+      tslib: 2.6.2
     dev: false
 
   /@smithy/hash-node@1.1.0:
@@ -4645,7 +4532,7 @@ packages:
       '@smithy/types': 1.2.0
       '@smithy/util-buffer-from': 1.1.0
       '@smithy/util-utf8': 1.1.0
-      tslib: 2.5.3
+      tslib: 2.6.2
     dev: false
 
   /@smithy/hash-stream-node@1.1.0:
@@ -4654,21 +4541,21 @@ packages:
     dependencies:
       '@smithy/types': 1.2.0
       '@smithy/util-utf8': 1.1.0
-      tslib: 2.5.3
+      tslib: 2.6.2
     dev: false
 
   /@smithy/invalid-dependency@1.1.0:
     resolution: {integrity: sha512-h2rXn68ClTwzPXYzEUNkz+0B/A0Hz8YdFNTiEwlxkwzkETGKMxmsrQGFXwYm3jd736R5vkXcClXz1ddKrsaBEQ==}
     dependencies:
       '@smithy/types': 1.2.0
-      tslib: 2.5.3
+      tslib: 2.6.2
     dev: false
 
   /@smithy/is-array-buffer@1.1.0:
     resolution: {integrity: sha512-twpQ/n+3OWZJ7Z+xu43MJErmhB/WO/mMTnqR6PwWQShvSJ/emx5d1N59LQZk6ZpTAeuRWrc+eHhkzTp9NFjNRQ==}
     engines: {node: '>=14.0.0'}
     dependencies:
-      tslib: 2.5.3
+      tslib: 2.6.2
     dev: false
 
   /@smithy/md5-js@1.1.0:
@@ -4676,7 +4563,7 @@ packages:
     dependencies:
       '@smithy/types': 1.2.0
       '@smithy/util-utf8': 1.1.0
-      tslib: 2.5.3
+      tslib: 2.6.2
     dev: false
 
   /@smithy/middleware-content-length@1.1.0:
@@ -4685,7 +4572,7 @@ packages:
     dependencies:
       '@smithy/protocol-http': 1.2.0
       '@smithy/types': 1.2.0
-      tslib: 2.5.3
+      tslib: 2.6.2
     dev: false
 
   /@smithy/middleware-endpoint@1.1.0:
@@ -4696,7 +4583,7 @@ packages:
       '@smithy/types': 1.2.0
       '@smithy/url-parser': 1.1.0
       '@smithy/util-middleware': 1.1.0
-      tslib: 2.5.3
+      tslib: 2.6.2
     dev: false
 
   /@smithy/middleware-retry@1.1.0:
@@ -4708,7 +4595,7 @@ packages:
       '@smithy/types': 1.2.0
       '@smithy/util-middleware': 1.1.0
       '@smithy/util-retry': 1.1.0
-      tslib: 2.5.3
+      tslib: 2.6.2
       uuid: 8.3.2
     dev: false
 
@@ -4717,14 +4604,14 @@ packages:
     engines: {node: '>=14.0.0'}
     dependencies:
       '@smithy/types': 1.2.0
-      tslib: 2.5.3
+      tslib: 2.6.2
     dev: false
 
   /@smithy/middleware-stack@1.1.0:
     resolution: {integrity: sha512-XynYiIvXNea2BbLcppvpNK0zu8o2woJqgnmxqYTn4FWagH/Hr2QIk8LOsUz7BIJ4tooFhmx8urHKCdlPbbPDCA==}
     engines: {node: '>=14.0.0'}
     dependencies:
-      tslib: 2.5.3
+      tslib: 2.6.2
     dev: false
 
   /@smithy/node-config-provider@1.1.0:
@@ -4734,7 +4621,7 @@ packages:
       '@smithy/property-provider': 1.2.0
       '@smithy/shared-ini-file-loader': 1.1.0
       '@smithy/types': 1.2.0
-      tslib: 2.5.3
+      tslib: 2.6.2
     dev: false
 
   /@smithy/node-http-handler@1.1.0:
@@ -4745,7 +4632,7 @@ packages:
       '@smithy/protocol-http': 1.2.0
       '@smithy/querystring-builder': 1.1.0
       '@smithy/types': 1.2.0
-      tslib: 2.5.3
+      tslib: 2.6.2
     dev: false
 
   /@smithy/property-provider@1.2.0:
@@ -4753,7 +4640,7 @@ packages:
     engines: {node: '>=14.0.0'}
     dependencies:
       '@smithy/types': 1.2.0
-      tslib: 2.5.3
+      tslib: 2.6.2
     dev: false
 
   /@smithy/protocol-http@1.2.0:
@@ -4761,7 +4648,7 @@ packages:
     engines: {node: '>=14.0.0'}
     dependencies:
       '@smithy/types': 1.2.0
-      tslib: 2.5.3
+      tslib: 2.6.2
     dev: false
 
   /@smithy/querystring-builder@1.1.0:
@@ -4770,7 +4657,7 @@ packages:
     dependencies:
       '@smithy/types': 1.2.0
       '@smithy/util-uri-escape': 1.1.0
-      tslib: 2.5.3
+      tslib: 2.6.2
     dev: false
 
   /@smithy/querystring-parser@1.1.0:
@@ -4778,7 +4665,7 @@ packages:
     engines: {node: '>=14.0.0'}
     dependencies:
       '@smithy/types': 1.2.0
-      tslib: 2.5.3
+      tslib: 2.6.2
     dev: false
 
   /@smithy/service-error-classification@1.1.0:
@@ -4791,7 +4678,7 @@ packages:
     engines: {node: '>=14.0.0'}
     dependencies:
       '@smithy/types': 1.2.0
-      tslib: 2.5.3
+      tslib: 2.6.2
     dev: false
 
   /@smithy/signature-v4@1.1.0:
@@ -4805,7 +4692,7 @@ packages:
       '@smithy/util-middleware': 1.1.0
       '@smithy/util-uri-escape': 1.1.0
       '@smithy/util-utf8': 1.1.0
-      tslib: 2.5.3
+      tslib: 2.6.2
     dev: false
 
   /@smithy/smithy-client@1.1.0:
@@ -4815,14 +4702,14 @@ packages:
       '@smithy/middleware-stack': 1.1.0
       '@smithy/types': 1.2.0
       '@smithy/util-stream': 1.1.0
-      tslib: 2.5.3
+      tslib: 2.6.2
     dev: false
 
   /@smithy/types@1.2.0:
     resolution: {integrity: sha512-z1r00TvBqF3dh4aHhya7nz1HhvCg4TRmw51fjMrh5do3h+ngSstt/yKlNbHeb9QxJmFbmN8KEVSWgb1bRvfEoA==}
     engines: {node: '>=14.0.0'}
     dependencies:
-      tslib: 2.5.3
+      tslib: 2.6.2
     dev: false
 
   /@smithy/url-parser@1.1.0:
@@ -4830,7 +4717,7 @@ packages:
     dependencies:
       '@smithy/querystring-parser': 1.1.0
       '@smithy/types': 1.2.0
-      tslib: 2.5.3
+      tslib: 2.6.2
     dev: false
 
   /@smithy/util-base64@1.1.0:
@@ -4838,20 +4725,20 @@ packages:
     engines: {node: '>=14.0.0'}
     dependencies:
       '@smithy/util-buffer-from': 1.1.0
-      tslib: 2.5.3
+      tslib: 2.6.2
     dev: false
 
   /@smithy/util-body-length-browser@1.1.0:
     resolution: {integrity: sha512-cep3ioRxzRZ2Jbp3Kly7gy6iNVefYXiT6ETt8W01RQr3uwi1YMkrbU1p3lMR4KhX/91Nrk6UOgX1RH+oIt48RQ==}
     dependencies:
-      tslib: 2.5.3
+      tslib: 2.6.2
     dev: false
 
   /@smithy/util-body-length-node@1.1.0:
     resolution: {integrity: sha512-fRHRjkUuT5em4HZoshySXmB1n3HAU7IS232s+qU4TicexhyGJpXMK/2+c56ePOIa1FOK2tV1Q3J/7Mae35QVSw==}
     engines: {node: '>=14.0.0'}
     dependencies:
-      tslib: 2.5.3
+      tslib: 2.6.2
     dev: false
 
   /@smithy/util-buffer-from@1.1.0:
@@ -4859,14 +4746,14 @@ packages:
     engines: {node: '>=14.0.0'}
     dependencies:
       '@smithy/is-array-buffer': 1.1.0
-      tslib: 2.5.3
+      tslib: 2.6.2
     dev: false
 
   /@smithy/util-config-provider@1.1.0:
     resolution: {integrity: sha512-rQ47YpNmF6Is4I9GiE3T3+0xQ+r7RKRKbmHYyGSbyep/0cSf9kteKcI0ssJTvveJ1K4QvwrxXj1tEFp/G2UqxQ==}
     engines: {node: '>=14.0.0'}
     dependencies:
-      tslib: 2.5.3
+      tslib: 2.6.2
     dev: false
 
   /@smithy/util-defaults-mode-browser@1.1.0:
@@ -4876,7 +4763,7 @@ packages:
       '@smithy/property-provider': 1.2.0
       '@smithy/types': 1.2.0
       bowser: 2.11.0
-      tslib: 2.5.3
+      tslib: 2.6.2
     dev: false
 
   /@smithy/util-defaults-mode-node@1.1.0:
@@ -4888,21 +4775,21 @@ packages:
       '@smithy/node-config-provider': 1.1.0
       '@smithy/property-provider': 1.2.0
       '@smithy/types': 1.2.0
-      tslib: 2.5.3
+      tslib: 2.6.2
     dev: false
 
   /@smithy/util-hex-encoding@1.1.0:
     resolution: {integrity: sha512-7UtIE9eH0u41zpB60Jzr0oNCQ3hMJUabMcKRUVjmyHTXiWDE4vjSqN6qlih7rCNeKGbioS7f/y2Jgym4QZcKFg==}
     engines: {node: '>=14.0.0'}
     dependencies:
-      tslib: 2.5.3
+      tslib: 2.6.2
     dev: false
 
   /@smithy/util-middleware@1.1.0:
     resolution: {integrity: sha512-6hhckcBqVgjWAqLy2vqlPZ3rfxLDhFWEmM7oLh2POGvsi7j0tHkbN7w4DFhuBExVJAbJ/qqxqZdRY6Fu7/OezQ==}
     engines: {node: '>=14.0.0'}
     dependencies:
-      tslib: 2.5.3
+      tslib: 2.6.2
     dev: false
 
   /@smithy/util-retry@1.1.0:
@@ -4910,7 +4797,7 @@ packages:
     engines: {node: '>= 14.0.0'}
     dependencies:
       '@smithy/service-error-classification': 1.1.0
-      tslib: 2.5.3
+      tslib: 2.6.2
     dev: false
 
   /@smithy/util-stream@1.1.0:
@@ -4924,14 +4811,14 @@ packages:
       '@smithy/util-buffer-from': 1.1.0
       '@smithy/util-hex-encoding': 1.1.0
       '@smithy/util-utf8': 1.1.0
-      tslib: 2.5.3
+      tslib: 2.6.2
     dev: false
 
   /@smithy/util-uri-escape@1.1.0:
     resolution: {integrity: sha512-/jL/V1xdVRt5XppwiaEU8Etp5WHZj609n0xMTuehmCqdoOFbId1M+aEeDWZsQ+8JbEB/BJ6ynY2SlYmOaKtt8w==}
     engines: {node: '>=14.0.0'}
     dependencies:
-      tslib: 2.5.3
+      tslib: 2.6.2
     dev: false
 
   /@smithy/util-utf8@1.1.0:
@@ -4939,7 +4826,7 @@ packages:
     engines: {node: '>=14.0.0'}
     dependencies:
       '@smithy/util-buffer-from': 1.1.0
-      tslib: 2.5.3
+      tslib: 2.6.2
     dev: false
 
   /@smithy/util-waiter@1.1.0:
@@ -4948,127 +4835,135 @@ packages:
     dependencies:
       '@smithy/abort-controller': 1.1.0
       '@smithy/types': 1.2.0
-      tslib: 2.5.3
+      tslib: 2.6.2
     dev: false
 
-  /@solid-primitives/active-element@2.0.15(solid-js@1.7.8):
+  /@solid-primitives/active-element@2.0.15(solid-js@1.7.11):
     resolution: {integrity: sha512-ShHOjC59Ng6QIMvKjWs8XpIksGmP93dZC0AmagCXEbWzkqQieAaiyCkEezuXOK3tiVke0HItRByv90eBn9QPXA==}
     peerDependencies:
       solid-js: ^1.6.12
     dependencies:
-      '@solid-primitives/event-listener': 2.2.13(solid-js@1.7.8)
-      '@solid-primitives/utils': 6.2.0(solid-js@1.7.8)
-      solid-js: 1.7.8
+      '@solid-primitives/event-listener': 2.3.0(solid-js@1.7.11)
+      '@solid-primitives/utils': 6.2.1(solid-js@1.7.11)
+      solid-js: 1.7.11
     dev: false
 
-  /@solid-primitives/connectivity@0.3.15(solid-js@1.7.8):
+  /@solid-primitives/connectivity@0.3.15(solid-js@1.7.11):
     resolution: {integrity: sha512-BN1Be+rYg7rtw6h2pGzwiiyE5ObrrMRzjOUOnWPujHwWRFbdsnrhfpGVvqYvmzDEVXwCfNJMyhCxHmg/h8M2cw==}
     peerDependencies:
       solid-js: ^1.6.12
     dependencies:
-      '@solid-primitives/event-listener': 2.2.13(solid-js@1.7.8)
-      '@solid-primitives/rootless': 1.4.1(solid-js@1.7.8)
-      '@solid-primitives/utils': 6.2.0(solid-js@1.7.8)
-      solid-js: 1.7.8
+      '@solid-primitives/event-listener': 2.3.0(solid-js@1.7.11)
+      '@solid-primitives/rootless': 1.4.2(solid-js@1.7.11)
+      '@solid-primitives/utils': 6.2.1(solid-js@1.7.11)
+      solid-js: 1.7.11
     dev: false
 
-  /@solid-primitives/event-listener@2.2.13(solid-js@1.7.8):
-    resolution: {integrity: sha512-8GtVEq0ECZoa5Klo1jjfGPfwg0zVJ8TNnNkWu8FqRkh0CkhbhCVJAKwjleem9K/qL6zUDfJihLjhqGBTBbb+8w==}
+  /@solid-primitives/event-listener@2.3.0(solid-js@1.7.11):
+    resolution: {integrity: sha512-0DS7DQZvCExWSpurVZC9/wjI8RmkhuOtWOy6Pp1Woq9ElMT9/bfjNpkwXsOwisLpcTqh9eUs17kp7jtpWcC20w==}
     peerDependencies:
       solid-js: ^1.6.12
     dependencies:
-      '@solid-primitives/utils': 6.2.0(solid-js@1.7.8)
-      solid-js: 1.7.8
+      '@solid-primitives/utils': 6.2.1(solid-js@1.7.11)
+      solid-js: 1.7.11
     dev: false
 
-  /@solid-primitives/media@2.2.3(solid-js@1.7.8):
+  /@solid-primitives/media@2.2.3(solid-js@1.7.11):
     resolution: {integrity: sha512-xhKaTJjH6e65OL706/hA38WWitafbJCm/Zpv7qAn4cy/cgxZ39Cl0bPdYzZhUlkJvTt8YVT0IBcOBLKlJVaPRg==}
     peerDependencies:
       solid-js: ^1.6.12
     dependencies:
-      '@solid-primitives/event-listener': 2.2.13(solid-js@1.7.8)
-      '@solid-primitives/rootless': 1.4.1(solid-js@1.7.8)
-      '@solid-primitives/static-store': 0.0.4(solid-js@1.7.8)
-      '@solid-primitives/utils': 6.2.0(solid-js@1.7.8)
-      solid-js: 1.7.8
+      '@solid-primitives/event-listener': 2.3.0(solid-js@1.7.11)
+      '@solid-primitives/rootless': 1.4.2(solid-js@1.7.11)
+      '@solid-primitives/static-store': 0.0.4(solid-js@1.7.11)
+      '@solid-primitives/utils': 6.2.1(solid-js@1.7.11)
+      solid-js: 1.7.11
     dev: false
 
-  /@solid-primitives/memo@1.3.2(solid-js@1.7.8):
+  /@solid-primitives/memo@1.3.2(solid-js@1.7.11):
     resolution: {integrity: sha512-HhQ+tjX9XxGIQQhejLmJCmrIj1jTEkPbSGoIAjC2nCIU9wE0DuNpupluNuh0HL7yfldMWqwXFOWG5+OKUB29nQ==}
     peerDependencies:
       solid-js: ^1.6.12
     dependencies:
-      '@solid-primitives/scheduled': 1.4.0(solid-js@1.7.8)
-      '@solid-primitives/utils': 6.2.0(solid-js@1.7.8)
-      solid-js: 1.7.8
+      '@solid-primitives/scheduled': 1.4.0(solid-js@1.7.11)
+      '@solid-primitives/utils': 6.2.1(solid-js@1.7.11)
+      solid-js: 1.7.11
     dev: false
 
-  /@solid-primitives/props@3.1.6(solid-js@1.7.8):
-    resolution: {integrity: sha512-ChtvXBDxASR+zZgH0ysoBstbVJdqJk6LITb78CScgHd+Uc8C6eaHKLmhNeuVCd36FGAuyj9vylDHe2GhmFlecA==}
+  /@solid-primitives/props@3.1.8(solid-js@1.7.11):
+    resolution: {integrity: sha512-38ERNFhl87emUDPRlYvCmlbvEcK2mOJB38SU22YS2QXFDK7TQf/7P46XZacs7oODc/fckhfZTitht71FMEDe2g==}
     peerDependencies:
       solid-js: ^1.6.12
     dependencies:
-      '@solid-primitives/utils': 6.2.0(solid-js@1.7.8)
-      solid-js: 1.7.8
+      '@solid-primitives/utils': 6.2.1(solid-js@1.7.11)
+      solid-js: 1.7.11
     dev: false
 
-  /@solid-primitives/refs@1.0.4(solid-js@1.7.8):
-    resolution: {integrity: sha512-BxZKkct0OIyADWIoA9UITm+3G5Xb3IkOa0nZd40SgOK5DtMqpXFIEPUkJ/woPB90WqlM9UvvuiJHUyAjMeAmCw==}
+  /@solid-primitives/refs@1.0.5(solid-js@1.7.11):
+    resolution: {integrity: sha512-5hmYmYbm6rs43nMHHozyyUngGA7P7q2WtlaCLJEfmlUJf67GWI1PZmqAiol6m9F37XSMZRuvZLoQ7HA/0q3GYg==}
     peerDependencies:
       solid-js: ^1.6.12
     dependencies:
-      '@solid-primitives/utils': 6.2.0(solid-js@1.7.8)
-      solid-js: 1.7.8
+      '@solid-primitives/utils': 6.2.1(solid-js@1.7.11)
+      solid-js: 1.7.11
     dev: false
 
-  /@solid-primitives/rootless@1.4.1(solid-js@1.7.8):
-    resolution: {integrity: sha512-h7VBUk8usD76Eh1a4wT17PcGtIRxGPlLuJ4Mf7roCNu46W5cc9DAoz8M6XebuZWVKeUkML/JuPMZQSV0mLo2Fw==}
+  /@solid-primitives/rootless@1.4.2(solid-js@1.7.11):
+    resolution: {integrity: sha512-ynI/2aEOPyc14IKCX6yDBqnsAYCoLbaP9V/jejEWMVKOT2ZdV2ZxdftaLimOpWPpvjyti5DUJIGTOfLaNb7jlg==}
     peerDependencies:
       solid-js: ^1.6.12
     dependencies:
-      '@solid-primitives/utils': 6.2.0(solid-js@1.7.8)
-      solid-js: 1.7.8
+      '@solid-primitives/utils': 6.2.1(solid-js@1.7.11)
+      solid-js: 1.7.11
     dev: false
 
-  /@solid-primitives/scheduled@1.4.0(solid-js@1.7.8):
+  /@solid-primitives/scheduled@1.4.0(solid-js@1.7.11):
     resolution: {integrity: sha512-j4xMdsvluO8xv+M62gSUrUEKiqT0qlymM9PhXiqIzpnRNm5rrP+bHpG0BDhqkNe6fDEDb+W1L7OCmiG+qveBvQ==}
     peerDependencies:
       solid-js: ^1.6.12
     dependencies:
-      solid-js: 1.7.8
+      solid-js: 1.7.11
     dev: false
 
-  /@solid-primitives/static-store@0.0.4(solid-js@1.7.8):
+  /@solid-primitives/static-store@0.0.4(solid-js@1.7.11):
     resolution: {integrity: sha512-NcLtDNA6H+Z9LmqaUe4SKfMx0YbszIMXEqfV15cB34t5XyEeOM5TihYwsVJ/dpkmpHYzflm0SwAL+P9uwyzvWQ==}
     peerDependencies:
       solid-js: ^1.6.12
     dependencies:
-      '@solid-primitives/utils': 6.2.0(solid-js@1.7.8)
-      solid-js: 1.7.8
+      '@solid-primitives/utils': 6.2.1(solid-js@1.7.11)
+      solid-js: 1.7.11
     dev: false
 
-  /@solid-primitives/transition-group@1.0.2(solid-js@1.7.8):
-    resolution: {integrity: sha512-+o3J7TnU0/Sok+LKA0z0wvhim88dpd2eFBk8/05adE6wVypVlME8sKqTMO+xRv8HoT4Kq3sczmvwV07FKg2n+g==}
+  /@solid-primitives/transition-group@1.0.3(solid-js@1.7.11):
+    resolution: {integrity: sha512-TnFADZhx9sibdoW5gxkU1QmLabzV2H2OBKYGS2aR5IC61Q/+7v8wlxOJEevxXNbPiRo6qlE3STLU3L9XS8hDbA==}
     peerDependencies:
       solid-js: ^1.6.12
     dependencies:
-      solid-js: 1.7.8
+      solid-js: 1.7.11
     dev: false
 
-  /@solid-primitives/utils@6.2.0(solid-js@1.7.8):
-    resolution: {integrity: sha512-T62WlLwKkbmicsw/xpwMQyv9MmZRSaVyutXfS5icc9v0cb8qGMUxRxr5LVvZHYQCZ9DEFboZB0r711xsbVBbeA==}
+  /@solid-primitives/utils@6.2.1(solid-js@1.7.11):
+    resolution: {integrity: sha512-TsecNzxiO5bLfzqb4OOuzfUmdOROcssuGqgh5rXMMaasoFZ3GoveUgdY1wcf17frMJM7kCNGNuK34EjErneZkg==}
     peerDependencies:
       solid-js: ^1.6.12
     dependencies:
-      solid-js: 1.7.8
+      solid-js: 1.7.11
     dev: false
 
-  /@solidjs/router@0.8.2(solid-js@1.7.8):
+  /@solidjs/router@0.8.2(solid-js@1.7.11):
     resolution: {integrity: sha512-gUKW+LZqxtX6y/Aw6JKyy4gQ9E7dLqp513oB9pSYJR1HM5c56Pf7eijzyXX+b3WuXig18Cxqah4tMtF0YGu80w==}
     peerDependencies:
       solid-js: ^1.5.3
     dependencies:
-      solid-js: 1.7.8
+      solid-js: 1.7.11
+    dev: false
+
+  /@tiptap/core@2.1.11(@tiptap/pm@2.1.8):
+    resolution: {integrity: sha512-1W2DdjpPwfphHgQ3Qm4s5wzCnEjiXm1TeZ+6/zBl89yKURXgv8Mw1JGdj/NcImQjtDcsNn97MscACK3GKbEJBA==}
+    peerDependencies:
+      '@tiptap/pm': ^2.0.0
+    dependencies:
+      '@tiptap/pm': 2.1.8
     dev: false
 
   /@tiptap/core@2.1.8(@tiptap/pm@2.1.8):
@@ -5079,6 +4974,14 @@ packages:
       '@tiptap/pm': 2.1.8
     dev: false
 
+  /@tiptap/extension-blockquote@2.1.11(@tiptap/core@2.1.11):
+    resolution: {integrity: sha512-IEVe3goA0rgp1G8Wm733BSRJiy71Vh2fmTCyZKWmc2A6GREVSy1X3fCvAo6pMENRObhjIoaBQUCE3p4iJYOxqg==}
+    peerDependencies:
+      '@tiptap/core': ^2.0.0
+    dependencies:
+      '@tiptap/core': 2.1.11(@tiptap/pm@2.1.8)
+    dev: false
+
   /@tiptap/extension-blockquote@2.1.8(@tiptap/core@2.1.8):
     resolution: {integrity: sha512-NhTE90ZDb/BbtkgeNjwLYPYMryAfCXCM+Zpk8AMsVODZ+bDy+lsqpnDw7uRxUK3guLMnqKgSe2eTaXqx7AKE+A==}
     peerDependencies:
@@ -5087,6 +4990,14 @@ packages:
       '@tiptap/core': 2.1.8(@tiptap/pm@2.1.8)
     dev: false
 
+  /@tiptap/extension-bold@2.1.11(@tiptap/core@2.1.11):
+    resolution: {integrity: sha512-vhdkBtvd029ufOYt2ug49Gz+RLKSczO/CCqKYBqBmpIpsifyK7M6jkgamvAQg3c/vYk0LNcKiL2dp0Jp7L+5Gw==}
+    peerDependencies:
+      '@tiptap/core': ^2.0.0
+    dependencies:
+      '@tiptap/core': 2.1.11(@tiptap/pm@2.1.8)
+    dev: false
+
   /@tiptap/extension-bold@2.1.8(@tiptap/core@2.1.8):
     resolution: {integrity: sha512-rDdmir78a0JTiV+vrycGh3yS1ZzRF1bRvBt4jr7Rne0LOl03kc7Wm936ommiL3McWUpZZV37ZpCm5JfE8rQb+w==}
     peerDependencies:
@@ -5106,6 +5017,14 @@ packages:
       tippy.js: 6.3.7
     dev: false
 
+  /@tiptap/extension-bullet-list@2.1.11(@tiptap/core@2.1.11):
+    resolution: {integrity: sha512-SOOVH2aSmdMtjWL7TTLbN72xbAFz2G5jifT4UCXb7Qx6LsyhNCyDCu0ukOW8rSosGoSdmBXxAsD9sBJ1jEOmZw==}
+    peerDependencies:
+      '@tiptap/core': ^2.0.0
+    dependencies:
+      '@tiptap/core': 2.1.11(@tiptap/pm@2.1.8)
+    dev: false
+
   /@tiptap/extension-bullet-list@2.1.8(@tiptap/core@2.1.8):
     resolution: {integrity: sha512-VWj3XZMwJQVb7e4ZM0N+o6o+905lyMMS4C35yw/sxN5CDw4TJpQMSPSAmBVNtK469XUdlGOxeLc/+Q00aU+S8A==}
     peerDependencies:
@@ -5124,7 +5043,7 @@ packages:
       '@tiptap/pm': 2.1.8
     dev: false
 
-  /@tiptap/extension-code-block-lowlight@2.1.8(@tiptap/core@2.1.8)(@tiptap/extension-code-block@2.0.3)(@tiptap/pm@2.1.8):
+  /@tiptap/extension-code-block-lowlight@2.1.8(@tiptap/core@2.1.8)(@tiptap/extension-code-block@2.1.11)(@tiptap/pm@2.1.8):
     resolution: {integrity: sha512-qiUIh8JRfvd2rhDKFjHCxBp+nRy3HedovQoVFX9YEnBbg6so+I1nLE2Eck4t3KhBVfVRBrxBKZPLVb83zQ0s4w==}
     peerDependencies:
       '@tiptap/core': ^2.0.0
@@ -5132,12 +5051,22 @@ packages:
       '@tiptap/pm': ^2.0.0
     dependencies:
       '@tiptap/core': 2.1.8(@tiptap/pm@2.1.8)
-      '@tiptap/extension-code-block': 2.0.3(@tiptap/core@2.1.8)(@tiptap/pm@2.1.8)
+      '@tiptap/extension-code-block': 2.1.11(@tiptap/core@2.1.8)(@tiptap/pm@2.1.8)
+      '@tiptap/pm': 2.1.8
+    dev: false
+
+  /@tiptap/extension-code-block@2.1.11(@tiptap/core@2.1.11)(@tiptap/pm@2.1.8):
+    resolution: {integrity: sha512-QhmhCCWqg/5qLXpZ3sl2A0rqJqV8zMOegcxUFaqcJMOqNbsuHcRgc9C+1hWSVLbCmstB7M6sgF02QpTBOkYHxg==}
+    peerDependencies:
+      '@tiptap/core': ^2.0.0
+      '@tiptap/pm': ^2.0.0
+    dependencies:
+      '@tiptap/core': 2.1.11(@tiptap/pm@2.1.8)
       '@tiptap/pm': 2.1.8
     dev: false
 
-  /@tiptap/extension-code-block@2.0.3(@tiptap/core@2.1.8)(@tiptap/pm@2.1.8):
-    resolution: {integrity: sha512-F4xMy18EwgpyY9f5Te7UuF7UwxRLptOtCq1p2c2DfxBvHDWhAjQqVqcW/sq/I/WuED7FwCnPLyyAasPiVPkLPw==}
+  /@tiptap/extension-code-block@2.1.11(@tiptap/core@2.1.8)(@tiptap/pm@2.1.8):
+    resolution: {integrity: sha512-QhmhCCWqg/5qLXpZ3sl2A0rqJqV8zMOegcxUFaqcJMOqNbsuHcRgc9C+1hWSVLbCmstB7M6sgF02QpTBOkYHxg==}
     peerDependencies:
       '@tiptap/core': ^2.0.0
       '@tiptap/pm': ^2.0.0
@@ -5146,6 +5075,14 @@ packages:
       '@tiptap/pm': 2.1.8
     dev: false
 
+  /@tiptap/extension-code@2.1.11(@tiptap/core@2.1.11):
+    resolution: {integrity: sha512-G0UEbMFunujy/F86yHN0/dumPLbwTis9C+6IQv1XRPNsV28U0MgxBhlPcJUgyO5lwuleePDxiBVcRv2XrysgKw==}
+    peerDependencies:
+      '@tiptap/core': ^2.0.0
+    dependencies:
+      '@tiptap/core': 2.1.11(@tiptap/pm@2.1.8)
+    dev: false
+
   /@tiptap/extension-code@2.1.8(@tiptap/core@2.1.8):
     resolution: {integrity: sha512-dQL8aUYzSEkES5P4sBYZ6SiCMnFK1cUKKGruaRV1TJyFu/ClZ8Y+BKS2GCCMcyH0tKjqsibYsNFBWz9/Q5gjEg==}
     peerDependencies:
@@ -5161,7 +5098,7 @@ packages:
       y-prosemirror: 1.0.20
     dependencies:
       '@tiptap/core': 2.1.8(@tiptap/pm@2.1.8)
-      y-prosemirror: 1.0.20(prosemirror-model@1.19.2)(prosemirror-state@1.4.3)(prosemirror-view@1.31.4)(y-protocols@1.0.5)(yjs@13.6.7)
+      y-prosemirror: 1.0.20(prosemirror-model@1.19.3)(prosemirror-state@1.4.3)(prosemirror-view@1.32.0)(y-protocols@1.0.5)(yjs@13.6.7)
     dev: false
 
   /@tiptap/extension-collaboration-cursor@2.1.8(@tiptap/core@2.1.8)(y-prosemirror@1.2.1):
@@ -5171,7 +5108,7 @@ packages:
       y-prosemirror: 1.0.20
     dependencies:
       '@tiptap/core': 2.1.8(@tiptap/pm@2.1.8)
-      y-prosemirror: 1.2.1(prosemirror-model@1.19.2)(prosemirror-state@1.4.3)(prosemirror-view@1.31.4)(y-protocols@1.0.5)(yjs@13.6.7)
+      y-prosemirror: 1.2.1(prosemirror-model@1.19.3)(prosemirror-state@1.4.3)(prosemirror-view@1.32.0)(y-protocols@1.0.5)(yjs@13.6.7)
     dev: false
 
   /@tiptap/extension-collaboration@2.1.8(@tiptap/core@2.1.8)(@tiptap/pm@2.1.8)(y-prosemirror@1.0.20):
@@ -5183,7 +5120,7 @@ packages:
     dependencies:
       '@tiptap/core': 2.1.8(@tiptap/pm@2.1.8)
       '@tiptap/pm': 2.1.8
-      y-prosemirror: 1.0.20(prosemirror-model@1.19.2)(prosemirror-state@1.4.3)(prosemirror-view@1.31.4)(y-protocols@1.0.5)(yjs@13.6.7)
+      y-prosemirror: 1.0.20(prosemirror-model@1.19.3)(prosemirror-state@1.4.3)(prosemirror-view@1.32.0)(y-protocols@1.0.5)(yjs@13.6.7)
     dev: false
 
   /@tiptap/extension-collaboration@2.1.8(@tiptap/core@2.1.8)(@tiptap/pm@2.1.8)(y-prosemirror@1.2.1):
@@ -5195,7 +5132,15 @@ packages:
     dependencies:
       '@tiptap/core': 2.1.8(@tiptap/pm@2.1.8)
       '@tiptap/pm': 2.1.8
-      y-prosemirror: 1.2.1(prosemirror-model@1.19.2)(prosemirror-state@1.4.3)(prosemirror-view@1.31.4)(y-protocols@1.0.5)(yjs@13.6.7)
+      y-prosemirror: 1.2.1(prosemirror-model@1.19.3)(prosemirror-state@1.4.3)(prosemirror-view@1.32.0)(y-protocols@1.0.5)(yjs@13.6.7)
+    dev: false
+
+  /@tiptap/extension-document@2.1.11(@tiptap/core@2.1.11):
+    resolution: {integrity: sha512-L/iLuqxvJep33ycCFNrnUhdR0VtcZyeNnqB+ZvVHzEwLoRud+LBy44lpEdBrAFsvRm3DG14m/FGYL+TfaD0vxA==}
+    peerDependencies:
+      '@tiptap/core': ^2.0.0
+    dependencies:
+      '@tiptap/core': 2.1.11(@tiptap/pm@2.1.8)
     dev: false
 
   /@tiptap/extension-document@2.1.8(@tiptap/core@2.1.8):
@@ -5206,6 +5151,16 @@ packages:
       '@tiptap/core': 2.1.8(@tiptap/pm@2.1.8)
     dev: false
 
+  /@tiptap/extension-dropcursor@2.1.11(@tiptap/core@2.1.11)(@tiptap/pm@2.1.8):
+    resolution: {integrity: sha512-MiJepRpHlu93aInOMW8NeRCvm9VE5rL0MA9TONY/IspJFGFIqonc/01J6t33JQa3Xh/x3xAfis4nKa/UazeVJw==}
+    peerDependencies:
+      '@tiptap/core': ^2.0.0
+      '@tiptap/pm': ^2.0.0
+    dependencies:
+      '@tiptap/core': 2.1.11(@tiptap/pm@2.1.8)
+      '@tiptap/pm': 2.1.8
+    dev: false
+
   /@tiptap/extension-dropcursor@2.1.8(@tiptap/core@2.1.8)(@tiptap/pm@2.1.8):
     resolution: {integrity: sha512-KilbUHApYya2Q6brq5qW+B+pPkb6lvgnjRfuFuv6doM/v+lfEdozUE1Ma8C19UXtzl7BmPDut9HRMDL17Pqwyg==}
     peerDependencies:
@@ -5227,6 +5182,16 @@ packages:
       tippy.js: 6.3.7
     dev: false
 
+  /@tiptap/extension-gapcursor@2.1.11(@tiptap/core@2.1.11)(@tiptap/pm@2.1.8):
+    resolution: {integrity: sha512-P/xjyhSOVyop5XXbNtRPgrooQrSlpYblwR67ClI9FAC7uQliuOwi5VcndmEItjWWSe85kJa2IHjOS7mLYvJe8A==}
+    peerDependencies:
+      '@tiptap/core': ^2.0.0
+      '@tiptap/pm': ^2.0.0
+    dependencies:
+      '@tiptap/core': 2.1.11(@tiptap/pm@2.1.8)
+      '@tiptap/pm': 2.1.8
+    dev: false
+
   /@tiptap/extension-gapcursor@2.1.8(@tiptap/core@2.1.8)(@tiptap/pm@2.1.8):
     resolution: {integrity: sha512-0EQgV/kF2dg2dOpw0fTbwwNaubwS8QNhEPPbnXQP8xqZpupuia+DKKgC+ttzbE9XhS4Sv1fGib52Sr7MMIduhA==}
     peerDependencies:
@@ -5237,6 +5202,14 @@ packages:
       '@tiptap/pm': 2.1.8
     dev: false
 
+  /@tiptap/extension-hard-break@2.1.11(@tiptap/core@2.1.11):
+    resolution: {integrity: sha512-qhiPe6FA0b6PPb/ITlgSnY0l9tEVmXZ9e7eSjvks12ORfqL/dofSCLtChHWvhZxugzo92xejG2hXLi6lyOLbkg==}
+    peerDependencies:
+      '@tiptap/core': ^2.0.0
+    dependencies:
+      '@tiptap/core': 2.1.11(@tiptap/pm@2.1.8)
+    dev: false
+
   /@tiptap/extension-hard-break@2.1.8(@tiptap/core@2.1.8):
     resolution: {integrity: sha512-K86FTizvZu7779Gz2XigW1IxAjZXduyZ7w0ipwe+5QBa/Lh6Vfl9wa8TgV1lFAkC2VATsAa3aa36llMIDBgeew==}
     peerDependencies:
@@ -5245,12 +5218,12 @@ packages:
       '@tiptap/core': 2.1.8(@tiptap/pm@2.1.8)
     dev: false
 
-  /@tiptap/extension-heading@2.0.3(@tiptap/core@2.1.8):
-    resolution: {integrity: sha512-f0IEv5ms6aCzL80WeZ1qLCXTkRVwbpRr1qAETjg3gG4eoJN18+lZNOJYpyZy3P92C5KwF2T3Av00eFyVLIbb8Q==}
+  /@tiptap/extension-heading@2.1.11(@tiptap/core@2.1.11):
+    resolution: {integrity: sha512-QBtl0S1aDFB+F1wvTrS5iGdNUEeXp+WuTddj+L2f5EP4KqG2x7sj7e7ENMy20g/l8tbKwzd3AZZydvClH4Ybbw==}
     peerDependencies:
       '@tiptap/core': ^2.0.0
     dependencies:
-      '@tiptap/core': 2.1.8(@tiptap/pm@2.1.8)
+      '@tiptap/core': 2.1.11(@tiptap/pm@2.1.8)
     dev: false
 
   /@tiptap/extension-highlight@2.1.8(@tiptap/core@2.1.8):
@@ -5261,6 +5234,16 @@ packages:
       '@tiptap/core': 2.1.8(@tiptap/pm@2.1.8)
     dev: false
 
+  /@tiptap/extension-history@2.1.11(@tiptap/core@2.1.11)(@tiptap/pm@2.1.8):
+    resolution: {integrity: sha512-88dovV2O9icmBn0IvaArFFeS6X5ts6BxZPu5VbGML8KBL8iAu+Og7RXEPdOy5e13K0K4V21fDpO3n7KdvNOAYQ==}
+    peerDependencies:
+      '@tiptap/core': ^2.0.0
+      '@tiptap/pm': ^2.0.0
+    dependencies:
+      '@tiptap/core': 2.1.11(@tiptap/pm@2.1.8)
+      '@tiptap/pm': 2.1.8
+    dev: false
+
   /@tiptap/extension-history@2.1.8(@tiptap/core@2.1.8)(@tiptap/pm@2.1.8):
     resolution: {integrity: sha512-Cyq4YsmosfgHGlaf2wiiU8VaLweUMG8LHuhZ5A2RAoriy3G09Bqgn6eqLmho8KoU1VgvffXTVBaYKxz9gVgu3w==}
     peerDependencies:
@@ -5271,6 +5254,16 @@ packages:
       '@tiptap/pm': 2.1.8
     dev: false
 
+  /@tiptap/extension-horizontal-rule@2.1.11(@tiptap/core@2.1.11)(@tiptap/pm@2.1.8):
+    resolution: {integrity: sha512-uvHPa2YCKnDhtSBSZB3lk5U4H3wRKP0DNvVx4Y2F7MdQianVzcyOd1pZYO9BQs+lUB1aZots6doE69Zqz3mU2Q==}
+    peerDependencies:
+      '@tiptap/core': ^2.0.0
+      '@tiptap/pm': ^2.0.0
+    dependencies:
+      '@tiptap/core': 2.1.11(@tiptap/pm@2.1.8)
+      '@tiptap/pm': 2.1.8
+    dev: false
+
   /@tiptap/extension-horizontal-rule@2.1.8(@tiptap/core@2.1.8)(@tiptap/pm@2.1.8):
     resolution: {integrity: sha512-qUNz8p/p3gth0ueYFkmMdVRcRVmtCwQGJsHWwbx23XrF/a7AJ0FSdiW0sk8YD6Dbw+i1cB3cnRyO+qq9XuWdqw==}
     peerDependencies:
@@ -5289,6 +5282,14 @@ packages:
       '@tiptap/core': 2.1.8(@tiptap/pm@2.1.8)
     dev: false
 
+  /@tiptap/extension-italic@2.1.11(@tiptap/core@2.1.11):
+    resolution: {integrity: sha512-QmDsHtnBBit/1KtQpBPxjSPjDC1mVKtoNTgsEwMWK6YAkCKOKPj7oPEqqjaNZIRMKPPzE5XCsfBoS3jtVmo+6A==}
+    peerDependencies:
+      '@tiptap/core': ^2.0.0
+    dependencies:
+      '@tiptap/core': 2.1.11(@tiptap/pm@2.1.8)
+    dev: false
+
   /@tiptap/extension-italic@2.1.8(@tiptap/core@2.1.8):
     resolution: {integrity: sha512-cR6kSoMraA/dCdwmus8A09WAwpxiZiGG+B0OqsludGF+MdZLilhoGyXDbTeO3aKoKccfqxZGk1YKK13C/gRM1Q==}
     peerDependencies:
@@ -5308,6 +5309,14 @@ packages:
       linkifyjs: 4.1.1
     dev: false
 
+  /@tiptap/extension-list-item@2.1.11(@tiptap/core@2.1.11):
+    resolution: {integrity: sha512-YhwHaPGhffsFsg/zjCu1G24//j/BTRDRZbZXmMwp77m1yEqPULcWyoWrI+gUzetQxJRD/ruAucqjLtoLLfICmQ==}
+    peerDependencies:
+      '@tiptap/core': ^2.0.0
+    dependencies:
+      '@tiptap/core': 2.1.11(@tiptap/pm@2.1.8)
+    dev: false
+
   /@tiptap/extension-list-item@2.1.8(@tiptap/core@2.1.8):
     resolution: {integrity: sha512-fiYVRhHvcXMcVuuiXBx/0AFWwGoKzs9784VSuVUeSSzSuH6vOchM1kZCH+v6acs7vltFKNDrluyEiwGIz1b8qA==}
     peerDependencies:
@@ -5316,6 +5325,14 @@ packages:
       '@tiptap/core': 2.1.8(@tiptap/pm@2.1.8)
     dev: false
 
+  /@tiptap/extension-ordered-list@2.1.11(@tiptap/core@2.1.11):
+    resolution: {integrity: sha512-/tghfEJ5U7WFbF8xyOqRJks8KxP/lRjnroMXMglaushSMx8PYPo1dZDB/dJZw7ksy47MAaKJfKlx3gyN2CPXBQ==}
+    peerDependencies:
+      '@tiptap/core': ^2.0.0
+    dependencies:
+      '@tiptap/core': 2.1.11(@tiptap/pm@2.1.8)
+    dev: false
+
   /@tiptap/extension-ordered-list@2.1.8(@tiptap/core@2.1.8):
     resolution: {integrity: sha512-qTVSWTlSjFNRwPNmWmfe9TsW9XL3LQCNJsfaBxtVZfhDN9rhoIZ6rPTBO7f2TTiPK1+uyLTvK+znWYvU9RtD5A==}
     peerDependencies:
@@ -5324,6 +5341,14 @@ packages:
       '@tiptap/core': 2.1.8(@tiptap/pm@2.1.8)
     dev: false
 
+  /@tiptap/extension-paragraph@2.1.11(@tiptap/core@2.1.11):
+    resolution: {integrity: sha512-gXMgJ2CU3X4yh1wKnb8RdbDmhITB76pH6DX0uWprmEgvzNMN3Qw+h5uBD9lgxg1WVghbCmkG9mY9J4PPbPTLxw==}
+    peerDependencies:
+      '@tiptap/core': ^2.0.0
+    dependencies:
+      '@tiptap/core': 2.1.11(@tiptap/pm@2.1.8)
+    dev: false
+
   /@tiptap/extension-paragraph@2.1.8(@tiptap/core@2.1.8):
     resolution: {integrity: sha512-ZuwvwKaG5GeoYRgeh96PToLk2TjxsLiZKnLN6rkUCsW6aLoseK7/8/7vm3dP2N9dAUN35ESw0/pRk2Q/VK1/+g==}
     peerDependencies:
@@ -5342,6 +5367,14 @@ packages:
       '@tiptap/pm': 2.1.8
     dev: false
 
+  /@tiptap/extension-strike@2.1.11(@tiptap/core@2.1.11):
+    resolution: {integrity: sha512-UnjeSVgu3bDuyjjUdWsUErRCoQKAHCzH/pAiqTEPEEdFYgZFQPBpcJICRVdlYjRmI2ZKh6d0TMUS55m7ckmwmQ==}
+    peerDependencies:
+      '@tiptap/core': ^2.0.0
+    dependencies:
+      '@tiptap/core': 2.1.11(@tiptap/pm@2.1.8)
+    dev: false
+
   /@tiptap/extension-strike@2.1.8(@tiptap/core@2.1.8):
     resolution: {integrity: sha512-JGPiGudEZAKTiOirua9gtDG+HILHEx4CGODW5PDBMA1xYDfyo7ZJk5xgfJWZ1SOo7YviF26HSY4KKV9ThINq2Q==}
     peerDependencies:
@@ -5418,6 +5451,14 @@ packages:
       '@tiptap/core': 2.1.8(@tiptap/pm@2.1.8)
     dev: false
 
+  /@tiptap/extension-text@2.1.11(@tiptap/core@2.1.11):
+    resolution: {integrity: sha512-Iey0EXYv9079+lbHMvZtLc6XcYfKrq++msEXuFFNHxvL0i/XzndhGf+qlDhLROLgEtDiiTqzOBBwFCGlFjbDow==}
+    peerDependencies:
+      '@tiptap/core': ^2.0.0
+    dependencies:
+      '@tiptap/core': 2.1.11(@tiptap/pm@2.1.8)
+    dev: false
+
   /@tiptap/extension-text@2.1.8(@tiptap/core@2.1.8):
     resolution: {integrity: sha512-ha7oTtUdcJdTVLr8CrxbNMucbAmOBCi83MLxdKZclVf1VpdIVpE3NTojfH2mnZCVMvtPhj4PILQp2hGO95SFig==}
     peerDependencies:
@@ -5456,42 +5497,40 @@ packages:
       prosemirror-history: 1.3.2
       prosemirror-inputrules: 1.2.1
       prosemirror-keymap: 1.2.2
-      prosemirror-markdown: 1.11.0
-      prosemirror-menu: 1.2.2
-      prosemirror-model: 1.19.2
+      prosemirror-markdown: 1.11.2
+      prosemirror-menu: 1.2.4
+      prosemirror-model: 1.19.3
       prosemirror-schema-basic: 1.2.2
       prosemirror-schema-list: 1.3.0
       prosemirror-state: 1.4.3
-      prosemirror-tables: 1.3.3
-      prosemirror-trailing-node: 2.0.4(prosemirror-model@1.19.2)(prosemirror-state@1.4.3)(prosemirror-view@1.31.4)
-      prosemirror-transform: 1.7.3
-      prosemirror-view: 1.31.4
-    transitivePeerDependencies:
-      - supports-color
-    dev: false
-
-  /@tiptap/starter-kit@2.0.3(@tiptap/pm@2.1.8):
-    resolution: {integrity: sha512-t4WG4w93zTpL2VxhVyJJvl3kdLF001ZrhpOuEiZqEMBMUMbM56Uiigv1CnUQpTFrjDAh3IM8hkqzAh20TYw2iQ==}
-    dependencies:
-      '@tiptap/core': 2.1.8(@tiptap/pm@2.1.8)
-      '@tiptap/extension-blockquote': 2.1.8(@tiptap/core@2.1.8)
-      '@tiptap/extension-bold': 2.1.8(@tiptap/core@2.1.8)
-      '@tiptap/extension-bullet-list': 2.1.8(@tiptap/core@2.1.8)
-      '@tiptap/extension-code': 2.1.8(@tiptap/core@2.1.8)
-      '@tiptap/extension-code-block': 2.0.3(@tiptap/core@2.1.8)(@tiptap/pm@2.1.8)
-      '@tiptap/extension-document': 2.1.8(@tiptap/core@2.1.8)
-      '@tiptap/extension-dropcursor': 2.1.8(@tiptap/core@2.1.8)(@tiptap/pm@2.1.8)
-      '@tiptap/extension-gapcursor': 2.1.8(@tiptap/core@2.1.8)(@tiptap/pm@2.1.8)
-      '@tiptap/extension-hard-break': 2.1.8(@tiptap/core@2.1.8)
-      '@tiptap/extension-heading': 2.0.3(@tiptap/core@2.1.8)
-      '@tiptap/extension-history': 2.1.8(@tiptap/core@2.1.8)(@tiptap/pm@2.1.8)
-      '@tiptap/extension-horizontal-rule': 2.1.8(@tiptap/core@2.1.8)(@tiptap/pm@2.1.8)
-      '@tiptap/extension-italic': 2.1.8(@tiptap/core@2.1.8)
-      '@tiptap/extension-list-item': 2.1.8(@tiptap/core@2.1.8)
-      '@tiptap/extension-ordered-list': 2.1.8(@tiptap/core@2.1.8)
-      '@tiptap/extension-paragraph': 2.1.8(@tiptap/core@2.1.8)
-      '@tiptap/extension-strike': 2.1.8(@tiptap/core@2.1.8)
-      '@tiptap/extension-text': 2.1.8(@tiptap/core@2.1.8)
+      prosemirror-tables: 1.3.4
+      prosemirror-trailing-node: 2.0.7(prosemirror-model@1.19.3)(prosemirror-state@1.4.3)(prosemirror-view@1.32.0)
+      prosemirror-transform: 1.8.0
+      prosemirror-view: 1.32.0
+    dev: false
+
+  /@tiptap/starter-kit@2.1.11(@tiptap/pm@2.1.8):
+    resolution: {integrity: sha512-kZXwuo9yxrs1ASxluRKjXThjdcy90d7owJxnJWD7SyEwXaXYc4h+Ar1M9rP3jieCDBuRTtCgvAOKbVbhnRJ2jg==}
+    dependencies:
+      '@tiptap/core': 2.1.11(@tiptap/pm@2.1.8)
+      '@tiptap/extension-blockquote': 2.1.11(@tiptap/core@2.1.11)
+      '@tiptap/extension-bold': 2.1.11(@tiptap/core@2.1.11)
+      '@tiptap/extension-bullet-list': 2.1.11(@tiptap/core@2.1.11)
+      '@tiptap/extension-code': 2.1.11(@tiptap/core@2.1.11)
+      '@tiptap/extension-code-block': 2.1.11(@tiptap/core@2.1.11)(@tiptap/pm@2.1.8)
+      '@tiptap/extension-document': 2.1.11(@tiptap/core@2.1.11)
+      '@tiptap/extension-dropcursor': 2.1.11(@tiptap/core@2.1.11)(@tiptap/pm@2.1.8)
+      '@tiptap/extension-gapcursor': 2.1.11(@tiptap/core@2.1.11)(@tiptap/pm@2.1.8)
+      '@tiptap/extension-hard-break': 2.1.11(@tiptap/core@2.1.11)
+      '@tiptap/extension-heading': 2.1.11(@tiptap/core@2.1.11)
+      '@tiptap/extension-history': 2.1.11(@tiptap/core@2.1.11)(@tiptap/pm@2.1.8)
+      '@tiptap/extension-horizontal-rule': 2.1.11(@tiptap/core@2.1.11)(@tiptap/pm@2.1.8)
+      '@tiptap/extension-italic': 2.1.11(@tiptap/core@2.1.11)
+      '@tiptap/extension-list-item': 2.1.11(@tiptap/core@2.1.11)
+      '@tiptap/extension-ordered-list': 2.1.11(@tiptap/core@2.1.11)
+      '@tiptap/extension-paragraph': 2.1.11(@tiptap/core@2.1.11)
+      '@tiptap/extension-strike': 2.1.11(@tiptap/core@2.1.11)
+      '@tiptap/extension-text': 2.1.11(@tiptap/core@2.1.11)
     transitivePeerDependencies:
       - '@tiptap/pm'
     dev: false
@@ -5522,59 +5561,76 @@ packages:
     resolution: {integrity: sha512-UntbE9gG+kB2nEwuJ0hw7AmQuRWw67voKaVBPBA7Ow6+aGZc00gva7015Ey5BT7Qf1wq7xJMLUdgw4QiVU+VpQ==}
     dev: false
 
-  /@types/aws-lambda@8.10.119:
-    resolution: {integrity: sha512-Vqm22aZrCvCd6I5g1SvpW151jfqwTzEZ7XJ3yZ6xaZG31nUEOEyzzVImjRcsN8Wi/QyPxId/x8GTtgIbsy8kEw==}
+  /@trysound/sax@0.2.0:
+    resolution: {integrity: sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==}
+    engines: {node: '>=10.13.0'}
+    dev: false
+
+  /@types/acorn@4.0.6:
+    resolution: {integrity: sha512-veQTnWP+1D/xbxVrPC3zHnCZRjSrKfhbMUlEA43iMZLu7EsnTtkJklIuwrCPbOi8YkvDQAiW05VQQFvvz9oieQ==}
+    dependencies:
+      '@types/estree': 1.0.2
+    dev: false
+
+  /@types/aws-lambda@8.10.124:
+    resolution: {integrity: sha512-PHqK0SuAkFS3tZjceqRXecxxrWIN3VqTicuialtK2wZmvBy7H9WGc3u3+wOgaZB7N8SpSXDpWk9qa7eorpTStg==}
     dev: false
 
-  /@types/babel__core@7.20.1:
-    resolution: {integrity: sha512-aACu/U/omhdk15O4Nfb+fHgH/z3QsfQzpnvRZhYhThms83ZnAOZz7zZAWO7mn2yyNQaA4xTO8GLK3uqFU4bYYw==}
+  /@types/babel__core@7.20.2:
+    resolution: {integrity: sha512-pNpr1T1xLUc2l3xJKuPtsEky3ybxN3m4fJkknfIpTCTfIZCDW57oAg+EfCgIIp2rvCe0Wn++/FfodDS4YXxBwA==}
     dependencies:
-      '@babel/parser': 7.22.16
-      '@babel/types': 7.22.15
-      '@types/babel__generator': 7.6.4
-      '@types/babel__template': 7.4.1
-      '@types/babel__traverse': 7.20.1
+      '@babel/parser': 7.23.0
+      '@babel/types': 7.23.0
+      '@types/babel__generator': 7.6.5
+      '@types/babel__template': 7.4.2
+      '@types/babel__traverse': 7.20.2
 
-  /@types/babel__generator@7.6.4:
-    resolution: {integrity: sha512-tFkciB9j2K755yrTALxD44McOrk+gfpIpvC3sxHjRawj6PfnQxrse4Clq5y/Rq+G3mrBurMax/lG8Qn2t9mSsg==}
+  /@types/babel__generator@7.6.5:
+    resolution: {integrity: sha512-h9yIuWbJKdOPLJTbmSpPzkF67e659PbQDba7ifWm5BJ8xTv+sDmS7rFmywkWOvXedGTivCdeGSIIX8WLcRTz8w==}
     dependencies:
-      '@babel/types': 7.22.15
+      '@babel/types': 7.23.0
 
-  /@types/babel__template@7.4.1:
-    resolution: {integrity: sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g==}
+  /@types/babel__template@7.4.2:
+    resolution: {integrity: sha512-/AVzPICMhMOMYoSx9MoKpGDKdBRsIXMNByh1PXSZoa+v6ZoLa8xxtsT/uLQ/NJm0XVAWl/BvId4MlDeXJaeIZQ==}
     dependencies:
-      '@babel/parser': 7.22.5
-      '@babel/types': 7.22.15
+      '@babel/parser': 7.23.0
+      '@babel/types': 7.23.0
 
-  /@types/babel__traverse@7.20.1:
-    resolution: {integrity: sha512-MitHFXnhtgwsGZWtT68URpOvLN4EREih1u3QtQiN4VdAxWKRVvGCSvw/Qth0M0Qq3pJpnGOu5JaM/ydK7OGbqg==}
+  /@types/babel__traverse@7.20.2:
+    resolution: {integrity: sha512-ojlGK1Hsfce93J0+kn3H5R73elidKUaZonirN33GSmgTUMpzI/MIFfSpF3haANe3G1bEBS9/9/QEqwTzwqFsKw==}
     dependencies:
-      '@babel/types': 7.22.15
+      '@babel/types': 7.23.0
 
   /@types/btoa-lite@1.0.0:
     resolution: {integrity: sha512-wJsiX1tosQ+J5+bY5LrSahHxr2wT+uME5UDwdN1kg4frt40euqA+wzECkmq4t5QbveHiJepfdThgQrPw6KiSlg==}
     dev: false
 
-  /@types/debug@4.1.8:
-    resolution: {integrity: sha512-/vPO1EPOs306Cvhwv7KfVfYvOJqA/S/AXjaHQiJboCZzcNDb+TIJFN9/2C9DZ//ijSKWioNyUxD792QmDJ+HKQ==}
+  /@types/debug@4.1.9:
+    resolution: {integrity: sha512-8Hz50m2eoS56ldRlepxSBa6PWEVCtzUo/92HgLc2qTMnotJNIm7xP+UZhyWoYsyOdd5dxZ+NZLb24rsKyFs2ow==}
     dependencies:
-      '@types/ms': 0.7.31
+      '@types/ms': 0.7.32
 
-  /@types/dom-view-transitions@1.0.1:
-    resolution: {integrity: sha512-A9S1ijj/4MX06I1W/6on8lhaYyq1Ir7gaOvfllW1o4RzVWW88HAeqX0pUx9VgOLnNpdiGeUW2CTkg18p5LWIrA==}
+  /@types/dom-view-transitions@1.0.2:
+    resolution: {integrity: sha512-+ctRyzGMOZB5AbvhpTv37OWkP9N3Xxfac7bhS7AcuRMmO03SHxm5/5kWCPtcatx2gW+NhFMdl7l1DqJvvPVtwg==}
 
   /@types/dompurify@3.0.2:
     resolution: {integrity: sha512-YBL4ziFebbbfQfH5mlC+QTJsvh0oJUrWbmxKMyEdL7emlHJqGR2Qb34TEFKj+VCayBvjKy3xczMFNhugThUsfQ==}
     dependencies:
-      '@types/trusted-types': 2.0.3
+      '@types/trusted-types': 2.0.4
     dev: false
 
   /@types/eslint-visitor-keys@1.0.0:
     resolution: {integrity: sha512-OCutwjDZ4aFS6PB1UZ988C4YgwlBHJd6wCeQqaLdmadZ/7e+w79+hbMUFC1QXDNCmdyoRfAFdm0RypzwR+Qpag==}
     dev: true
 
-  /@types/estree@1.0.1:
-    resolution: {integrity: sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA==}
+  /@types/estree-jsx@1.0.1:
+    resolution: {integrity: sha512-sHyakZlAezNFxmYRo0fopDZW+XvK6ipeZkkp5EAOLjdPfZp8VjZBJ67vSRI99RSCAoqXVmXOHS4fnWoxpuGQtQ==}
+    dependencies:
+      '@types/estree': 1.0.2
+    dev: false
+
+  /@types/estree@1.0.2:
+    resolution: {integrity: sha512-VeiPZ9MMwXjO32/Xu7+OwflfmeoRwkE/qzndw42gGtgJwZopBnzy2gD//NN1+go1mADzkDcqf/KnFRSjTJ8xJA==}
 
   /@types/event-source-polyfill@1.0.1:
     resolution: {integrity: sha512-dls8b0lUgJ/miRApF0efboQ9QZnAm7ofTO6P1ILu8bRPxUFKDxVwFf8+TeuuErmNui6blpltyr7+eV72dbQXlQ==}
@@ -5584,17 +5640,27 @@ packages:
     resolution: {integrity: sha512-L7wLDZlWm5mROzv87W0ofIYeQP5K2UhoFnnUyEWLKM6UBb0ZNRgAqp98qE5DkgfBXdWfc2kYmw9KZm4NLjRbsw==}
     dev: false
 
-  /@types/hast@2.3.4:
-    resolution: {integrity: sha512-wLEm0QvaoawEDoTRwzTXp4b4jpwiJDvR5KMnFnVodm3scufTlBOWRD6N1OBf9TZMhjlNsSfcO5V+7AF4+Vy+9g==}
+  /@types/hast@2.3.6:
+    resolution: {integrity: sha512-47rJE80oqPmFdVDCD7IheXBrVdwuBgsYwoczFvKmwfo2Mzsnt+V9OONsYauFmICb6lQPpCuXYJWejBNs4pDJRg==}
+    dependencies:
+      '@types/unist': 2.0.8
+
+  /@types/hast@3.0.1:
+    resolution: {integrity: sha512-hs/iBJx2aydugBQx5ETV3ZgeSS0oIreQrFJ4bjBl0XvM4wAmDjFEALY7p0rTSLt2eL+ibjRAAs9dTPiCLtmbqQ==}
     dependencies:
-      '@types/unist': 2.0.6
+      '@types/unist': 3.0.0
+    dev: false
 
   /@types/html-to-text@9.0.1:
     resolution: {integrity: sha512-sHu702QGb0SP2F0Zt+CxdCmGZIZ0gEaaCjqOh/V4iba1wTxPVntEPOM/vHm5bel08TILhB3+OxUTkDJWnr/zHQ==}
     dev: false
 
-  /@types/json-schema@7.0.12:
-    resolution: {integrity: sha512-Hr5Jfhc9eYOQNPYO5WLDq/n4jqijdHNlDXjuAQkkt+mWdQR+XJToOHrsD4cPaMXpn6KO7y2+wM8AZEs8VpBLVA==}
+  /@types/js-yaml@4.0.6:
+    resolution: {integrity: sha512-ACTuifTSIIbyksx2HTon3aFtCKWcID7/h3XEmRpDYdMCXxPbl+m9GteOJeaAkiAta/NJaSFuA7ahZ0NkwajDSw==}
+    dev: false
+
+  /@types/json-schema@7.0.13:
+    resolution: {integrity: sha512-RbSSoHliUbnXj3ny0CNFOoxrIDV6SUGyStHsvDqosw6CkdPV8TtWGlfecuK4ToyMEAql6pzNxgCFKanovUzlgQ==}
     dev: true
 
   /@types/json5@0.0.29:
@@ -5604,8 +5670,8 @@ packages:
   /@types/json5@0.0.30:
     resolution: {integrity: sha512-sqm9g7mHlPY/43fcSNrCYfOeX9zkTTK+euO5E6+CVijSMm5tTjkVdwdqRkY3ljjIAf8679vps5jKUoJBCLsMDA==}
 
-  /@types/jsonwebtoken@9.0.2:
-    resolution: {integrity: sha512-drE6uz7QBKq1fYqqoFKTDRdFCPHd5TCub75BM+D+cMx7NU9hUz7SESLfC2fSCXVFMO5Yj8sOWHuGqPgjc+fz0Q==}
+  /@types/jsonwebtoken@9.0.3:
+    resolution: {integrity: sha512-b0jGiOgHtZ2jqdPgPnP6WLCXZk1T8p06A/vPGzUvxpFGgKMbjXJDjC5m52ErqBnIuWZFgGoIJyRdeG5AyreJjA==}
     dependencies:
       '@types/node': 20.4.5
     dev: false
@@ -5614,33 +5680,37 @@ packages:
     resolution: {integrity: sha512-Y3pAUzHKh605fN6fvASsz5FDSWbZcs/65Q6xYRmnIP9ZIYz27T4IOmXfH9gWJV1dpi7f1e7z7nBGUTx/a0ptpA==}
     dev: false
 
-  /@types/mdast@3.0.11:
-    resolution: {integrity: sha512-Y/uImid8aAwrEA24/1tcRZwpxX3pIFTSilcNDKSPn+Y2iDywSEachzRuvgAYYLR3wpGXAsMbv5lvKLDZLeYPAw==}
+  /@types/mdast@3.0.13:
+    resolution: {integrity: sha512-HjiGiWedR0DVFkeNljpa6Lv4/IZU1+30VY5d747K7lBudFc3R0Ibr6yJ9lN3BE28VnZyDfLF/VB1Ql1ZIbKrmg==}
     dependencies:
-      '@types/unist': 2.0.6
+      '@types/unist': 2.0.8
 
-  /@types/mdast@4.0.0:
-    resolution: {integrity: sha512-YLeG8CujC9adtj/kuDzq1N4tCDYKoZ5l/bnjq8d74+t/3q/tHquJOJKUQXJrLCflOHpKjXgcI/a929gpmLOEng==}
+  /@types/mdast@4.0.1:
+    resolution: {integrity: sha512-IlKct1rUTJ1T81d8OHzyop15kGv9A/ff7Gz7IJgrk6jDb4Udw77pCJ+vq8oxZf4Ghpm+616+i1s/LNg/Vh7d+g==}
     dependencies:
       '@types/unist': 3.0.0
 
+  /@types/mdx@2.0.8:
+    resolution: {integrity: sha512-r7/zWe+f9x+zjXqGxf821qz++ld8tp6Z4jUS6qmPZUXH6tfh4riXOhAqb12tWGWAevCFtMt1goLWkQMqIJKpsA==}
+    dev: false
+
   /@types/mime-types@2.1.1:
     resolution: {integrity: sha512-vXOTGVSLR2jMw440moWTC7H19iUyLtP3Z1YTj7cSsubOICinjMxFeb/V57v9QdyyPGbbWolUFSSmSiRSn94tFw==}
     dev: false
 
-  /@types/ms@0.7.31:
-    resolution: {integrity: sha512-iiUgKzV9AuaEkZqkOLDIvlQiL6ltuZd9tGcW3gwpnX8JbuiuhFlEGmmFXEXkN50Cvq7Os88IY2v0dkDqXYWVgA==}
+  /@types/ms@0.7.32:
+    resolution: {integrity: sha512-xPSg0jm4mqgEkNhowKgZFBNtwoEwF6gJ4Dhww+GFpm3IgtNseHQZ5IqdNwnquZEoANxyDAKDRAdVo4Z72VvD/g==}
 
-  /@types/nlcst@1.0.0:
-    resolution: {integrity: sha512-3TGCfOcy8R8mMQ4CNSNOe3PG66HttvjcLzCoOpvXvDtfWOTi+uT/rxeOKm/qEwbM4SNe1O/PjdiBK2YcTjU4OQ==}
+  /@types/nlcst@1.0.2:
+    resolution: {integrity: sha512-ykxL/GDDUhqikjU0LIywZvEwb1NTYXTEWf+XgMSS2o6IXIakafPccxZmxgZcvJPZ3yFl2kdL1gJZz3U3iZF3QA==}
     dependencies:
-      '@types/unist': 3.0.0
+      '@types/unist': 2.0.8
 
-  /@types/node-fetch@2.6.4:
-    resolution: {integrity: sha512-1ZX9fcN4Rvkvgv4E6PAY5WXUFWFcRWxZa3EW83UjycOB9ljJCedb2CupIP4RZMEwF/M3eTcCihbBRgwtGbg5Rg==}
+  /@types/node-fetch@2.6.6:
+    resolution: {integrity: sha512-95X8guJYhfqiuVVhRFxVQcf4hW/2bCuoPwDasMf/531STFoNoWTT7YDnWdXHEZKqAGUigmpG31r2FE70LwnzJw==}
     dependencies:
       '@types/node': 20.4.5
-      form-data: 3.0.1
+      form-data: 4.0.0
     dev: false
 
   /@types/node@12.20.55:
@@ -5651,13 +5721,12 @@ packages:
     resolution: {integrity: sha512-w+tIMs3rq2afQdsPJlODhoUEKzFP1ayaoyl1CcnwtIlsVe7K7bA1NGm4s3PraqTLlXnbIN84zuBlxBWo1u9BLw==}
     dev: false
 
-  /@types/node@18.17.5:
-    resolution: {integrity: sha512-xNbS75FxH6P4UXTPUJp/zNPq6/xsfdJKussCWNOnz4aULWIRwMgP1LgaB5RiBnMX1DPCYenuqGZfnIAx5mbFLA==}
+  /@types/node@18.18.4:
+    resolution: {integrity: sha512-t3rNFBgJRugIhackit2mVcLfF6IRc0JE4oeizPQL8Zrm8n2WY/0wOdpOPhdtG0V9Q2TlW/axbF1MJ6z+Yj/kKQ==}
     dev: false
 
   /@types/node@20.4.4:
     resolution: {integrity: sha512-CukZhumInROvLq3+b5gLev+vgpsIqC2D0deQr/yS1WnxvmYLlJXZpaQrQiseMY+6xusl79E04UjWoqyr+t1/Ew==}
-    dev: true
 
   /@types/node@20.4.5:
     resolution: {integrity: sha512-rt40Nk13II9JwQBdeYqmbn2Q6IVTA5uPhvSO+JVqdXw/6/4glI6oR9ezty/A9Hg5u7JH4OmYmuQ+XvjKm0Datg==}
@@ -5668,11 +5737,11 @@ packages:
       '@types/node': 20.4.5
     dev: false
 
-  /@types/normalize-package-data@2.4.1:
-    resolution: {integrity: sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==}
+  /@types/normalize-package-data@2.4.2:
+    resolution: {integrity: sha512-lqa4UEhhv/2sjjIQgjX8B+RBjj47eo0mzGasklVJ78UKGQY1r0VpB9XHDaZZO9qzEFDdy4MrXLuEaSmPrPSe/A==}
 
-  /@types/object.omit@3.0.0:
-    resolution: {integrity: sha512-I27IoPpH250TUzc9FzXd0P1BV/BMJuzqD3jOz98ehf9dQqGkxlq+hO1bIqZGWqCg5bVOy0g4AUVJtnxe0klDmw==}
+  /@types/object.omit@3.0.1:
+    resolution: {integrity: sha512-24XD34UeRWw505TsMNBrQ4bES2s8IxiFC59mmNUFhTz9IX2hAtA7gQ8wVww1i17QmhBYILg5iqYP2y7aqA3pwQ==}
     dev: false
 
   /@types/object.pick@1.3.2:
@@ -5682,33 +5751,37 @@ packages:
   /@types/parse5@6.0.3:
     resolution: {integrity: sha512-SuT16Q1K51EAVPz1K29DJ/sXjhSQ0zjvsypYJ6tlwVsRV9jwW5Adq2ch8Dq8kDBCkYnELS7N7VNCSB5nC56t/g==}
 
-  /@types/prop-types@15.7.5:
-    resolution: {integrity: sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==}
+  /@types/prop-types@15.7.8:
+    resolution: {integrity: sha512-kMpQpfZKSCBqltAJwskgePRaYRFukDkm1oItcAbC3gNELR20XIBcN9VRgg4+m8DKsTfkWeA4m4Imp4DDuWy7FQ==}
     dev: false
 
   /@types/react@18.2.21:
     resolution: {integrity: sha512-neFKG/sBAwGxHgXiIxnbm3/AAVQ/cMRS93hvBpg8xYRbeQSPVABp9U2bRnPf0iI4+Ucdv3plSxKK+3CW2ENJxA==}
     dependencies:
-      '@types/prop-types': 15.7.5
-      '@types/scheduler': 0.16.3
+      '@types/prop-types': 15.7.8
+      '@types/scheduler': 0.16.4
       csstype: 3.1.2
     dev: false
 
   /@types/resolve@1.20.2:
     resolution: {integrity: sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==}
+    dev: true
 
-  /@types/sax@1.2.4:
-    resolution: {integrity: sha512-pSAff4IAxJjfAXUG6tFkO7dsSbTmf8CtUpfhhZ5VhkRpC4628tJhh3+V6H1E+/Gs9piSzYKT5yzHO5M4GG9jkw==}
+  /@types/resolve@1.20.3:
+    resolution: {integrity: sha512-NH5oErHOtHZYcjCtg69t26aXEk4BN2zLWqf7wnDZ+dpe0iR7Rds1SPGEItl3fca21oOe0n3OCnZ4W7jBxu7FOw==}
+
+  /@types/sax@1.2.5:
+    resolution: {integrity: sha512-9jWta97bBVC027/MShr3gLab8gPhKy4l6qpb+UJLF5pDm3501NvA7uvqVCW+REFtx00oTi6Cq9JzLwgq6evVgw==}
     dependencies:
       '@types/node': 20.4.5
     dev: false
 
-  /@types/scheduler@0.16.3:
-    resolution: {integrity: sha512-5cJ8CB4yAx7BH1oMvdU0Jh9lrEXyPkar6F9G/ERswkCuvP4KQZfZkSjcMbAICCpQTN4OuZn8tz0HiKv9TGZgrQ==}
+  /@types/scheduler@0.16.4:
+    resolution: {integrity: sha512-2L9ifAGl7wmXwP4v3pN4p2FLhD0O1qsJpvKmNin5VA8+UvNVb447UDaAEV6UdrkA+m/Xs58U1RFps44x6TFsVQ==}
     dev: false
 
-  /@types/semver@7.5.0:
-    resolution: {integrity: sha512-G8hZ6XJiHnuhQKR7ZmysCeJWE08o8T0AXtk5darsCaTVsYZhhgUrq53jizaR2FvsoeCwJhlmwTjkXBY5Pn/ZHw==}
+  /@types/semver@7.5.3:
+    resolution: {integrity: sha512-OxepLK9EuNEIPxWNME+C6WwbRAOOI2o2BaQEGzz5Lu2e4Z5eDnEo+/aVEDMIXywoJitJ7xWd641wrGLZdtwRyw==}
     dev: true
 
   /@types/sortablejs@1.15.1:
@@ -5719,25 +5792,25 @@ packages:
     resolution: {integrity: sha512-5eQEtSCoESnh2FsiLTxE121IiE60hnMqcb435fShf4bpLRjEu1Eoekht23y6zXS9Ts3l+Szu3TARnTsA0GkOkQ==}
     dev: false
 
-  /@types/trusted-types@2.0.3:
-    resolution: {integrity: sha512-NfQ4gyz38SL8sDNrSixxU2Os1a5xcdFxipAFxYEuLUlvU2uDwS4NUpsImcf1//SlWItCVMMLiylsxbmNMToV/g==}
+  /@types/trusted-types@2.0.4:
+    resolution: {integrity: sha512-IDaobHimLQhjwsQ/NMwRVfa/yL7L/wriQPMhw1ZJall0KX6E1oxk29XMDeilW5qTIg5aoiqf5Udy8U/51aNoQQ==}
     dev: false
 
-  /@types/unist@2.0.6:
-    resolution: {integrity: sha512-PBjIUxZHOuj0R15/xuwJYjFi+KZdNFrehocChv4g5hu6aFroHue8m0lBP0POdK2nKzbw0cgV1mws8+V/JAcEkQ==}
+  /@types/unist@2.0.8:
+    resolution: {integrity: sha512-d0XxK3YTObnWVp6rZuev3c49+j4Lo8g4L1ZRm9z5L0xpoZycUPshHgczK5gsUMaZOstjVYYi09p5gYvUtfChYw==}
 
   /@types/unist@3.0.0:
     resolution: {integrity: sha512-MFETx3tbTjE7Uk6vvnWINA/1iJ7LuMdO4fcq8UfF0pRbj01aGLduVvQcRyswuACJdpnHgg8E3rQLhaRdNEJS0w==}
 
-  /@types/webidl-conversions@7.0.0:
-    resolution: {integrity: sha512-xTE1E+YF4aWPJJeUzaZI5DRntlkY3+BCVJi0axFptnjGmAoWxkyREIh/XMrfxVLejwQxMCfDXdICo0VLxThrog==}
+  /@types/webidl-conversions@7.0.1:
+    resolution: {integrity: sha512-8hKOnOan+Uu+NgMaCouhg3cT9x5fFZ92Jwf+uDLXLu/MFRbXxlWwGeQY7KVHkeSft6RvY+tdxklUBuyY9eIEKg==}
     dev: false
 
   /@types/whatwg-url@8.2.2:
     resolution: {integrity: sha512-FtQu10RWgn3D9U4aazdwIE2yzphmTJREDqNdODHrbrZmmMqI0vMheC/6NE/J1Yveaj8H+ela+YwWTjq5PGmuhA==}
     dependencies:
       '@types/node': 20.4.5
-      '@types/webidl-conversions': 7.0.0
+      '@types/webidl-conversions': 7.0.1
     dev: false
 
   /@types/ws@8.5.5:
@@ -5746,10 +5819,10 @@ packages:
       '@types/node': 20.4.5
     dev: false
 
-  /@types/yargs-parser@21.0.0:
-    resolution: {integrity: sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==}
+  /@types/yargs-parser@21.0.1:
+    resolution: {integrity: sha512-axdPBuLuEJt0c4yI5OZssC19K2Mq1uKdrfZBzuxLvaztgqUtFYZUNw7lETExPYJR9jdEoIg4mb7RQKRQzOkeGQ==}
 
-  /@typescript-eslint/eslint-plugin@3.10.1(@typescript-eslint/parser@3.10.1)(eslint@8.45.0)(typescript@5.1.6):
+  /@typescript-eslint/eslint-plugin@3.10.1(@typescript-eslint/parser@3.10.1)(eslint@8.45.0)(typescript@5.2.2):
     resolution: {integrity: sha512-PQg0emRtzZFWq6PxBcdxRH3QIQiyFO3WCVpRL3fgj5oQS3CDs3AeAKfv4DxNhzn8ITdNJGJ4D3Qw8eAJf3lXeQ==}
     engines: {node: ^10.12.0 || >=12.0.0}
     peerDependencies:
@@ -5760,20 +5833,20 @@ packages:
       typescript:
         optional: true
     dependencies:
-      '@typescript-eslint/experimental-utils': 3.10.1(eslint@8.45.0)(typescript@5.1.6)
-      '@typescript-eslint/parser': 3.10.1(eslint@8.45.0)(typescript@5.1.6)
+      '@typescript-eslint/experimental-utils': 3.10.1(eslint@8.45.0)(typescript@5.2.2)
+      '@typescript-eslint/parser': 3.10.1(eslint@8.45.0)(typescript@5.2.2)
       debug: 4.3.4
       eslint: 8.45.0
       functional-red-black-tree: 1.0.1
       regexpp: 3.2.0
       semver: 7.5.4
-      tsutils: 3.21.0(typescript@5.1.6)
-      typescript: 5.1.6
+      tsutils: 3.21.0(typescript@5.2.2)
+      typescript: 5.2.2
     transitivePeerDependencies:
       - supports-color
     dev: true
 
-  /@typescript-eslint/eslint-plugin@6.2.0(@typescript-eslint/parser@6.2.0)(eslint@8.45.0)(typescript@5.1.6):
+  /@typescript-eslint/eslint-plugin@6.2.0(@typescript-eslint/parser@6.2.0)(eslint@8.45.0)(typescript@5.2.2):
     resolution: {integrity: sha512-rClGrMuyS/3j0ETa1Ui7s6GkLhfZGKZL3ZrChLeAiACBE/tRc1wq8SNZESUuluxhLj9FkUefRs2l6bCIArWBiQ==}
     engines: {node: ^16.0.0 || >=18.0.0}
     peerDependencies:
@@ -5784,11 +5857,11 @@ packages:
       typescript:
         optional: true
     dependencies:
-      '@eslint-community/regexpp': 4.6.1
-      '@typescript-eslint/parser': 6.2.0(eslint@8.45.0)(typescript@5.1.6)
+      '@eslint-community/regexpp': 4.9.1
+      '@typescript-eslint/parser': 6.2.0(eslint@8.45.0)(typescript@5.2.2)
       '@typescript-eslint/scope-manager': 6.2.0
-      '@typescript-eslint/type-utils': 6.2.0(eslint@8.45.0)(typescript@5.1.6)
-      '@typescript-eslint/utils': 6.2.0(eslint@8.45.0)(typescript@5.1.6)
+      '@typescript-eslint/type-utils': 6.2.0(eslint@8.45.0)(typescript@5.2.2)
+      '@typescript-eslint/utils': 6.2.0(eslint@8.45.0)(typescript@5.2.2)
       '@typescript-eslint/visitor-keys': 6.2.0
       debug: 4.3.4
       eslint: 8.45.0
@@ -5797,21 +5870,21 @@ packages:
       natural-compare: 1.4.0
       natural-compare-lite: 1.4.0
       semver: 7.5.4
-      ts-api-utils: 1.0.1(typescript@5.1.6)
-      typescript: 5.1.6
+      ts-api-utils: 1.0.3(typescript@5.2.2)
+      typescript: 5.2.2
     transitivePeerDependencies:
       - supports-color
     dev: true
 
-  /@typescript-eslint/experimental-utils@3.10.1(eslint@8.45.0)(typescript@5.1.6):
+  /@typescript-eslint/experimental-utils@3.10.1(eslint@8.45.0)(typescript@5.2.2):
     resolution: {integrity: sha512-DewqIgscDzmAfd5nOGe4zm6Bl7PKtMG2Ad0KG8CUZAHlXfAKTF9Ol5PXhiMh39yRL2ChRH1cuuUGOcVyyrhQIw==}
     engines: {node: ^10.12.0 || >=12.0.0}
     peerDependencies:
       eslint: '*'
     dependencies:
-      '@types/json-schema': 7.0.12
+      '@types/json-schema': 7.0.13
       '@typescript-eslint/types': 3.10.1
-      '@typescript-eslint/typescript-estree': 3.10.1(typescript@5.1.6)
+      '@typescript-eslint/typescript-estree': 3.10.1(typescript@5.2.2)
       eslint: 8.45.0
       eslint-scope: 5.1.1
       eslint-utils: 2.1.0
@@ -5820,7 +5893,7 @@ packages:
       - typescript
     dev: true
 
-  /@typescript-eslint/parser@3.10.1(eslint@8.45.0)(typescript@5.1.6):
+  /@typescript-eslint/parser@3.10.1(eslint@8.45.0)(typescript@5.2.2):
     resolution: {integrity: sha512-Ug1RcWcrJP02hmtaXVS3axPPTTPnZjupqhgj+NnZ6BCkwSImWk/283347+x9wN+lqOdK9Eo3vsyiyDHgsmiEJw==}
     engines: {node: ^10.12.0 || >=12.0.0}
     peerDependencies:
@@ -5831,17 +5904,17 @@ packages:
         optional: true
     dependencies:
       '@types/eslint-visitor-keys': 1.0.0
-      '@typescript-eslint/experimental-utils': 3.10.1(eslint@8.45.0)(typescript@5.1.6)
+      '@typescript-eslint/experimental-utils': 3.10.1(eslint@8.45.0)(typescript@5.2.2)
       '@typescript-eslint/types': 3.10.1
-      '@typescript-eslint/typescript-estree': 3.10.1(typescript@5.1.6)
+      '@typescript-eslint/typescript-estree': 3.10.1(typescript@5.2.2)
       eslint: 8.45.0
       eslint-visitor-keys: 1.3.0
-      typescript: 5.1.6
+      typescript: 5.2.2
     transitivePeerDependencies:
       - supports-color
     dev: true
 
-  /@typescript-eslint/parser@6.2.0(eslint@8.45.0)(typescript@5.1.6):
+  /@typescript-eslint/parser@6.2.0(eslint@8.45.0)(typescript@5.2.2):
     resolution: {integrity: sha512-igVYOqtiK/UsvKAmmloQAruAdUHihsOCvplJpplPZ+3h4aDkC/UKZZNKgB6h93ayuYLuEymU3h8nF1xMRbh37g==}
     engines: {node: ^16.0.0 || >=18.0.0}
     peerDependencies:
@@ -5853,21 +5926,21 @@ packages:
     dependencies:
       '@typescript-eslint/scope-manager': 6.2.0
       '@typescript-eslint/types': 6.2.0
-      '@typescript-eslint/typescript-estree': 6.2.0(typescript@5.1.6)
+      '@typescript-eslint/typescript-estree': 6.2.0(typescript@5.2.2)
       '@typescript-eslint/visitor-keys': 6.2.0
       debug: 4.3.4
       eslint: 8.45.0
-      typescript: 5.1.6
+      typescript: 5.2.2
     transitivePeerDependencies:
       - supports-color
     dev: true
 
-  /@typescript-eslint/scope-manager@5.59.11:
-    resolution: {integrity: sha512-dHFOsxoLFtrIcSj5h0QoBT/89hxQONwmn3FOQ0GOQcLOOXm+MIrS8zEAhs4tWl5MraxCY3ZJpaXQQdFMc2Tu+Q==}
+  /@typescript-eslint/scope-manager@5.62.0:
+    resolution: {integrity: sha512-VXuvVvZeQCQb5Zgf4HAxc04q5j+WrNAtNh9OwCsCgpKqESMTu3tF/jhZ3xG6T4NZwWl65Bg8KuS2uEvhSfLl0w==}
     engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
     dependencies:
-      '@typescript-eslint/types': 5.59.11
-      '@typescript-eslint/visitor-keys': 5.59.11
+      '@typescript-eslint/types': 5.62.0
+      '@typescript-eslint/visitor-keys': 5.62.0
     dev: true
 
   /@typescript-eslint/scope-manager@6.2.0:
@@ -5878,7 +5951,7 @@ packages:
       '@typescript-eslint/visitor-keys': 6.2.0
     dev: true
 
-  /@typescript-eslint/type-utils@6.2.0(eslint@8.45.0)(typescript@5.1.6):
+  /@typescript-eslint/type-utils@6.2.0(eslint@8.45.0)(typescript@5.2.2):
     resolution: {integrity: sha512-DnGZuNU2JN3AYwddYIqrVkYW0uUQdv0AY+kz2M25euVNlujcN2u+rJgfJsBFlUEzBB6OQkUqSZPyuTLf2bP5mw==}
     engines: {node: ^16.0.0 || >=18.0.0}
     peerDependencies:
@@ -5888,12 +5961,12 @@ packages:
       typescript:
         optional: true
     dependencies:
-      '@typescript-eslint/typescript-estree': 6.2.0(typescript@5.1.6)
-      '@typescript-eslint/utils': 6.2.0(eslint@8.45.0)(typescript@5.1.6)
+      '@typescript-eslint/typescript-estree': 6.2.0(typescript@5.2.2)
+      '@typescript-eslint/utils': 6.2.0(eslint@8.45.0)(typescript@5.2.2)
       debug: 4.3.4
       eslint: 8.45.0
-      ts-api-utils: 1.0.1(typescript@5.1.6)
-      typescript: 5.1.6
+      ts-api-utils: 1.0.3(typescript@5.2.2)
+      typescript: 5.2.2
     transitivePeerDependencies:
       - supports-color
     dev: true
@@ -5903,8 +5976,8 @@ packages:
     engines: {node: ^8.10.0 || ^10.13.0 || >=11.10.1}
     dev: true
 
-  /@typescript-eslint/types@5.59.11:
-    resolution: {integrity: sha512-epoN6R6tkvBYSc+cllrz+c2sOFWkbisJZWkOE+y3xHtvYaOE6Wk6B8e114McRJwFRjGvYdJwLXQH5c9osME/AA==}
+  /@typescript-eslint/types@5.62.0:
+    resolution: {integrity: sha512-87NVngcbVXUahrRTqIK27gD2t5Cu1yuCXxbLcFtCzZGlfyVWWh8mLHkoxzjsB6DDNnvdL+fW8MiwPEJyGJQDgQ==}
     engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
     dev: true
 
@@ -5913,7 +5986,7 @@ packages:
     engines: {node: ^16.0.0 || >=18.0.0}
     dev: true
 
-  /@typescript-eslint/typescript-estree@3.10.1(typescript@5.1.6):
+  /@typescript-eslint/typescript-estree@3.10.1(typescript@5.2.2):
     resolution: {integrity: sha512-QbcXOuq6WYvnB3XPsZpIwztBoquEYLXh2MtwVU+kO8jgYCiv4G5xrSP/1wg4tkvrEE+esZVquIPX/dxPlePk1w==}
     engines: {node: ^10.12.0 || >=12.0.0}
     peerDependencies:
@@ -5929,14 +6002,14 @@ packages:
       is-glob: 4.0.3
       lodash: 4.17.21
       semver: 7.5.4
-      tsutils: 3.21.0(typescript@5.1.6)
-      typescript: 5.1.6
+      tsutils: 3.21.0(typescript@5.2.2)
+      typescript: 5.2.2
     transitivePeerDependencies:
       - supports-color
     dev: true
 
-  /@typescript-eslint/typescript-estree@5.59.11(typescript@5.1.6):
-    resolution: {integrity: sha512-YupOpot5hJO0maupJXixi6l5ETdrITxeo5eBOeuV7RSKgYdU3G5cxO49/9WRnJq9EMrB7AuTSLH/bqOsXi7wPA==}
+  /@typescript-eslint/typescript-estree@5.62.0(typescript@5.2.2):
+    resolution: {integrity: sha512-CmcQ6uY7b9y694lKdRB8FEel7JbU/40iSAPomu++SjLMntB+2Leay2LO6i8VnJk58MtE9/nQSFIH6jpyRWyYzA==}
     engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
     peerDependencies:
       typescript: '*'
@@ -5944,19 +6017,19 @@ packages:
       typescript:
         optional: true
     dependencies:
-      '@typescript-eslint/types': 5.59.11
-      '@typescript-eslint/visitor-keys': 5.59.11
+      '@typescript-eslint/types': 5.62.0
+      '@typescript-eslint/visitor-keys': 5.62.0
       debug: 4.3.4
       globby: 11.1.0
       is-glob: 4.0.3
       semver: 7.5.4
-      tsutils: 3.21.0(typescript@5.1.6)
-      typescript: 5.1.6
+      tsutils: 3.21.0(typescript@5.2.2)
+      typescript: 5.2.2
     transitivePeerDependencies:
       - supports-color
     dev: true
 
-  /@typescript-eslint/typescript-estree@6.2.0(typescript@5.1.6):
+  /@typescript-eslint/typescript-estree@6.2.0(typescript@5.2.2):
     resolution: {integrity: sha512-Mts6+3HQMSM+LZCglsc2yMIny37IhUgp1Qe8yJUYVyO6rHP7/vN0vajKu3JvHCBIy8TSiKddJ/Zwu80jhnGj1w==}
     engines: {node: ^16.0.0 || >=18.0.0}
     peerDependencies:
@@ -5971,24 +6044,24 @@ packages:
       globby: 11.1.0
       is-glob: 4.0.3
       semver: 7.5.4
-      ts-api-utils: 1.0.1(typescript@5.1.6)
-      typescript: 5.1.6
+      ts-api-utils: 1.0.3(typescript@5.2.2)
+      typescript: 5.2.2
     transitivePeerDependencies:
       - supports-color
     dev: true
 
-  /@typescript-eslint/utils@5.59.11(eslint@8.45.0)(typescript@5.1.6):
-    resolution: {integrity: sha512-didu2rHSOMUdJThLk4aZ1Or8IcO3HzCw/ZvEjTTIfjIrcdd5cvSIwwDy2AOlE7htSNp7QIZ10fLMyRCveesMLg==}
+  /@typescript-eslint/utils@5.62.0(eslint@8.45.0)(typescript@5.2.2):
+    resolution: {integrity: sha512-n8oxjeb5aIbPFEtmQxQYOLI0i9n5ySBEY/ZEHHZqKQSFnxio1rv6dthascc9dLuwrL0RC5mPCxB7vnAVGAYWAQ==}
     engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
     peerDependencies:
       eslint: ^6.0.0 || ^7.0.0 || ^8.0.0
     dependencies:
       '@eslint-community/eslint-utils': 4.4.0(eslint@8.45.0)
-      '@types/json-schema': 7.0.12
-      '@types/semver': 7.5.0
-      '@typescript-eslint/scope-manager': 5.59.11
-      '@typescript-eslint/types': 5.59.11
-      '@typescript-eslint/typescript-estree': 5.59.11(typescript@5.1.6)
+      '@types/json-schema': 7.0.13
+      '@types/semver': 7.5.3
+      '@typescript-eslint/scope-manager': 5.62.0
+      '@typescript-eslint/types': 5.62.0
+      '@typescript-eslint/typescript-estree': 5.62.0(typescript@5.2.2)
       eslint: 8.45.0
       eslint-scope: 5.1.1
       semver: 7.5.4
@@ -5997,18 +6070,18 @@ packages:
       - typescript
     dev: true
 
-  /@typescript-eslint/utils@6.2.0(eslint@8.45.0)(typescript@5.1.6):
+  /@typescript-eslint/utils@6.2.0(eslint@8.45.0)(typescript@5.2.2):
     resolution: {integrity: sha512-RCFrC1lXiX1qEZN8LmLrxYRhOkElEsPKTVSNout8DMzf8PeWoQG7Rxz2SadpJa3VSh5oYKGwt7j7X/VRg+Y3OQ==}
     engines: {node: ^16.0.0 || >=18.0.0}
     peerDependencies:
       eslint: ^7.0.0 || ^8.0.0
     dependencies:
       '@eslint-community/eslint-utils': 4.4.0(eslint@8.45.0)
-      '@types/json-schema': 7.0.12
-      '@types/semver': 7.5.0
+      '@types/json-schema': 7.0.13
+      '@types/semver': 7.5.3
       '@typescript-eslint/scope-manager': 6.2.0
       '@typescript-eslint/types': 6.2.0
-      '@typescript-eslint/typescript-estree': 6.2.0(typescript@5.1.6)
+      '@typescript-eslint/typescript-estree': 6.2.0(typescript@5.2.2)
       eslint: 8.45.0
       semver: 7.5.4
     transitivePeerDependencies:
@@ -6023,12 +6096,12 @@ packages:
       eslint-visitor-keys: 1.3.0
     dev: true
 
-  /@typescript-eslint/visitor-keys@5.59.11:
-    resolution: {integrity: sha512-KGYniTGG3AMTuKF9QBD7EIrvufkB6O6uX3knP73xbKLMpH+QRPcgnCxjWXSHjMRuOxFLovljqQgQpR0c7GvjoA==}
+  /@typescript-eslint/visitor-keys@5.62.0:
+    resolution: {integrity: sha512-07ny+LHRzQXepkGg6w0mFY41fVUNBrL2Roj/++7V1txKugfjm/Ci/qSND03r2RhlJhJYMcTn9AhhSSqQp0Ysyw==}
     engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
     dependencies:
-      '@typescript-eslint/types': 5.59.11
-      eslint-visitor-keys: 3.4.1
+      '@typescript-eslint/types': 5.62.0
+      eslint-visitor-keys: 3.4.3
     dev: true
 
   /@typescript-eslint/visitor-keys@6.2.0:
@@ -6036,24 +6109,12 @@ packages:
     engines: {node: ^16.0.0 || >=18.0.0}
     dependencies:
       '@typescript-eslint/types': 6.2.0
-      eslint-visitor-keys: 3.4.1
+      eslint-visitor-keys: 3.4.3
     dev: true
 
-  /@unocss/astro@0.55.7(vite@4.4.7):
-    resolution: {integrity: sha512-mw8r14ArxUQBVCCisAJlF/WsZb650iBsduD/lXMk56N/nQ3MMArCcn62kcAxgZSb5tfIOQGQu/tbR8hEcD8y2g==}
-    peerDependencies:
-      vite: ^2.9.0 || ^3.0.0-0 || ^4.0.0
-    peerDependenciesMeta:
-      vite:
-        optional: true
-    dependencies:
-      '@unocss/core': 0.55.7
-      '@unocss/reset': 0.55.7
-      '@unocss/vite': 0.55.7(vite@4.4.7)
-      vite: 4.4.7(@types/node@20.4.4)(sass@1.64.1)(terser@5.19.2)
-    transitivePeerDependencies:
-      - rollup
-    dev: true
+  /@ungap/structured-clone@1.2.0:
+    resolution: {integrity: sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==}
+    dev: false
 
   /@unocss/astro@0.55.7(vite@4.4.9):
     resolution: {integrity: sha512-mw8r14ArxUQBVCCisAJlF/WsZb650iBsduD/lXMk56N/nQ3MMArCcn62kcAxgZSb5tfIOQGQu/tbR8hEcD8y2g==}
@@ -6066,10 +6127,9 @@ packages:
       '@unocss/core': 0.55.7
       '@unocss/reset': 0.55.7
       '@unocss/vite': 0.55.7(vite@4.4.9)
-      vite: 4.4.9(sass@1.64.1)
+      vite: 4.4.9(@types/node@20.4.4)(sass@1.64.1)(terser@5.19.2)
     transitivePeerDependencies:
       - rollup
-    dev: false
 
   /@unocss/cli@0.55.7:
     resolution: {integrity: sha512-ZHX2SR2WQbKfcmgOOHjBLB3V57Ct76Zb76YULzBj2EVX43lX/YDCVG87n6ePDY7rOcjCAthjrFQYCLV5KVLKHg==}
@@ -6077,7 +6137,7 @@ packages:
     hasBin: true
     dependencies:
       '@ampproject/remapping': 2.2.1
-      '@rollup/pluginutils': 5.0.4(rollup@3.26.2)
+      '@rollup/pluginutils': 5.0.5(rollup@3.29.4)
       '@unocss/config': 0.55.7
       '@unocss/core': 0.55.7
       '@unocss/preset-uno': 0.55.7
@@ -6086,7 +6146,7 @@ packages:
       colorette: 2.0.20
       consola: 3.2.3
       fast-glob: 3.3.1
-      magic-string: 0.30.3
+      magic-string: 0.30.4
       pathe: 1.1.1
       perfect-debounce: 1.0.0
     transitivePeerDependencies:
@@ -6097,7 +6157,7 @@ packages:
     engines: {node: '>=14'}
     dependencies:
       '@unocss/core': 0.55.7
-      unconfig: 0.3.10
+      unconfig: 0.3.11
 
   /@unocss/core@0.55.7:
     resolution: {integrity: sha512-c+bWe844Xjlwc1EPwHj0+n3LpntJG7ELPbEOOxNIG+CQdcEX0l1G0rkM8+nKstJ9WJmgpf1HdJQLVMF62HXvhw==}
@@ -6113,7 +6173,7 @@ packages:
       gzip-size: 6.0.0
       sirv: 2.0.3
 
-  /@unocss/postcss@0.55.7(postcss@8.4.29):
+  /@unocss/postcss@0.55.7(postcss@8.4.31):
     resolution: {integrity: sha512-53Z/yv/CNdlTqKZQ9gpYRoLZSuzQ28J0SDrGCdzwjLcvHG/FD7/x1S7yxE7cUp/4sjvLL15HSzkWq8vNy6SkwQ==}
     engines: {node: '>=14'}
     peerDependencies:
@@ -6123,8 +6183,8 @@ packages:
       '@unocss/core': 0.55.7
       css-tree: 2.3.1
       fast-glob: 3.3.1
-      magic-string: 0.30.3
-      postcss: 8.4.29
+      magic-string: 0.30.4
+      postcss: 8.4.31
 
   /@unocss/preset-attributify@0.55.7:
     resolution: {integrity: sha512-L1sNw3DyM4mymIm4DBTTTOllk8LmhYlWMgDlaAW2MYWygjqDCsp99wRKT2175Ya5xHYBA6XetMoBryZD23qJYQ==}
@@ -6134,7 +6194,7 @@ packages:
   /@unocss/preset-icons@0.55.7:
     resolution: {integrity: sha512-JXLOHkyEKKAjLTqjAxYfhwln05WXilGg3jctkZWKpMNawPaonrGt3kZT12YMuMmOryxk7UcyKB0dtYc+p3QYvw==}
     dependencies:
-      '@iconify/utils': 2.1.9
+      '@iconify/utils': 2.1.11
       '@unocss/core': 0.55.7
       ofetch: 1.3.3
     transitivePeerDependencies:
@@ -6208,13 +6268,13 @@ packages:
     dependencies:
       '@unocss/core': 0.55.7
 
-  /@unocss/vite@0.55.7(vite@4.4.7):
+  /@unocss/vite@0.55.7(vite@4.4.9):
     resolution: {integrity: sha512-xmdyDnt9Ag4o7DGl22/P6MaB+HSjWOQw9qYYzIefSv3SVUvn3cEhIX/PCWqFp8Kts2HyvAoJLbZmygSf1XdZNQ==}
     peerDependencies:
       vite: ^2.9.0 || ^3.0.0-0 || ^4.0.0
     dependencies:
       '@ampproject/remapping': 2.2.1
-      '@rollup/pluginutils': 5.0.4(rollup@3.26.2)
+      '@rollup/pluginutils': 5.0.5(rollup@3.29.4)
       '@unocss/config': 0.55.7
       '@unocss/core': 0.55.7
       '@unocss/inspector': 0.55.7
@@ -6222,58 +6282,37 @@ packages:
       '@unocss/transformer-directives': 0.55.7
       chokidar: 3.5.3
       fast-glob: 3.3.1
-      magic-string: 0.30.3
-      vite: 4.4.7(@types/node@20.4.4)(sass@1.64.1)(terser@5.19.2)
+      magic-string: 0.30.4
+      vite: 4.4.9(@types/node@20.4.4)(sass@1.64.1)(terser@5.19.2)
     transitivePeerDependencies:
       - rollup
-    dev: true
 
-  /@unocss/vite@0.55.7(vite@4.4.9):
-    resolution: {integrity: sha512-xmdyDnt9Ag4o7DGl22/P6MaB+HSjWOQw9qYYzIefSv3SVUvn3cEhIX/PCWqFp8Kts2HyvAoJLbZmygSf1XdZNQ==}
+  /@vrite/tiptap-solid@1.0.0(@tiptap/core@2.1.8)(@tiptap/pm@2.1.8)(solid-js@1.7.11):
+    resolution: {integrity: sha512-eSv3kr8VAjyZ8aVEfhzIGe/LLDAcdBS0GEcWr+Eaab3tM6N11PIhI/1vlufU02uAF0JFY4yx/NA1jvGLU8jEWw==}
     peerDependencies:
-      vite: ^2.9.0 || ^3.0.0-0 || ^4.0.0
-    dependencies:
-      '@ampproject/remapping': 2.2.1
-      '@rollup/pluginutils': 5.0.4(rollup@3.26.2)
-      '@unocss/config': 0.55.7
-      '@unocss/core': 0.55.7
-      '@unocss/inspector': 0.55.7
-      '@unocss/scope': 0.55.7
-      '@unocss/transformer-directives': 0.55.7
-      chokidar: 3.5.3
-      fast-glob: 3.3.1
-      magic-string: 0.30.3
-      vite: 4.4.9(sass@1.64.1)
-    transitivePeerDependencies:
-      - rollup
-    dev: false
-
-  /@vrite/tiptap-solid@1.0.0(@tiptap/core@2.1.8)(@tiptap/pm@2.1.8)(solid-js@1.7.8):
-    resolution: {integrity: sha512-eSv3kr8VAjyZ8aVEfhzIGe/LLDAcdBS0GEcWr+Eaab3tM6N11PIhI/1vlufU02uAF0JFY4yx/NA1jvGLU8jEWw==}
-    peerDependencies:
-      '@tiptap/core': 2.1.8
-      '@tiptap/pm': 2.1.8
-      solid-js: ^1.7.11
+      '@tiptap/core': 2.1.8
+      '@tiptap/pm': 2.1.8
+      solid-js: ^1.7.11
     dependencies:
       '@tiptap/core': 2.1.8(@tiptap/pm@2.1.8)
       '@tiptap/extension-bubble-menu': 2.1.8(@tiptap/core@2.1.8)(@tiptap/pm@2.1.8)
       '@tiptap/extension-floating-menu': 2.1.8(@tiptap/core@2.1.8)(@tiptap/pm@2.1.8)
       '@tiptap/pm': 2.1.8
       nanoid: 4.0.2
-      solid-js: 1.7.8
+      solid-js: 1.7.11
     dev: false
 
-  /@vscode/emmet-helper@2.8.9:
-    resolution: {integrity: sha512-ygpVStaePHt9aI9zk4NNJWI/NsRaeDSW1vQsZVmtpVRVCOdwYlsc3BfB/eppUu1OucT0x3OHDAzKcxnitjcSXQ==}
+  /@vscode/emmet-helper@2.9.2:
+    resolution: {integrity: sha512-MaGuyW+fa13q3aYsluKqclmh62Hgp0BpKIqS66fCxfOaBcVQ1OnMQxRRgQUYnCkxFISAQlkJ0qWWPyXjro1Qrg==}
     dependencies:
-      emmet: 2.4.4
+      emmet: 2.4.6
       jsonc-parser: 2.3.1
-      vscode-languageserver-textdocument: 1.0.8
-      vscode-languageserver-types: 3.17.3
+      vscode-languageserver-textdocument: 1.0.11
+      vscode-languageserver-types: 3.17.5
       vscode-uri: 2.1.2
 
-  /@vscode/l10n@0.0.14:
-    resolution: {integrity: sha512-/yrv59IEnmh655z1oeDnGcvMYwnEzNzHLgeYcQCkhYX0xBvYWrAuefoiLcPBUkMpJsb46bqQ6Yv4pwTTQ4d3Qg==}
+  /@vscode/l10n@0.0.16:
+    resolution: {integrity: sha512-JT5CvrIYYCrmB+dCana8sUqJEcGB1ZDXNLMQ2+42bW995WmNoenijWMUdZfwmuQUTQcEVVIa2OecZzTYWUW9Cg==}
 
   /abbrev@1.1.1:
     resolution: {integrity: sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==}
@@ -6304,7 +6343,6 @@ packages:
       acorn: ^6.0.0 || ^7.0.0 || ^8.0.0
     dependencies:
       acorn: 8.10.0
-    dev: true
 
   /acorn-node@1.8.2:
     resolution: {integrity: sha512-8mt+fslDufLYntIoPAaIMUe/lrbrehIiwmR3t2k9LljIzoigEPF27eLk2hy8zSGzmR/ogr7zbRKINMo1u0yh5A==}
@@ -6387,8 +6425,8 @@ packages:
     resolution: {integrity: sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==}
     engines: {node: '>=12'}
 
-  /ansi-sequence-parser@1.1.0:
-    resolution: {integrity: sha512-lEm8mt52to2fT8GhciPCGeCXACSz2UwIN4X2e2LJSnZ5uAbn2/dsYdOmUXq0AtWS5cpAupysIneExOgH0Vd2TQ==}
+  /ansi-sequence-parser@1.1.1:
+    resolution: {integrity: sha512-vJXt3yiaUL4UU546s3rPXlsry/RnM730G1+HkpKE012AN0sx1eOrxSu95oKDIonskeLTijMgqWZ3uDEe3NFvyg==}
 
   /ansi-styles@3.2.1:
     resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==}
@@ -6436,13 +6474,13 @@ packages:
       is-array-buffer: 3.0.2
     dev: true
 
-  /array-includes@3.1.6:
-    resolution: {integrity: sha512-sgTbLvL6cNnw24FnbaDyjmvddQ2ML8arZsgaJhoABMoplz/4QRhtrYS+alr1BUM1Bwp6dhx8vVCBSLG+StwOFw==}
+  /array-includes@3.1.7:
+    resolution: {integrity: sha512-dlcsNBIiWhPkHdOEEKnehA+RNUWDc4UqFtnIXU4uuYDPtA4LDkr7qip2p0VvFAEXNDr0yWZ9PJyIRiGjRLQzwQ==}
     engines: {node: '>= 0.4'}
     dependencies:
       call-bind: 1.0.2
-      define-properties: 1.2.0
-      es-abstract: 1.21.2
+      define-properties: 1.2.1
+      es-abstract: 1.22.2
       get-intrinsic: 1.2.1
       is-string: 1.0.7
     dev: true
@@ -6454,26 +6492,39 @@ packages:
     resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==}
     engines: {node: '>=8'}
 
-  /array.prototype.flat@1.3.1:
-    resolution: {integrity: sha512-roTU0KWIOmJ4DRLmwKd19Otg0/mT3qPNt0Qb3GWW8iObuZXxrjB/pzn0R3hqpRSWg4HCwqx+0vwOnWnvlOyeIA==}
+  /array.prototype.flat@1.3.2:
+    resolution: {integrity: sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA==}
     engines: {node: '>= 0.4'}
     dependencies:
       call-bind: 1.0.2
-      define-properties: 1.2.0
-      es-abstract: 1.21.2
+      define-properties: 1.2.1
+      es-abstract: 1.22.2
       es-shim-unscopables: 1.0.0
     dev: true
 
-  /array.prototype.flatmap@1.3.1:
-    resolution: {integrity: sha512-8UGn9O1FDVvMNB0UlLv4voxRMze7+FpHyF5mSMRjWHUMlpoDViniy05870VlxhfgTnLbpuwTzvD76MTtWxB/mQ==}
+  /array.prototype.flatmap@1.3.2:
+    resolution: {integrity: sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ==}
     engines: {node: '>= 0.4'}
     dependencies:
       call-bind: 1.0.2
-      define-properties: 1.2.0
-      es-abstract: 1.21.2
+      define-properties: 1.2.1
+      es-abstract: 1.22.2
       es-shim-unscopables: 1.0.0
     dev: true
 
+  /arraybuffer.prototype.slice@1.0.2:
+    resolution: {integrity: sha512-yMBKppFur/fbHu9/6USUe03bZ4knMYiwFBcyiaXB8Go0qNehwX6inYPzK9U0NeQvGxKthcmHcaR8P5MStSRBAw==}
+    engines: {node: '>= 0.4'}
+    dependencies:
+      array-buffer-byte-length: 1.0.0
+      call-bind: 1.0.2
+      define-properties: 1.2.1
+      es-abstract: 1.22.2
+      get-intrinsic: 1.2.1
+      is-array-buffer: 3.0.2
+      is-shared-array-buffer: 1.0.2
+    dev: true
+
   /asn1.js@5.4.1:
     resolution: {integrity: sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA==}
     dependencies:
@@ -6483,6 +6534,30 @@ packages:
       safer-buffer: 2.1.2
     dev: false
 
+  /astring@1.8.6:
+    resolution: {integrity: sha512-ISvCdHdlTDlH5IpxQJIex7BWBywFWgjJSVdwst+/iQCoEYnyOaQ95+X1JGshuBjGp6nxKUy1jMgE3zPqN7fQdg==}
+    hasBin: true
+    dev: false
+
+  /astro-auto-import@0.3.1(astro@3.1.0):
+    resolution: {integrity: sha512-4kXZMlZFiq3dqT6fcfPbCjHTABQ279eKbIqZAb6qktBhGlmHwpHr1spOUFj/RQFilaWVgfjzOBmuZnoydZb5Vg==}
+    engines: {node: '>=16.0.0'}
+    peerDependencies:
+      astro: ^2.0.0 || ^3.0.0-beta
+    dependencies:
+      '@types/node': 18.18.4
+      acorn: 8.10.0
+      astro: 3.1.0(sass@1.64.1)
+    dev: false
+
+  /astro-icon@0.8.1:
+    resolution: {integrity: sha512-APk+fbFnoyGdIVSPFrdrOW9YBK96/1fYuVe7ULTGW92+z00RKB8GfLJiUvzNVXUAX2rZJCFmruGVF4rrhcTYsg==}
+    dependencies:
+      node-fetch: 3.3.2
+      resolve-pkg: 2.0.0
+      svgo: 2.8.0
+    dev: false
+
   /astro-robots-txt@0.4.1:
     resolution: {integrity: sha512-YujWFocCHcOA+sDlaiqVsUH7eeHDOn9WrtsyT7KPW3JOHn1dZB1KwoshsPGTJiZ0PeeAqPcHOz+M9xjzc/tjsQ==}
     dependencies:
@@ -6497,7 +6572,7 @@ packages:
     resolution: {integrity: sha512-6JQSLid4gMhoWjOm85UHLkgrw0+hHIjnJVIUqxjU2D6feKlVyYukMNYjH44ZDZBK1P8hNxd33PgWlHzCASvedA==}
     dependencies:
       valid-filename: 4.0.0
-      zod: 3.22.2
+      zod: 3.22.4
     dev: true
 
   /astro@2.10.15:
@@ -6516,25 +6591,25 @@ packages:
       '@astrojs/markdown-remark': 2.2.1(astro@2.10.15)
       '@astrojs/telemetry': 2.1.1
       '@astrojs/webapi': 2.2.0
-      '@babel/core': 7.22.15
-      '@babel/generator': 7.22.15
-      '@babel/parser': 7.22.16
-      '@babel/plugin-transform-react-jsx': 7.22.5(@babel/core@7.22.15)
-      '@babel/traverse': 7.22.15
-      '@babel/types': 7.22.15
-      '@types/babel__core': 7.20.1
-      '@types/dom-view-transitions': 1.0.1
-      '@types/yargs-parser': 21.0.0
+      '@babel/core': 7.23.0
+      '@babel/generator': 7.23.0
+      '@babel/parser': 7.23.0
+      '@babel/plugin-transform-react-jsx': 7.22.15(@babel/core@7.23.0)
+      '@babel/traverse': 7.23.0
+      '@babel/types': 7.23.0
+      '@types/babel__core': 7.20.2
+      '@types/dom-view-transitions': 1.0.2
+      '@types/yargs-parser': 21.0.1
       acorn: 8.10.0
       boxen: 6.2.1
       chokidar: 3.5.3
-      ci-info: 3.8.0
+      ci-info: 3.9.0
       common-ancestor-path: 1.0.1
       cookie: 0.5.0
       debug: 4.3.4
       devalue: 4.3.2
       diff: 5.1.0
-      es-module-lexer: 1.3.0
+      es-module-lexer: 1.3.1
       esbuild: 0.17.19
       estree-walker: 3.0.0
       execa: 6.1.0
@@ -6545,7 +6620,7 @@ packages:
       http-cache-semantics: 4.1.1
       js-yaml: 4.1.0
       kleur: 4.1.5
-      magic-string: 0.30.3
+      magic-string: 0.30.4
       mime: 3.0.0
       network-information-types: 0.1.1(typescript@5.2.2)
       ora: 6.3.1
@@ -6563,89 +6638,10 @@ packages:
       typescript: 5.2.2
       unist-util-visit: 4.1.2
       vfile: 5.3.7
-      vite: 4.4.9(sass@1.64.1)
+      vite: 4.4.9(@types/node@20.4.4)(sass@1.64.1)(terser@5.19.2)
       vitefu: 0.2.4(vite@4.4.9)
       which-pm: 2.1.1
       yargs-parser: 21.1.1
-      zod: 3.22.2
-    transitivePeerDependencies:
-      - '@types/node'
-      - less
-      - lightningcss
-      - sass
-      - stylus
-      - sugarss
-      - supports-color
-      - terser
-    dev: false
-
-  /astro@2.9.2:
-    resolution: {integrity: sha512-ejdGM9SbK58AvJS8lbkre/d5CoW8JftqaRxc9rGqzpiZQ8iU8gfdFmi3Hzkcvd2HrGvYYsJku88pM6tkBPniJQ==}
-    engines: {node: '>=16.12.0', npm: '>=6.14.0'}
-    hasBin: true
-    peerDependencies:
-      sharp: '>=0.31.0'
-    peerDependenciesMeta:
-      sharp:
-        optional: true
-    dependencies:
-      '@astrojs/compiler': 1.6.2
-      '@astrojs/internal-helpers': 0.1.1
-      '@astrojs/language-server': 1.0.8
-      '@astrojs/markdown-remark': 2.2.1(astro@2.9.2)
-      '@astrojs/telemetry': 2.1.1
-      '@astrojs/webapi': 2.2.0
-      '@babel/core': 7.22.5
-      '@babel/generator': 7.22.5
-      '@babel/parser': 7.22.5
-      '@babel/plugin-transform-react-jsx': 7.22.5(@babel/core@7.22.5)
-      '@babel/traverse': 7.22.5
-      '@babel/types': 7.22.5
-      '@types/babel__core': 7.20.1
-      '@types/dom-view-transitions': 1.0.1
-      '@types/yargs-parser': 21.0.0
-      acorn: 8.10.0
-      boxen: 6.2.1
-      chokidar: 3.5.3
-      ci-info: 3.8.0
-      common-ancestor-path: 1.0.1
-      cookie: 0.5.0
-      debug: 4.3.4
-      deepmerge-ts: 4.3.0
-      devalue: 4.3.2
-      diff: 5.1.0
-      es-module-lexer: 1.3.0
-      esbuild: 0.17.19
-      estree-walker: 3.0.0
-      execa: 6.1.0
-      fast-glob: 3.3.1
-      github-slugger: 2.0.0
-      gray-matter: 4.0.3
-      html-escaper: 3.0.3
-      js-yaml: 4.1.0
-      kleur: 4.1.5
-      magic-string: 0.27.0
-      mime: 3.0.0
-      network-information-types: 0.1.1(typescript@5.2.2)
-      ora: 6.3.1
-      p-limit: 4.0.0
-      path-to-regexp: 6.2.1
-      preferred-pm: 3.0.3
-      prompts: 2.4.2
-      rehype: 12.0.1
-      semver: 7.5.4
-      server-destroy: 1.0.1
-      shiki: 0.14.4
-      string-width: 5.1.2
-      strip-ansi: 7.1.0
-      tsconfig-resolver: 3.0.1
-      typescript: 5.2.2
-      unist-util-visit: 4.1.2
-      vfile: 5.3.7
-      vite: 4.4.9(sass@1.64.1)
-      vitefu: 0.2.4(vite@4.4.9)
-      which-pm: 2.0.0
-      yargs-parser: 21.1.1
       zod: 3.21.4
     transitivePeerDependencies:
       - '@types/node'
@@ -6656,36 +6652,35 @@ packages:
       - sugarss
       - supports-color
       - terser
-    dev: true
 
   /astro@3.1.0(sass@1.64.1):
     resolution: {integrity: sha512-hVPZg9uDafqJbDwOwtcujwhJ6Qp3BCaIj1cvablTYI0jdYrZSvcybhIMTf8NhzK5smvZy2Bv9eEDYXLpiLDrRQ==}
     engines: {node: '>=18.14.1', npm: '>=6.14.0'}
     hasBin: true
     dependencies:
-      '@astrojs/compiler': 2.1.0
+      '@astrojs/compiler': 2.2.0
       '@astrojs/internal-helpers': 0.2.0
       '@astrojs/markdown-remark': 3.2.0(astro@3.1.0)
       '@astrojs/telemetry': 3.0.1
-      '@babel/core': 7.22.15
-      '@babel/generator': 7.22.15
-      '@babel/parser': 7.22.16
-      '@babel/plugin-transform-react-jsx': 7.22.5(@babel/core@7.22.15)
-      '@babel/traverse': 7.22.15
-      '@babel/types': 7.22.15
-      '@types/babel__core': 7.20.1
+      '@babel/core': 7.23.0
+      '@babel/generator': 7.23.0
+      '@babel/parser': 7.23.0
+      '@babel/plugin-transform-react-jsx': 7.22.15(@babel/core@7.23.0)
+      '@babel/traverse': 7.23.0
+      '@babel/types': 7.23.0
+      '@types/babel__core': 7.20.2
       acorn: 8.10.0
       boxen: 7.1.1
       chokidar: 3.5.3
-      ci-info: 3.8.0
+      ci-info: 3.9.0
       clsx: 2.0.0
       common-ancestor-path: 1.0.1
       cookie: 0.5.0
       debug: 4.3.4
       devalue: 4.3.2
       diff: 5.1.0
-      es-module-lexer: 1.3.0
-      esbuild: 0.19.3
+      es-module-lexer: 1.3.1
+      esbuild: 0.19.4
       estree-walker: 3.0.3
       execa: 8.0.1
       fast-glob: 3.3.1
@@ -6695,7 +6690,7 @@ packages:
       http-cache-semantics: 4.1.1
       js-yaml: 4.1.0
       kleur: 4.1.5
-      magic-string: 0.30.3
+      magic-string: 0.30.4
       mime: 3.0.0
       ora: 7.0.1
       p-limit: 4.0.0
@@ -6704,17 +6699,17 @@ packages:
       probe-image-size: 7.2.3
       prompts: 2.4.2
       rehype: 12.0.1
-      resolve: 1.22.4
+      resolve: 1.22.6
       semver: 7.5.4
       server-destroy: 1.0.1
       shiki: 0.14.4
       string-width: 6.1.0
       strip-ansi: 7.1.0
       tsconfig-resolver: 3.0.1
-      undici: 5.23.0
+      undici: 5.25.4
       unist-util-visit: 4.1.2
       vfile: 5.3.7
-      vite: 4.4.9(sass@1.64.1)
+      vite: 4.4.9(@types/node@20.4.4)(sass@1.64.1)(terser@5.19.2)
       vitefu: 0.2.4(vite@4.4.9)
       which-pm: 2.1.1
       yargs-parser: 21.1.1
@@ -6762,7 +6757,7 @@ packages:
   /axios@0.26.1:
     resolution: {integrity: sha512-fPwcX4EvnSHuInCMItEhAGnaSEXRBjtzh9fOtsE6E1G6p7vl7edEeZe11QHf18+6+9gR5PbKV/sGKNaD8YaMeA==}
     dependencies:
-      follow-redirects: 1.15.2
+      follow-redirects: 1.15.3
     transitivePeerDependencies:
       - debug
     dev: false
@@ -6770,7 +6765,7 @@ packages:
   /axios@1.4.0:
     resolution: {integrity: sha512-S4XCWMEmzvo64T9GfvQDOXgYRDJ/wsSZc7Jvdgx5u1sd0JwsuPLqb3SYmusag+edF6ziyMensPVqLTSc1PiSEA==}
     dependencies:
-      follow-redirects: 1.15.2
+      follow-redirects: 1.15.3
       form-data: 4.0.0
       proxy-from-env: 1.1.0
     transitivePeerDependencies:
@@ -6780,57 +6775,25 @@ packages:
   /b4a@1.6.4:
     resolution: {integrity: sha512-fpWrvyVHEKyeEvbKZTVOeZF3VSKKWtJxFIxX/jaVPf+cLbGUSitjb49pHLqPV2BUNNZ0LcoeEGfE/YCpyDYHIw==}
 
-  /babel-merge@3.0.0(@babel/core@7.22.15):
-    resolution: {integrity: sha512-eBOBtHnzt9xvnjpYNI5HmaPp/b2vMveE5XggzqHnQeHJ8mFIBrBv6WZEVIj5jJ2uwTItkqKo9gWzEEcBxEq0yw==}
-    peerDependencies:
-      '@babel/core': ^7.0.0
-    dependencies:
-      '@babel/core': 7.22.15
-      deepmerge: 2.2.1
-      object.omit: 3.0.0
-    dev: false
-
-  /babel-plugin-jsx-dom-expressions@0.36.10(@babel/core@7.22.15):
-    resolution: {integrity: sha512-QA2k/14WGw+RgcGGnEuLWwnu4em6CGhjeXtjvgOYyFHYS2a+CzPeaVQHDOlfuiBcjq/3hWMspHMIMnPEOIzdBg==}
-    peerDependencies:
-      '@babel/core': ^7.20.12
-    dependencies:
-      '@babel/core': 7.22.15
-      '@babel/helper-module-imports': 7.18.6
-      '@babel/plugin-syntax-jsx': 7.22.5(@babel/core@7.22.15)
-      '@babel/types': 7.22.15
-      html-entities: 2.3.3
-      validate-html-nesting: 1.2.2
-    dev: false
-
-  /babel-plugin-jsx-dom-expressions@0.36.10(@babel/core@7.22.5):
-    resolution: {integrity: sha512-QA2k/14WGw+RgcGGnEuLWwnu4em6CGhjeXtjvgOYyFHYS2a+CzPeaVQHDOlfuiBcjq/3hWMspHMIMnPEOIzdBg==}
+  /babel-plugin-jsx-dom-expressions@0.36.18(@babel/core@7.23.0):
+    resolution: {integrity: sha512-8K0CHgzNMB0+1OC+GQf1O49Nc6DfHAoWDjY4YTW3W/3il5KrDKAj65723oPmya68kKKOkqDKuz+Zh1u7VFHthw==}
     peerDependencies:
       '@babel/core': ^7.20.12
     dependencies:
-      '@babel/core': 7.22.5
+      '@babel/core': 7.23.0
       '@babel/helper-module-imports': 7.18.6
-      '@babel/plugin-syntax-jsx': 7.22.5(@babel/core@7.22.5)
-      '@babel/types': 7.22.15
+      '@babel/plugin-syntax-jsx': 7.22.5(@babel/core@7.23.0)
+      '@babel/types': 7.23.0
       html-entities: 2.3.3
       validate-html-nesting: 1.2.2
 
-  /babel-preset-solid@1.7.4(@babel/core@7.22.5):
-    resolution: {integrity: sha512-0mbHNYkbOVYhH6L95VlHVkBEVQjOXSzUqLDiFxUcsg/tU4yTM/qx7FI8C+kmos9LHckQBSm3wtwoe1BZLNJR1w==}
-    peerDependencies:
-      '@babel/core': ^7.0.0
-    dependencies:
-      '@babel/core': 7.22.5
-      babel-plugin-jsx-dom-expressions: 0.36.10(@babel/core@7.22.5)
-
-  /babel-preset-solid@1.7.7(@babel/core@7.22.15):
-    resolution: {integrity: sha512-tdxVzx3kgcIjNXAOmGRbzIhFBPeJjSakiN9yM+IYdL/+LtXNnbGqb0Va5tJb8Sjbk+QVEriovCyuzB5T7jeTvg==}
+  /babel-preset-solid@1.7.12(@babel/core@7.23.0):
+    resolution: {integrity: sha512-vNZn34Dv6IsWK/F59HhZlN8gP0ihZfkhPp8Lx/nxlY+rKtSZEAmmYlXWtds6EDKSiXoj2TEHuCcuqp6cO7oLSg==}
     peerDependencies:
       '@babel/core': ^7.0.0
     dependencies:
-      '@babel/core': 7.22.15
-      babel-plugin-jsx-dom-expressions: 0.36.10(@babel/core@7.22.15)
-    dev: false
+      '@babel/core': 7.23.0
+      babel-plugin-jsx-dom-expressions: 0.36.18(@babel/core@7.23.0)
 
   /bail@2.0.2:
     resolution: {integrity: sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==}
@@ -6951,18 +6914,18 @@ packages:
     dependencies:
       fill-range: 7.0.1
 
-  /browserslist@4.21.10:
-    resolution: {integrity: sha512-bipEBdZfVH5/pwrvqc+Ub0kUPVfGUhlKxbvfD+z1BDnPEO/X98ruXGA1WP5ASpAFKan7Qr6j736IacbZQuAlKQ==}
+  /browserslist@4.22.1:
+    resolution: {integrity: sha512-FEVc202+2iuClEhZhrWy6ZiAcRLvNMyYcxZ8raemul1DYVOVdFsbqckWLdsixQZCpJlwe77Z3UTalE7jsjnKfQ==}
     engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7}
     hasBin: true
     dependencies:
-      caniuse-lite: 1.0.30001528
-      electron-to-chromium: 1.4.510
+      caniuse-lite: 1.0.30001546
+      electron-to-chromium: 1.4.544
       node-releases: 2.0.13
-      update-browserslist-db: 1.0.11(browserslist@4.21.10)
+      update-browserslist-db: 1.0.13(browserslist@4.22.1)
 
-  /bson@5.4.0:
-    resolution: {integrity: sha512-WRZ5SQI5GfUuKnPTNmAYPiKIof3ORXAF4IRU5UcgmivNIon01rWQlw5RUH954dpu8yGL8T59YShVddIPaU/gFA==}
+  /bson@5.5.0:
+    resolution: {integrity: sha512-B+QB4YmDx9RStKv8LLSl/aVIEV3nYJc3cJNNTK2Cd1TL+7P+cNpw9mAPeCgc5K+j01Dv6sxUzcITXDx7ZU3F0w==}
     engines: {node: '>=14.20.1'}
     dev: false
 
@@ -6976,7 +6939,6 @@ packages:
 
   /buffer-from@1.1.2:
     resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==}
-    dev: true
 
   /buffer-indexof-polyfill@1.0.2:
     resolution: {integrity: sha512-I7wzHwA3t1/lwXQh+A5PbNvJxgfo5r3xulgpYDB5zckTu/Z9oUK9biouBKQUjEqzaz3HnAT6TYoovmE+GqSf7A==}
@@ -7011,12 +6973,6 @@ packages:
     dependencies:
       run-applescript: 5.0.0
 
-  /busboy@1.6.0:
-    resolution: {integrity: sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==}
-    engines: {node: '>=10.16.0'}
-    dependencies:
-      streamsearch: 1.1.0
-
   /bytes@3.1.2:
     resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==}
     engines: {node: '>= 0.8'}
@@ -7050,8 +7006,8 @@ packages:
     resolution: {integrity: sha512-xlx1yCK2Oc1APsPXDL2LdlNP6+uu8OCDdhOBSVT279M/S+y75O30C2VuD8T2ogdePBBl7PfPF4504tnLgX3zfw==}
     engines: {node: '>=14.16'}
 
-  /caniuse-lite@1.0.30001528:
-    resolution: {integrity: sha512-0Db4yyjR9QMNlsxh+kKWzQtkyflkG/snYheSzkjmvdEtEXB1+jt7A2HmSEiO6XIJPIbo92lHNGNySvE5pZcs5Q==}
+  /caniuse-lite@1.0.30001546:
+    resolution: {integrity: sha512-zvtSJwuQFpewSyRrI3AsftF6rM0X80mZkChIt1spBGEvRglCrjTniXvinc8JKRoqTwXAgvqTImaN9igfSMtUBw==}
 
   /case-anything@2.1.13:
     resolution: {integrity: sha512-zlOQ80VrQ2Ue+ymH5OuM/DlDq64mEm+B9UTdHULv5osUMD6HalNTblf2b1u/m6QecjsnOkBpqVZ+XPwIVsy7Ng==}
@@ -7095,6 +7051,10 @@ packages:
   /character-entities@2.0.2:
     resolution: {integrity: sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==}
 
+  /character-reference-invalid@2.0.1:
+    resolution: {integrity: sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw==}
+    dev: false
+
   /chardet@1.6.0:
     resolution: {integrity: sha512-+QOTw3otC4+FxdjK9RopGpNOglADbr4WPFi0SonkO99JbpkTPbMxmdm4NenhF5Zs+4gPXLI1+y2uazws5TMe8w==}
     dev: false
@@ -7139,7 +7099,7 @@ packages:
       normalize-path: 3.0.0
       readdirp: 3.6.0
     optionalDependencies:
-      fsevents: 2.3.2
+      fsevents: 2.3.3
 
   /chownr@1.1.4:
     resolution: {integrity: sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==}
@@ -7148,10 +7108,16 @@ packages:
     resolution: {integrity: sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==}
     dev: true
 
-  /ci-info@3.8.0:
-    resolution: {integrity: sha512-eXTggHWSooYhq49F2opQhuHWgzucfF2YgODK4e1566GQs5BIfP30B0oenwBJHfWxAs2fyPB1s7Mg949zLf61Yw==}
+  /ci-info@3.9.0:
+    resolution: {integrity: sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==}
     engines: {node: '>=8'}
 
+  /citty@0.1.4:
+    resolution: {integrity: sha512-Q3bK1huLxzQrvj7hImJ7Z1vKYJRPQCDnd0EjXfHMidcjecGOMuLrmuQmtWmFkuKLcMThlGh1yCKG8IEc6VeNXQ==}
+    dependencies:
+      consola: 3.2.3
+    dev: true
+
   /clean-regexp@1.0.0:
     resolution: {integrity: sha512-GfisEZEJvzKrmGWkvfhgzcz/BllN1USeqD2V6tg14OAOgaCD2Z/PUEuxnAZ/nPvmaHRG7a8y77p1T/IRQ4D1Hw==}
     engines: {node: '>=4'}
@@ -7181,8 +7147,8 @@ packages:
     dependencies:
       restore-cursor: 4.0.0
 
-  /cli-spinners@2.9.0:
-    resolution: {integrity: sha512-4/aL9X3Wh0yiMQlE+eeRhWP6vclO3QRtw1JHKIT0FFUs5FjpFmESqtMvYZ0+lbzBw900b95mS0hohy+qn2VK/g==}
+  /cli-spinners@2.9.1:
+    resolution: {integrity: sha512-jHgecW0pxkonBJdrKsqxgRX9AcG+u/5k0Q7WPDfi8AogLAdwxEkyYYNWwZ5GvVFoFx2uiY1eNcSK00fh+1+FyQ==}
     engines: {node: '>=6'}
 
   /clone@1.0.4:
@@ -7267,13 +7233,17 @@ packages:
 
   /commander@2.20.3:
     resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==}
-    dev: true
 
   /commander@5.1.0:
     resolution: {integrity: sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==}
     engines: {node: '>= 6'}
     dev: false
 
+  /commander@7.2.0:
+    resolution: {integrity: sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==}
+    engines: {node: '>= 10'}
+    dev: false
+
   /commander@9.4.1:
     resolution: {integrity: sha512-5EEkTNyHNGFPD2H+c/dXXfQZYa/scCKasxWcXJaWnNJ99pnQN9Vnmqow+p+PlFPE63Q6mThaZws1T+HxfpgtPw==}
     engines: {node: ^12.20.0 || >=14}
@@ -7321,8 +7291,8 @@ packages:
       safe-buffer: 5.2.1
     dev: false
 
-  /convert-source-map@1.9.0:
-    resolution: {integrity: sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==}
+  /convert-source-map@2.0.0:
+    resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==}
 
   /cookie-es@1.0.0:
     resolution: {integrity: sha512-mWYvfOLrfEc996hlKcdABeIiPHUPC6DM2QYZdGGOvhOTbA3tjm2eBwqlJpoFdjC89NI4Qt6h0Pu06Mp+1Pj5OQ==}
@@ -7343,7 +7313,7 @@ packages:
   /cross-fetch@3.1.8:
     resolution: {integrity: sha512-cvA+JwZoU0Xq+h6WkMvAUqPEYy92Obet6UdKLfW60qn99ftItKjB5T+BkyWOFWe2pUyfQ+IJHmpOTznqk1M6Kg==}
     dependencies:
-      node-fetch: 2.6.12
+      node-fetch: 2.7.0
     transitivePeerDependencies:
       - encoding
     dev: false
@@ -7360,6 +7330,16 @@ packages:
     resolution: {integrity: sha512-mCxBlsHFYh9C+HVpiEacem8FEBnMXgU9gy4zmNC+SXAZNB/1idgp/aulFJ4FgCi7GPEVbfyng092GqL2k2rmow==}
     dev: false
 
+  /css-select@4.3.0:
+    resolution: {integrity: sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ==}
+    dependencies:
+      boolbase: 1.0.0
+      css-what: 6.1.0
+      domhandler: 4.3.1
+      domutils: 2.8.0
+      nth-check: 2.1.1
+    dev: false
+
   /css-select@5.1.0:
     resolution: {integrity: sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==}
     dependencies:
@@ -7370,6 +7350,14 @@ packages:
       nth-check: 2.1.1
     dev: false
 
+  /css-tree@1.1.3:
+    resolution: {integrity: sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==}
+    engines: {node: '>=8.0.0'}
+    dependencies:
+      mdn-data: 2.0.14
+      source-map: 0.6.1
+    dev: false
+
   /css-tree@2.3.1:
     resolution: {integrity: sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==}
     engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0}
@@ -7388,6 +7376,13 @@ packages:
     hasBin: true
     dev: false
 
+  /csso@4.2.0:
+    resolution: {integrity: sha512-wvlcdIbf6pwKEk7vHj8/Bkc0B4ylXZruLvOgs9doS5eOsOpuodOV2zJChSpkp+pRpYQLQMeF04nr3Z68Sta9jA==}
+    engines: {node: '>=8.0.0'}
+    dependencies:
+      css-tree: 1.1.3
+    dev: false
+
   /csstype@3.1.2:
     resolution: {integrity: sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==}
 
@@ -7402,11 +7397,16 @@ packages:
     resolution: {integrity: sha512-4FbVrHDwfOASx7uQVxeiCTo7ggSdYZbqs8lH+WU6ViypPlDbe9y6IP5VVUDQBv9DcnyaiPT5XT0UWHgJ64zLeQ==}
     dev: false
 
+  /data-uri-to-buffer@4.0.1:
+    resolution: {integrity: sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==}
+    engines: {node: '>= 12'}
+    dev: false
+
   /date-fns@2.30.0:
     resolution: {integrity: sha512-fnULvOpxnC5/Vg3NCiWelDsLiUc9bRwAPs/+LfTLNvetFCtCTN+yQz15C/fs4AwX1R9K5GLtLfn8QW+dWisaAw==}
     engines: {node: '>=0.11'}
     dependencies:
-      '@babel/runtime': 7.22.5
+      '@babel/runtime': 7.23.1
     dev: false
 
   /dayjs@1.11.9:
@@ -7463,16 +7463,6 @@ packages:
     resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==}
     dev: true
 
-  /deepmerge-ts@4.3.0:
-    resolution: {integrity: sha512-if3ZYdkD2dClhnXR5reKtG98cwyaRT1NeugQoAPTTfsOpV9kqyeiBF9Qa5RHjemb3KzD5ulqygv6ED3t5j9eJw==}
-    engines: {node: '>=12.4.0'}
-    dev: true
-
-  /deepmerge@2.2.1:
-    resolution: {integrity: sha512-R9hc1Xa/NOBi9WRVUWg19rl1UB7Tt4kuPd+thNJgFZoxXsTz7ncaPaeIm+40oSGuP33DfMb4sZt1QIGiJzC4EA==}
-    engines: {node: '>=0.10.0'}
-    dev: false
-
   /deepmerge@4.3.1:
     resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==}
     engines: {node: '>=0.10.0'}
@@ -7490,7 +7480,7 @@ packages:
     dependencies:
       bundle-name: 3.0.0
       default-browser-id: 3.0.0
-      execa: 7.1.1
+      execa: 7.2.0
       titleize: 3.0.0
 
   /defaults@1.0.4:
@@ -7498,14 +7488,24 @@ packages:
     dependencies:
       clone: 1.0.4
 
+  /define-data-property@1.1.0:
+    resolution: {integrity: sha512-UzGwzcjyv3OtAvolTj1GoyNYzfFR+iqbGjcnBEENZVCpM4/Ng1yhGNvS3lR/xDS74Tb2wGG9WzNSNIOS9UVb2g==}
+    engines: {node: '>= 0.4'}
+    dependencies:
+      get-intrinsic: 1.2.1
+      gopd: 1.0.1
+      has-property-descriptors: 1.0.0
+    dev: true
+
   /define-lazy-prop@3.0.0:
     resolution: {integrity: sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==}
     engines: {node: '>=12'}
 
-  /define-properties@1.2.0:
-    resolution: {integrity: sha512-xvqAVKGfT1+UAvPwKTVw/njhdQ8ZhXK4lI0bCIuCMrp2up9nPnaDftrLtmpTazqd1o+UY4zgzU+avtMbDP+ldA==}
+  /define-properties@1.2.1:
+    resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==}
     engines: {node: '>= 0.4'}
     dependencies:
+      define-data-property: 1.1.0
       has-property-descriptors: 1.0.0
       object-keys: 1.1.1
     dev: true
@@ -7549,10 +7549,6 @@ packages:
     resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==}
     engines: {node: '>=6'}
 
-  /destr@2.0.0:
-    resolution: {integrity: sha512-FJ9RDpf3GicEBvzI3jxc2XhHzbqD8p4ANw/1kPsFBfTvP1b7Gn/Lg1vO7R9J4IVgoMbyUmFrFGZafJ1hPZpvlg==}
-    dev: false
-
   /destr@2.0.1:
     resolution: {integrity: sha512-M1Ob1zPSIvlARiJUkKqvAZ3VAqQY6Jcuth/pBKQ2b1dX/Qx0OnJ8Vux6J2H5PTMQeRzWrrbTu70VxBfv/OPDJA==}
 
@@ -7585,6 +7581,12 @@ packages:
   /devalue@4.3.2:
     resolution: {integrity: sha512-KqFl6pOgOW+Y6wJgu80rHpo2/3H07vr8ntR9rkkFIRETewbf5GaYYcakYfiKz89K+sLsuPkQIZaXDMjUObZwWg==}
 
+  /devlop@1.1.0:
+    resolution: {integrity: sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==}
+    dependencies:
+      dequal: 2.0.3
+    dev: false
+
   /didyoumean@1.2.2:
     resolution: {integrity: sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==}
     dev: false
@@ -7623,6 +7625,14 @@ packages:
       esutils: 2.0.3
     dev: true
 
+  /dom-serializer@1.4.1:
+    resolution: {integrity: sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==}
+    dependencies:
+      domelementtype: 2.3.0
+      domhandler: 4.3.1
+      entities: 2.2.0
+    dev: false
+
   /dom-serializer@2.0.0:
     resolution: {integrity: sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==}
     dependencies:
@@ -7635,6 +7645,13 @@ packages:
     resolution: {integrity: sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==}
     dev: false
 
+  /domhandler@4.3.1:
+    resolution: {integrity: sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==}
+    engines: {node: '>= 4'}
+    dependencies:
+      domelementtype: 2.3.0
+    dev: false
+
   /domhandler@5.0.3:
     resolution: {integrity: sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==}
     engines: {node: '>= 4'}
@@ -7646,6 +7663,14 @@ packages:
     resolution: {integrity: sha512-F9e6wPGtY+8KNMRAVfxeCOHU0/NPWMSENNq4pQctuXRqqdEPW7q3CrLbR5Nse044WwacyjHGOMlvNsBe1y6z9A==}
     dev: false
 
+  /domutils@2.8.0:
+    resolution: {integrity: sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==}
+    dependencies:
+      dom-serializer: 1.4.1
+      domelementtype: 2.3.0
+      domhandler: 4.3.1
+    dev: false
+
   /domutils@3.1.0:
     resolution: {integrity: sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==}
     dependencies:
@@ -7659,7 +7684,7 @@ packages:
     hasBin: true
     dependencies:
       cross-spawn: 7.0.3
-      dotenv: 16.1.4
+      dotenv: 16.3.1
       dotenv-expand: 10.0.0
       minimist: 1.2.8
     dev: false
@@ -7674,8 +7699,8 @@ packages:
     engines: {node: '>=12'}
     dev: false
 
-  /dotenv@16.1.4:
-    resolution: {integrity: sha512-m55RtE8AsPeJBpOIFKihEmqUcoVncQIwo7x9U8ZwLEZw9ZpXboz2c+rvog+jUaJvVrZ5kBOeYQBX5+8Aa/OZQw==}
+  /dotenv@16.3.1:
+    resolution: {integrity: sha512-IPzF4w4/Rd94bA9imS68tZBaYyBWSCE47V1RGuMrB94iyTOIEwRmVL2x/4An+6mETpLrKJ5hQkB8W4kFAadeIQ==}
     engines: {node: '>=12'}
     dev: false
 
@@ -7716,11 +7741,11 @@ packages:
     resolution: {integrity: sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=}
     dev: true
 
-  /electron-to-chromium@1.4.510:
-    resolution: {integrity: sha512-xPfLIPFcN/WLXBpQ/K4UgE98oUBO5Tia6BD4rkSR0wE7ep/PwBVlgvPJQrIBpmJGVAmUzwPKuDbVt9XV6+uC2g==}
+  /electron-to-chromium@1.4.544:
+    resolution: {integrity: sha512-54z7squS1FyFRSUqq/knOFSptjjogLZXbKcYk3B0qkE1KZzvqASwRZnY2KzZQJqIYLVD38XZeoiMRflYSwyO4w==}
 
-  /emmet@2.4.4:
-    resolution: {integrity: sha512-v8Mwpjym55CS3EjJgiCLWUB3J2HSR93jhzXW325720u8KvYxdI2voYLstW3pHBxFz54H6jFjayR9G4LfTG0q+g==}
+  /emmet@2.4.6:
+    resolution: {integrity: sha512-dJfbdY/hfeTyf/Ef7Y7ubLYzkBvPQ912wPaeVYpAxvFxkEBf/+hJu4H6vhAvFN6HlxqedlfVn2x1S44FfQ97pg==}
     dependencies:
       '@emmetio/abbreviation': 2.3.3
       '@emmetio/css-abbreviation': 2.1.8
@@ -7744,6 +7769,10 @@ packages:
     dependencies:
       once: 1.4.0
 
+  /entities@2.2.0:
+    resolution: {integrity: sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==}
+    dev: false
+
   /entities@3.0.1:
     resolution: {integrity: sha512-WiyBqoomrwMdFG1e0kqvASYfnlb0lp8M5o5Fw2OFq1hNZxxcNk8Ik0Xm7LxzBhuidnZB/UtBqVCgUz3kBOP51Q==}
     engines: {node: '>=0.12'}
@@ -7758,7 +7787,7 @@ packages:
     resolution: {integrity: sha512-36/6cZ+zIbcPA2ANrzp7vTz2bS8/zdZaq2RPFqJVtCGJ4P55EakgJ1BeKP8RMvEmM7ndrnHdJXzL3J1dHrEm1w==}
     dependencies:
       ajv: 8.12.0
-      dotenv: 16.1.4
+      dotenv: 16.3.1
       dotenv-expand: 9.0.0
     dev: false
 
@@ -7767,21 +7796,22 @@ packages:
     dependencies:
       is-arrayish: 0.2.1
 
-  /es-abstract@1.21.2:
-    resolution: {integrity: sha512-y/B5POM2iBnIxCiernH1G7rC9qQoM77lLIMQLuob0zhp8C56Po81+2Nj0WFKnd0pNReDTnkYryc+zhOzpEIROg==}
+  /es-abstract@1.22.2:
+    resolution: {integrity: sha512-YoxfFcDmhjOgWPWsV13+2RNjq1F6UQnfs+8TftwNqtzlmFzEXvlUwdrNrYeaizfjQzRMxkZ6ElWMOJIFKdVqwA==}
     engines: {node: '>= 0.4'}
     dependencies:
       array-buffer-byte-length: 1.0.0
+      arraybuffer.prototype.slice: 1.0.2
       available-typed-arrays: 1.0.5
       call-bind: 1.0.2
       es-set-tostringtag: 2.0.1
       es-to-primitive: 1.2.1
-      function.prototype.name: 1.1.5
+      function.prototype.name: 1.1.6
       get-intrinsic: 1.2.1
       get-symbol-description: 1.0.0
       globalthis: 1.0.3
       gopd: 1.0.1
-      has: 1.0.3
+      has: 1.0.4
       has-property-descriptors: 1.0.0
       has-proto: 1.0.1
       has-symbols: 1.0.3
@@ -7792,37 +7822,41 @@ packages:
       is-regex: 1.1.4
       is-shared-array-buffer: 1.0.2
       is-string: 1.0.7
-      is-typed-array: 1.1.10
+      is-typed-array: 1.1.12
       is-weakref: 1.0.2
       object-inspect: 1.12.3
       object-keys: 1.1.1
       object.assign: 4.1.4
-      regexp.prototype.flags: 1.5.0
+      regexp.prototype.flags: 1.5.1
+      safe-array-concat: 1.0.1
       safe-regex-test: 1.0.0
-      string.prototype.trim: 1.2.7
-      string.prototype.trimend: 1.0.6
-      string.prototype.trimstart: 1.0.6
+      string.prototype.trim: 1.2.8
+      string.prototype.trimend: 1.0.7
+      string.prototype.trimstart: 1.0.7
+      typed-array-buffer: 1.0.0
+      typed-array-byte-length: 1.0.0
+      typed-array-byte-offset: 1.0.0
       typed-array-length: 1.0.4
       unbox-primitive: 1.0.2
-      which-typed-array: 1.1.9
+      which-typed-array: 1.1.11
     dev: true
 
-  /es-module-lexer@1.3.0:
-    resolution: {integrity: sha512-vZK7T0N2CBmBOixhmjdqx2gWVbFZ4DXZ/NyRMZVlJXPa7CyFS+/a4QQsDGDQy9ZfEzxFuNEsMLeQJnKP2p5/JA==}
+  /es-module-lexer@1.3.1:
+    resolution: {integrity: sha512-JUFAyicQV9mXc3YRxPnDlrfBKpqt6hUYzz9/boprUJHs4e4KVr3XwOF70doO6gwXUor6EWZJAyWAfKki84t20Q==}
 
   /es-set-tostringtag@2.0.1:
     resolution: {integrity: sha512-g3OMbtlwY3QewlqAiMLI47KywjWZoEytKr8pf6iTC8uJq5bIAH52Z9pnQ8pVL6whrCto53JZDuUIsifGeLorTg==}
     engines: {node: '>= 0.4'}
     dependencies:
       get-intrinsic: 1.2.1
-      has: 1.0.3
+      has: 1.0.4
       has-tostringtag: 1.0.0
     dev: true
 
   /es-shim-unscopables@1.0.0:
     resolution: {integrity: sha512-Jm6GPcCdC30eMLbZ2x8z2WuRwAws3zTBBKuusffYVUrNj/GVSUAZ+xKMaUpfNDR5IbyNA5LJbaecoUVbmUcB1w==}
     dependencies:
-      has: 1.0.3
+      has: 1.0.4
     dev: true
 
   /es-to-primitive@1.2.1:
@@ -8132,34 +8166,34 @@ packages:
       '@esbuild/win32-ia32': 0.18.16
       '@esbuild/win32-x64': 0.18.16
 
-  /esbuild@0.19.3:
-    resolution: {integrity: sha512-UlJ1qUUA2jL2nNib1JTSkifQTcYTroFqRjwCFW4QYEKEsixXD5Tik9xML7zh2gTxkYTBKGHNH9y7txMwVyPbjw==}
+  /esbuild@0.19.4:
+    resolution: {integrity: sha512-x7jL0tbRRpv4QUyuDMjONtWFciygUxWaUM1kMX2zWxI0X2YWOt7MSA0g4UdeSiHM8fcYVzpQhKYOycZwxTdZkA==}
     engines: {node: '>=12'}
     hasBin: true
     requiresBuild: true
     optionalDependencies:
-      '@esbuild/android-arm': 0.19.3
-      '@esbuild/android-arm64': 0.19.3
-      '@esbuild/android-x64': 0.19.3
-      '@esbuild/darwin-arm64': 0.19.3
-      '@esbuild/darwin-x64': 0.19.3
-      '@esbuild/freebsd-arm64': 0.19.3
-      '@esbuild/freebsd-x64': 0.19.3
-      '@esbuild/linux-arm': 0.19.3
-      '@esbuild/linux-arm64': 0.19.3
-      '@esbuild/linux-ia32': 0.19.3
-      '@esbuild/linux-loong64': 0.19.3
-      '@esbuild/linux-mips64el': 0.19.3
-      '@esbuild/linux-ppc64': 0.19.3
-      '@esbuild/linux-riscv64': 0.19.3
-      '@esbuild/linux-s390x': 0.19.3
-      '@esbuild/linux-x64': 0.19.3
-      '@esbuild/netbsd-x64': 0.19.3
-      '@esbuild/openbsd-x64': 0.19.3
-      '@esbuild/sunos-x64': 0.19.3
-      '@esbuild/win32-arm64': 0.19.3
-      '@esbuild/win32-ia32': 0.19.3
-      '@esbuild/win32-x64': 0.19.3
+      '@esbuild/android-arm': 0.19.4
+      '@esbuild/android-arm64': 0.19.4
+      '@esbuild/android-x64': 0.19.4
+      '@esbuild/darwin-arm64': 0.19.4
+      '@esbuild/darwin-x64': 0.19.4
+      '@esbuild/freebsd-arm64': 0.19.4
+      '@esbuild/freebsd-x64': 0.19.4
+      '@esbuild/linux-arm': 0.19.4
+      '@esbuild/linux-arm64': 0.19.4
+      '@esbuild/linux-ia32': 0.19.4
+      '@esbuild/linux-loong64': 0.19.4
+      '@esbuild/linux-mips64el': 0.19.4
+      '@esbuild/linux-ppc64': 0.19.4
+      '@esbuild/linux-riscv64': 0.19.4
+      '@esbuild/linux-s390x': 0.19.4
+      '@esbuild/linux-x64': 0.19.4
+      '@esbuild/netbsd-x64': 0.19.4
+      '@esbuild/openbsd-x64': 0.19.4
+      '@esbuild/sunos-x64': 0.19.4
+      '@esbuild/win32-arm64': 0.19.4
+      '@esbuild/win32-ia32': 0.19.4
+      '@esbuild/win32-x64': 0.19.4
 
   /escalade@3.1.1:
     resolution: {integrity: sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==}
@@ -8207,15 +8241,15 @@ packages:
       eslint: 8.45.0
     dev: true
 
-  /eslint-config-xtrict@3.0.1(eslint@8.45.0)(prettier@3.0.2)(typescript@5.1.6):
+  /eslint-config-xtrict@3.0.1(eslint@8.45.0)(prettier@3.0.2)(typescript@5.2.2):
     resolution: {integrity: sha512-5njDMQ1R2s9ghMYpk2Ox84bfd8Umly3yVs4DL5XjgR0XonD/s4Yw1nawqWhr7hZzSUXKcmRvPuOx0eJVX+7t7w==}
     engines: {node: '>=10'}
     peerDependencies:
       eslint: ^6.8.0
       typescript: ^3.8.3
     dependencies:
-      '@typescript-eslint/eslint-plugin': 3.10.1(@typescript-eslint/parser@3.10.1)(eslint@8.45.0)(typescript@5.1.6)
-      '@typescript-eslint/parser': 3.10.1(eslint@8.45.0)(typescript@5.1.6)
+      '@typescript-eslint/eslint-plugin': 3.10.1(@typescript-eslint/parser@3.10.1)(eslint@8.45.0)(typescript@5.2.2)
+      '@typescript-eslint/parser': 3.10.1(eslint@8.45.0)(typescript@5.2.2)
       eslint: 8.45.0
       eslint-config-prettier: 6.15.0(eslint@8.45.0)
       eslint-plugin-import: 2.27.5(@typescript-eslint/parser@3.10.1)(eslint@8.45.0)
@@ -8223,7 +8257,7 @@ packages:
       eslint-plugin-prettier: 3.4.1(eslint-config-prettier@6.15.0)(eslint@8.45.0)(prettier@3.0.2)
       eslint-plugin-sonarjs: 0.5.0(eslint@8.45.0)
       eslint-plugin-unicorn: 21.0.0(eslint@8.45.0)
-      typescript: 5.1.6
+      typescript: 5.2.2
     transitivePeerDependencies:
       - eslint-import-resolver-typescript
       - eslint-import-resolver-webpack
@@ -8231,17 +8265,17 @@ packages:
       - supports-color
     dev: true
 
-  /eslint-import-resolver-node@0.3.7:
-    resolution: {integrity: sha512-gozW2blMLJCeFpBwugLTGyvVjNoeo1knonXAcatC6bjPBZitotxdWf7Gimr25N4c0AAOo4eOUfaG82IJPDpqCA==}
+  /eslint-import-resolver-node@0.3.9:
+    resolution: {integrity: sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==}
     dependencies:
       debug: 3.2.7
-      is-core-module: 2.12.1
-      resolve: 1.22.2
+      is-core-module: 2.13.0
+      resolve: 1.22.6
     transitivePeerDependencies:
       - supports-color
     dev: true
 
-  /eslint-module-utils@2.8.0(@typescript-eslint/parser@3.10.1)(eslint-import-resolver-node@0.3.7)(eslint@8.45.0):
+  /eslint-module-utils@2.8.0(@typescript-eslint/parser@3.10.1)(eslint-import-resolver-node@0.3.9)(eslint@8.45.0):
     resolution: {integrity: sha512-aWajIYfsqCKRDgUfjEXNN/JlrzauMuSEy5sbd7WXbtW3EH6A6MpwEh42c7qD+MqQo9QMJ6fWLAeIJynx0g6OAw==}
     engines: {node: '>=4'}
     peerDependencies:
@@ -8262,15 +8296,15 @@ packages:
       eslint-import-resolver-webpack:
         optional: true
     dependencies:
-      '@typescript-eslint/parser': 3.10.1(eslint@8.45.0)(typescript@5.1.6)
+      '@typescript-eslint/parser': 3.10.1(eslint@8.45.0)(typescript@5.2.2)
       debug: 3.2.7
       eslint: 8.45.0
-      eslint-import-resolver-node: 0.3.7
+      eslint-import-resolver-node: 0.3.9
     transitivePeerDependencies:
       - supports-color
     dev: true
 
-  /eslint-module-utils@2.8.0(@typescript-eslint/parser@6.2.0)(eslint-import-resolver-node@0.3.7)(eslint@8.45.0):
+  /eslint-module-utils@2.8.0(@typescript-eslint/parser@6.2.0)(eslint-import-resolver-node@0.3.9)(eslint@8.45.0):
     resolution: {integrity: sha512-aWajIYfsqCKRDgUfjEXNN/JlrzauMuSEy5sbd7WXbtW3EH6A6MpwEh42c7qD+MqQo9QMJ6fWLAeIJynx0g6OAw==}
     engines: {node: '>=4'}
     peerDependencies:
@@ -8291,10 +8325,10 @@ packages:
       eslint-import-resolver-webpack:
         optional: true
     dependencies:
-      '@typescript-eslint/parser': 6.2.0(eslint@8.45.0)(typescript@5.1.6)
+      '@typescript-eslint/parser': 6.2.0(eslint@8.45.0)(typescript@5.2.2)
       debug: 3.2.7
       eslint: 8.45.0
-      eslint-import-resolver-node: 0.3.7
+      eslint-import-resolver-node: 0.3.9
     transitivePeerDependencies:
       - supports-color
     dev: true
@@ -8309,22 +8343,22 @@ packages:
       '@typescript-eslint/parser':
         optional: true
     dependencies:
-      '@typescript-eslint/parser': 3.10.1(eslint@8.45.0)(typescript@5.1.6)
-      array-includes: 3.1.6
-      array.prototype.flat: 1.3.1
-      array.prototype.flatmap: 1.3.1
+      '@typescript-eslint/parser': 3.10.1(eslint@8.45.0)(typescript@5.2.2)
+      array-includes: 3.1.7
+      array.prototype.flat: 1.3.2
+      array.prototype.flatmap: 1.3.2
       debug: 3.2.7
       doctrine: 2.1.0
       eslint: 8.45.0
-      eslint-import-resolver-node: 0.3.7
-      eslint-module-utils: 2.8.0(@typescript-eslint/parser@3.10.1)(eslint-import-resolver-node@0.3.7)(eslint@8.45.0)
-      has: 1.0.3
-      is-core-module: 2.12.1
+      eslint-import-resolver-node: 0.3.9
+      eslint-module-utils: 2.8.0(@typescript-eslint/parser@3.10.1)(eslint-import-resolver-node@0.3.9)(eslint@8.45.0)
+      has: 1.0.4
+      is-core-module: 2.13.0
       is-glob: 4.0.3
       minimatch: 3.1.2
-      object.values: 1.1.6
-      resolve: 1.22.2
-      semver: 6.3.0
+      object.values: 1.1.7
+      resolve: 1.22.6
+      semver: 6.3.1
       tsconfig-paths: 3.14.2
     transitivePeerDependencies:
       - eslint-import-resolver-typescript
@@ -8342,22 +8376,22 @@ packages:
       '@typescript-eslint/parser':
         optional: true
     dependencies:
-      '@typescript-eslint/parser': 6.2.0(eslint@8.45.0)(typescript@5.1.6)
-      array-includes: 3.1.6
-      array.prototype.flat: 1.3.1
-      array.prototype.flatmap: 1.3.1
+      '@typescript-eslint/parser': 6.2.0(eslint@8.45.0)(typescript@5.2.2)
+      array-includes: 3.1.7
+      array.prototype.flat: 1.3.2
+      array.prototype.flatmap: 1.3.2
       debug: 3.2.7
       doctrine: 2.1.0
       eslint: 8.45.0
-      eslint-import-resolver-node: 0.3.7
-      eslint-module-utils: 2.8.0(@typescript-eslint/parser@6.2.0)(eslint-import-resolver-node@0.3.7)(eslint@8.45.0)
-      has: 1.0.3
-      is-core-module: 2.12.1
+      eslint-import-resolver-node: 0.3.9
+      eslint-module-utils: 2.8.0(@typescript-eslint/parser@6.2.0)(eslint-import-resolver-node@0.3.9)(eslint@8.45.0)
+      has: 1.0.4
+      is-core-module: 2.13.0
       is-glob: 4.0.3
       minimatch: 3.1.2
-      object.values: 1.1.6
-      resolve: 1.22.2
-      semver: 6.3.0
+      object.values: 1.1.7
+      resolve: 1.22.6
+      semver: 6.3.1
       tsconfig-paths: 3.14.2
     transitivePeerDependencies:
       - eslint-import-resolver-typescript
@@ -8400,16 +8434,16 @@ packages:
       prettier-linter-helpers: 1.0.0
     dev: true
 
-  /eslint-plugin-solid@0.12.1(eslint@8.45.0)(typescript@5.1.6):
+  /eslint-plugin-solid@0.12.1(eslint@8.45.0)(typescript@5.2.2):
     resolution: {integrity: sha512-fM0sEg9PcS1mcNbWklwc+W/lOv1/XyEwXf53HmFFy4GOA8E3u41h8JW+hc+Vv1m3kh01umKoTalOTET08zKdAQ==}
     engines: {node: '>=12.0.0'}
     peerDependencies:
       eslint: ^6.0.0 || ^7.0.0 || ^8.0.0
     dependencies:
-      '@typescript-eslint/utils': 5.59.11(eslint@8.45.0)(typescript@5.1.6)
+      '@typescript-eslint/utils': 5.62.0(eslint@8.45.0)(typescript@5.2.2)
       eslint: 8.45.0
       is-html: 2.0.0
-      jsx-ast-utils: 3.3.3
+      jsx-ast-utils: 3.3.5
       kebab-case: 1.0.2
       known-css-properties: 0.24.0
       style-to-object: 0.3.0
@@ -8459,8 +8493,8 @@ packages:
       estraverse: 4.3.0
     dev: true
 
-  /eslint-scope@7.2.0:
-    resolution: {integrity: sha512-DYj5deGlHBfMt15J7rdtyKNq/Nqlv5KfU4iodrQ019XESsRnwXH9KAE0y3cwtUHDo2ob7CypAnCqefh6vioWRw==}
+  /eslint-scope@7.2.2:
+    resolution: {integrity: sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==}
     engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
     dependencies:
       esrecurse: 4.3.0
@@ -8472,8 +8506,8 @@ packages:
     peerDependencies:
       eslint: '>=7.0.0'
     dependencies:
-      '@babel/core': 7.22.5
-      '@babel/eslint-parser': 7.22.5(@babel/core@7.22.5)(eslint@8.45.0)
+      '@babel/core': 7.23.0
+      '@babel/eslint-parser': 7.22.15(@babel/core@7.23.0)(eslint@8.45.0)
       eslint: 8.45.0
       eslint-visitor-keys: 2.1.0
       esquery: 1.5.0
@@ -8499,8 +8533,8 @@ packages:
     engines: {node: '>=10'}
     dev: true
 
-  /eslint-visitor-keys@3.4.1:
-    resolution: {integrity: sha512-pZnmmLwYzf+kWaM/Qgrvpen51upAktaaiI01nsJD/Yr3lMOdNtq0cxkrrg16w64VtisN6okbs7Q8AfGqj4c9fA==}
+  /eslint-visitor-keys@3.4.3:
+    resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==}
     engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
     dev: true
 
@@ -8510,10 +8544,10 @@ packages:
     hasBin: true
     dependencies:
       '@eslint-community/eslint-utils': 4.4.0(eslint@8.45.0)
-      '@eslint-community/regexpp': 4.6.1
-      '@eslint/eslintrc': 2.1.0
+      '@eslint-community/regexpp': 4.9.1
+      '@eslint/eslintrc': 2.1.2
       '@eslint/js': 8.44.0
-      '@humanwhocodes/config-array': 0.11.10
+      '@humanwhocodes/config-array': 0.11.11
       '@humanwhocodes/module-importer': 1.0.1
       '@nodelib/fs.walk': 1.2.8
       ajv: 6.12.6
@@ -8522,8 +8556,8 @@ packages:
       debug: 4.3.4
       doctrine: 3.0.0
       escape-string-regexp: 4.0.0
-      eslint-scope: 7.2.0
-      eslint-visitor-keys: 3.4.1
+      eslint-scope: 7.2.2
+      eslint-visitor-keys: 3.4.3
       espree: 9.6.1
       esquery: 1.5.0
       esutils: 2.0.3
@@ -8531,7 +8565,7 @@ packages:
       file-entry-cache: 6.0.1
       find-up: 5.0.0
       glob-parent: 6.0.2
-      globals: 13.20.0
+      globals: 13.23.0
       graphemer: 1.4.0
       ignore: 5.2.4
       imurmurhash: 0.1.4
@@ -8556,7 +8590,7 @@ packages:
     dependencies:
       acorn: 8.10.0
       acorn-jsx: 5.3.2(acorn@8.10.0)
-      eslint-visitor-keys: 3.4.1
+      eslint-visitor-keys: 3.4.3
     dev: true
 
   /esprima@4.0.1:
@@ -8588,6 +8622,39 @@ packages:
     engines: {node: '>=4.0'}
     dev: true
 
+  /estree-util-attach-comments@2.1.1:
+    resolution: {integrity: sha512-+5Ba/xGGS6mnwFbXIuQiDPTbuTxuMCooq3arVv7gPZtYpjp+VXH/NkHAP35OOefPhNG/UGqU3vt/LTABwcHX0w==}
+    dependencies:
+      '@types/estree': 1.0.2
+    dev: false
+
+  /estree-util-build-jsx@2.2.2:
+    resolution: {integrity: sha512-m56vOXcOBuaF+Igpb9OPAy7f9w9OIkb5yhjsZuaPm7HoGi4oTOQi0h2+yZ+AtKklYFZ+rPC4n0wYCJCEU1ONqg==}
+    dependencies:
+      '@types/estree-jsx': 1.0.1
+      estree-util-is-identifier-name: 2.1.0
+      estree-walker: 3.0.3
+    dev: false
+
+  /estree-util-is-identifier-name@2.1.0:
+    resolution: {integrity: sha512-bEN9VHRyXAUOjkKVQVvArFym08BTWB0aJPppZZr0UNyAqWsLaVfAqP7hbaTJjzHifmB5ebnR8Wm7r7yGN/HonQ==}
+    dev: false
+
+  /estree-util-to-js@1.2.0:
+    resolution: {integrity: sha512-IzU74r1PK5IMMGZXUVZbmiu4A1uhiPgW5hm1GjcOfr4ZzHaMPpLNJjR7HjXiIOzi25nZDrgFTobHTkV5Q6ITjA==}
+    dependencies:
+      '@types/estree-jsx': 1.0.1
+      astring: 1.8.6
+      source-map: 0.7.4
+    dev: false
+
+  /estree-util-visit@1.2.1:
+    resolution: {integrity: sha512-xbgqcrkIVbIG+lI/gzbvd9SGTJL4zqJKBFttUl5pP27KhAjtMKbX/mQXJ7qgyXpMgVy/zvpm0xoQQaGL8OloOw==}
+    dependencies:
+      '@types/estree-jsx': 1.0.1
+      '@types/unist': 2.0.8
+    dev: false
+
   /estree-walker@2.0.2:
     resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==}
 
@@ -8597,7 +8664,7 @@ packages:
   /estree-walker@3.0.3:
     resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==}
     dependencies:
-      '@types/estree': 1.0.1
+      '@types/estree': 1.0.2
 
   /esutils@2.0.3:
     resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==}
@@ -8655,8 +8722,8 @@ packages:
       signal-exit: 3.0.7
       strip-final-newline: 3.0.0
 
-  /execa@7.1.1:
-    resolution: {integrity: sha512-wH0eMf/UXckdUYnO21+HDztteVv05rq2GXksxT4fCGeHkBhw1DROXh40wcjMcRqDOWE7iPJ4n3M7e2+YFP+76Q==}
+  /execa@7.2.0:
+    resolution: {integrity: sha512-UduyVP7TLB5IcAQl+OzLyLcS/l32W/GLg+AhHJ+ow40FOk2U3SAllPwR44v4vmdFwIWqpdwxxpQbF1n5ta9seA==}
     engines: {node: ^14.18.0 || ^16.14.0 || >=18.0.0}
     dependencies:
       cross-spawn: 7.0.3
@@ -8701,8 +8768,8 @@ packages:
     engines: {node: ^10.17.0 || ^12.0.0 || >= 13.7.0}
     dev: false
 
-  /fast-content-type-parse@1.0.0:
-    resolution: {integrity: sha512-Xbc4XcysUXcsP5aHUU7Nq3OwvHq97C+WnbkeIefpeYLX+ryzFJlU6OStFJhs6Ol0LkUGpcK+wL0JwfM+FCU5IA==}
+  /fast-content-type-parse@1.1.0:
+    resolution: {integrity: sha512-fBHHqSTFLVnR61C+gltJuE5GkVQMV0S2nqUO8TJ+5Z3qAKG8vAx4FKai1s5jq/inV1+sREynIWSuQ6HgoSXpDQ==}
     dev: false
 
   /fast-decode-uri-component@1.0.1:
@@ -8741,8 +8808,8 @@ packages:
     resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==}
     dev: true
 
-  /fast-json-stringify@5.7.0:
-    resolution: {integrity: sha512-sBVPTgnAZseLu1Qgj6lUbQ0HfjFhZWXAmpZ5AaSGkyLh5gAXBga/uPJjQPHpDFjC9adWIpdOcCLSDTgrZ7snoQ==}
+  /fast-json-stringify@5.8.0:
+    resolution: {integrity: sha512-VVwK8CFMSALIvt14U8AvrSzQAwN/0vaVRiFFUVlpnXSnDGrSkOAO5MtzyN8oQNjLd5AqTW5OZRgyjoNuAuR3jQ==}
     dependencies:
       '@fastify/deepmerge': 1.3.0
       ajv: 8.12.0
@@ -8752,10 +8819,11 @@ packages:
       rfdc: 1.3.0
     dev: false
 
-  /fast-jwt@3.1.1:
-    resolution: {integrity: sha512-c6gqmiMU9kUIMs0XcsnnpBMA4A+zi/XULA47r6hYoLR7s1teJ+LwviwZdttCeTZ+F5ZuHlRigNe98C4qN6h4pw==}
-    engines: {node: '>=14 <22'}
+  /fast-jwt@3.3.1:
+    resolution: {integrity: sha512-1YuuIJeh1hEvfcYDe89P2oGACWI5hd2GadRDKHalSxkc1Z0z8I6yzuVK6SF15sW09QZngTV6d7g4+TFL9bvs5A==}
+    engines: {node: '>=16 <22'}
     dependencies:
+      '@lukeed/ms': 2.0.1
       asn1.js: 5.4.1
       ecdsa-sig-formatter: 1.0.11
       mnemonist: 0.39.5
@@ -8771,8 +8839,8 @@ packages:
       fast-decode-uri-component: 1.0.1
     dev: false
 
-  /fast-redact@3.2.0:
-    resolution: {integrity: sha512-zaTadChr+NekyzallAMXATXLOR8MNx3zqpZ0MUF2aGf4EathnG0f32VLODNlY8IuGY3HoRO2L6/6fSzNsLaHIw==}
+  /fast-redact@3.3.0:
+    resolution: {integrity: sha512-6T5V1QK1u4oF+ATxs1lWUmlEk6P2T9HqJG3e2DnHOdVgZy2rFJBoEnrIedcTXlkAHU/zKC+7KETJ+KGGKwxgMQ==}
     engines: {node: '>=6'}
     dev: false
 
@@ -8794,29 +8862,29 @@ packages:
       reusify: 1.0.4
     dev: false
 
-  /fastify-plugin@4.5.0:
-    resolution: {integrity: sha512-79ak0JxddO0utAXAQ5ccKhvs6vX2MGyHHMMsmZkBANrq3hXc1CHzvNPHOcvTsVMEPl5I+NT+RO4YKMGehOfSIg==}
+  /fastify-plugin@4.5.1:
+    resolution: {integrity: sha512-stRHYGeuqpEZTL1Ef0Ovr2ltazUT9g844X5z/zEBFLG8RYlpDiOCIG+ATvYEp+/zmc7sN29mcIMp8gvYplYPIQ==}
     dev: false
 
   /fastify@4.20.0:
     resolution: {integrity: sha512-zWWi5KGAb1YZ6fyrnFnA1CA1EZHkGM6YuELgB3QpS3l4lLRy14W1cc16b4KGPH/zQ98WCSdS+T41JkHY3eq1oA==}
     dependencies:
       '@fastify/ajv-compiler': 3.5.0
-      '@fastify/error': 3.2.1
+      '@fastify/error': 3.4.0
       '@fastify/fast-json-stringify-compiler': 4.3.0
       abstract-logging: 2.0.1
       avvio: 8.2.1
-      fast-content-type-parse: 1.0.0
-      fast-json-stringify: 5.7.0
+      fast-content-type-parse: 1.1.0
+      fast-json-stringify: 5.8.0
       find-my-way: 7.6.2
-      light-my-request: 5.10.0
-      pino: 8.14.1
+      light-my-request: 5.11.0
+      pino: 8.15.6
       process-warning: 2.2.0
       proxy-addr: 2.0.7
       rfdc: 1.3.0
       secure-json-parse: 2.7.0
       semver: 7.5.4
-      tiny-lru: 11.0.1
+      tiny-lru: 11.2.2
     transitivePeerDependencies:
       - supports-color
     dev: false
@@ -8840,11 +8908,25 @@ packages:
       xtend: 4.0.2
     dev: false
 
+  /fault@2.0.1:
+    resolution: {integrity: sha512-WtySTkS4OKev5JtpHXnib4Gxiurzh5NCGvWrFaZ34m6JehfTUhKZvn9njTfw48t6JumVQOmrKqpmGcdwxnhqBQ==}
+    dependencies:
+      format: 0.2.2
+    dev: false
+
+  /fetch-blob@3.2.0:
+    resolution: {integrity: sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==}
+    engines: {node: ^12.20 || >= 14.13}
+    dependencies:
+      node-domexception: 1.0.0
+      web-streams-polyfill: 3.2.1
+    dev: false
+
   /file-entry-cache@6.0.1:
     resolution: {integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==}
     engines: {node: ^10.12.0 || >=12.0.0}
     dependencies:
-      flat-cache: 3.0.4
+      flat-cache: 3.1.1
     dev: true
 
   /file-type@18.5.0:
@@ -8896,20 +8978,21 @@ packages:
       micromatch: 4.0.5
       pkg-dir: 4.2.0
 
-  /flat-cache@3.0.4:
-    resolution: {integrity: sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==}
-    engines: {node: ^10.12.0 || >=12.0.0}
+  /flat-cache@3.1.1:
+    resolution: {integrity: sha512-/qM2b3LUIaIgviBQovTLvijfyOQXPtSRnRK26ksj2J7rzPIecePUIpJsZ4T02Qg+xiAEKIs5K8dsHEd+VaKa/Q==}
+    engines: {node: '>=12.0.0'}
     dependencies:
-      flatted: 3.2.7
+      flatted: 3.2.9
+      keyv: 4.5.4
       rimraf: 3.0.2
     dev: true
 
-  /flatted@3.2.7:
-    resolution: {integrity: sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==}
+  /flatted@3.2.9:
+    resolution: {integrity: sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ==}
     dev: true
 
-  /follow-redirects@1.15.2:
-    resolution: {integrity: sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==}
+  /follow-redirects@1.15.3:
+    resolution: {integrity: sha512-1VzOtuEM8pC9SFU1E+8KfTjZyMztRsgEfwQl44z8A25uy13jSzTj6dyK2Df52iV0vgHCfBwLhDWevLn95w5v6Q==}
     engines: {node: '>=4.0'}
     peerDependencies:
       debug: '*'
@@ -8929,7 +9012,7 @@ packages:
     engines: {node: '>=14'}
     dependencies:
       cross-spawn: 7.0.3
-      signal-exit: 4.0.2
+      signal-exit: 4.1.0
     dev: false
 
   /form-data-encoder@1.7.2:
@@ -8954,6 +9037,11 @@ packages:
       mime-types: 2.1.35
     dev: false
 
+  /format@0.2.2:
+    resolution: {integrity: sha512-wzsgA6WOq+09wrU1tsJ09udeR/YZRaeArL9e1wPbFg3GG2yDnC2ldKpxs4xunpFF9DgqCqOIra3bc1HWrJ37Ww==}
+    engines: {node: '>=0.4.x'}
+    dev: false
+
   /formdata-node@4.4.1:
     resolution: {integrity: sha512-0iirZp3uVDjVGt9p49aTaqjk84TrglENEDuqfdlZQ1roC9CWlPk6Avf8EEnZNcAqPonwkG35x4n3ww/1THYAeQ==}
     engines: {node: '>= 12.20'}
@@ -8962,6 +9050,13 @@ packages:
       web-streams-polyfill: 4.0.0-beta.3
     dev: false
 
+  /formdata-polyfill@4.0.10:
+    resolution: {integrity: sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==}
+    engines: {node: '>=12.20.0'}
+    dependencies:
+      fetch-blob: 3.2.0
+    dev: false
+
   /forwarded@0.2.0:
     resolution: {integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==}
     engines: {node: '>= 0.6'}
@@ -9004,8 +9099,8 @@ packages:
   /fs.realpath@1.0.0:
     resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==}
 
-  /fsevents@2.3.2:
-    resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==}
+  /fsevents@2.3.3:
+    resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==}
     engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
     os: [darwin]
     requiresBuild: true
@@ -9024,13 +9119,13 @@ packages:
   /function-bind@1.1.1:
     resolution: {integrity: sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==}
 
-  /function.prototype.name@1.1.5:
-    resolution: {integrity: sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA==}
+  /function.prototype.name@1.1.6:
+    resolution: {integrity: sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==}
     engines: {node: '>= 0.4'}
     dependencies:
       call-bind: 1.0.2
-      define-properties: 1.2.0
-      es-abstract: 1.21.2
+      define-properties: 1.2.1
+      es-abstract: 1.22.2
       functions-have-names: 1.2.3
     dev: true
 
@@ -9050,7 +9145,7 @@ packages:
     resolution: {integrity: sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw==}
     dependencies:
       function-bind: 1.1.1
-      has: 1.0.3
+      has: 1.0.4
       has-proto: 1.0.1
       has-symbols: 1.0.3
 
@@ -9102,9 +9197,9 @@ packages:
     hasBin: true
     dependencies:
       foreground-child: 3.1.1
-      jackspeak: 2.2.2
+      jackspeak: 2.3.6
       minimatch: 9.0.3
-      minipass: 6.0.2
+      minipass: 7.0.4
       path-scurry: 1.10.1
     dev: false
 
@@ -9143,8 +9238,8 @@ packages:
     resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==}
     engines: {node: '>=4'}
 
-  /globals@13.20.0:
-    resolution: {integrity: sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==}
+  /globals@13.23.0:
+    resolution: {integrity: sha512-XAmF0RjlrjY23MA51q3HltdlGxUpXPvg0GioKiD9X6HD28iMjo2dKC8Vqwm7lne4GNr78+RHTfliktR6ZH09wA==}
     engines: {node: '>=8'}
     dependencies:
       type-fest: 0.20.2
@@ -9154,7 +9249,7 @@ packages:
     resolution: {integrity: sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==}
     engines: {node: '>= 0.4'}
     dependencies:
-      define-properties: 1.2.0
+      define-properties: 1.2.1
     dev: true
 
   /globby@11.1.0:
@@ -9168,8 +9263,8 @@ packages:
       merge2: 1.4.1
       slash: 3.0.0
 
-  /globby@13.1.4:
-    resolution: {integrity: sha512-iui/IiiW+QrJ1X1hKH5qwlMQyv34wJAYwH1vrf8b9kBA4sNiif3gKsMHa+BrdnOpEudWjpotfa7LrTzB1ERS/g==}
+  /globby@13.2.2:
+    resolution: {integrity: sha512-Y1zNGV+pzQdh7H39l9zgB4PJqjRNqydvdYCDG4HFXM4XuvSaQQlEc91IU1yALL8gUTDomgBAfz3XJdmUS+oo0w==}
     engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
     dependencies:
       dir-glob: 3.0.1
@@ -9196,22 +9291,22 @@ packages:
     resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==}
     dev: true
 
-  /graphql-request@5.2.0(graphql@16.7.1):
+  /graphql-request@5.2.0(graphql@16.8.1):
     resolution: {integrity: sha512-pLhKIvnMyBERL0dtFI3medKqWOz/RhHdcgbZ+hMMIb32mEPa5MJSzS4AuXxfI4sRAu6JVVk5tvXuGfCWl9JYWQ==}
     peerDependencies:
       graphql: 14 - 16
     dependencies:
-      '@graphql-typed-document-node/core': 3.2.0(graphql@16.7.1)
+      '@graphql-typed-document-node/core': 3.2.0(graphql@16.8.1)
       cross-fetch: 3.1.8
       extract-files: 9.0.0
       form-data: 3.0.1
-      graphql: 16.7.1
+      graphql: 16.8.1
     transitivePeerDependencies:
       - encoding
     dev: false
 
-  /graphql@16.7.1:
-    resolution: {integrity: sha512-DRYR9tf+UGU0KOsMcKAlXeFfX89UiiIZ0dRU3mR0yJfu6OjZqUcp68NnFLnqQU5RexygFoDy1EW+ccOYcPfmHg==}
+  /graphql@16.8.1:
+    resolution: {integrity: sha512-59LZHPdGZVh695Ud9lRzPBVTtlX9ZCV150Er2W43ro37wVof0ctenSaskPPjN7lVTIN8mSZt8PHUNKZuNQUuxw==}
     engines: {node: ^12.22.0 || ^14.16.0 || ^16.0.0 || >=17.0.0}
     dev: false
 
@@ -9230,16 +9325,17 @@ packages:
     dependencies:
       duplexer: 0.1.2
 
-  /h3@1.7.1:
-    resolution: {integrity: sha512-A9V2NEDNHet7v1gCg7CMwerSigLi0SRbhTy7C3lGb0N4YKIpPmLDjedTUopqp4dnn7COHfqUjjaz3zbtz4QduA==}
+  /h3@1.8.2:
+    resolution: {integrity: sha512-1Ca0orJJlCaiFY68BvzQtP2lKLk46kcLAxVM8JgYbtm2cUg6IY7pjpYgWMwUvDO9QI30N5JAukOKoT8KD3Q0PQ==}
     dependencies:
       cookie-es: 1.0.0
       defu: 6.1.2
-      destr: 2.0.0
-      iron-webcrypto: 0.7.1
-      radix3: 1.0.1
-      ufo: 1.1.2
+      destr: 2.0.1
+      iron-webcrypto: 0.10.1
+      radix3: 1.1.0
+      ufo: 1.3.1
       uncrypto: 0.1.3
+      unenv: 1.7.4
     dev: false
 
   /handlebars@4.7.8:
@@ -9288,11 +9384,9 @@ packages:
       has-symbols: 1.0.3
     dev: true
 
-  /has@1.0.3:
-    resolution: {integrity: sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==}
+  /has@1.0.4:
+    resolution: {integrity: sha512-qdSAmqLF6209RFj4VVItywPMbm3vWylknmB3nvNiUIs72xAimcM8nVYxYr7ncvZq5qzk9MKIZR8ijqD/1QuYjQ==}
     engines: {node: '>= 0.4.0'}
-    dependencies:
-      function-bind: 1.1.1
 
   /hashlru@2.3.0:
     resolution: {integrity: sha512-0cMsjjIC8I+D3M44pOQdsy0OHXGLVz6Z0beRuufhKa0KfaD2wGwAev6jILzXsd3/vpnNQJmWyZtIILqM1N+n5A==}
@@ -9301,23 +9395,42 @@ packages:
   /hast-util-from-parse5@7.1.2:
     resolution: {integrity: sha512-Nz7FfPBuljzsN3tCQ4kCBKqdNhQE2l0Tn+X1ubgKBPRoiDIu1mL08Cfw4k7q71+Duyaw7DXDN+VTAp4Vh3oCOw==}
     dependencies:
-      '@types/hast': 2.3.4
-      '@types/unist': 2.0.6
+      '@types/hast': 2.3.6
+      '@types/unist': 2.0.8
       hastscript: 7.2.0
-      property-information: 6.2.0
+      property-information: 6.3.0
       vfile: 5.3.7
       vfile-location: 4.1.0
       web-namespaces: 2.0.1
 
+  /hast-util-from-parse5@8.0.1:
+    resolution: {integrity: sha512-Er/Iixbc7IEa7r/XLtuG52zoqn/b3Xng/w6aZQ0xGVxzhw5xUFxcRqdPzP6yFi/4HBYRaifaI5fQ1RH8n0ZeOQ==}
+    dependencies:
+      '@types/hast': 3.0.1
+      '@types/unist': 3.0.0
+      devlop: 1.1.0
+      hastscript: 8.0.0
+      property-information: 6.3.0
+      vfile: 6.0.1
+      vfile-location: 5.0.2
+      web-namespaces: 2.0.1
+    dev: false
+
   /hast-util-parse-selector@3.1.1:
     resolution: {integrity: sha512-jdlwBjEexy1oGz0aJ2f4GKMaVKkA9jwjr4MjAAI22E5fM/TXVZHuS5OpONtdeIkRKqAaryQ2E9xNQxijoThSZA==}
     dependencies:
-      '@types/hast': 2.3.4
+      '@types/hast': 2.3.6
+
+  /hast-util-parse-selector@4.0.0:
+    resolution: {integrity: sha512-wkQCkSYoOGCRKERFWcxMVMOcYE2K1AaNLU8DXS9arxnLOUEWbOXKXiJUNzEpqZ3JOKpnha3jkFrumEjVliDe7A==}
+    dependencies:
+      '@types/hast': 3.0.1
+    dev: false
 
   /hast-util-raw@7.2.3:
     resolution: {integrity: sha512-RujVQfVsOrxzPOPSzZFiwofMArbQke6DJjnFfceiEbFh7S05CbPt0cYN+A5YeD3pso0JQk6O1aHBnx9+Pm2uqg==}
     dependencies:
-      '@types/hast': 2.3.4
+      '@types/hast': 2.3.6
       '@types/parse5': 6.0.3
       hast-util-from-parse5: 7.1.2
       hast-util-to-parse5: 7.1.0
@@ -9329,45 +9442,130 @@ packages:
       web-namespaces: 2.0.1
       zwitch: 2.0.4
 
+  /hast-util-raw@9.0.1:
+    resolution: {integrity: sha512-5m1gmba658Q+lO5uqL5YNGQWeh1MYWZbZmWrM5lncdcuiXuo5E2HT/CIOp0rLF8ksfSwiCVJ3twlgVRyTGThGA==}
+    dependencies:
+      '@types/hast': 3.0.1
+      '@types/unist': 3.0.0
+      '@ungap/structured-clone': 1.2.0
+      hast-util-from-parse5: 8.0.1
+      hast-util-to-parse5: 8.0.0
+      html-void-elements: 3.0.0
+      mdast-util-to-hast: 13.0.2
+      parse5: 7.1.2
+      unist-util-position: 5.0.0
+      unist-util-visit: 5.0.0
+      vfile: 6.0.1
+      web-namespaces: 2.0.1
+      zwitch: 2.0.4
+    dev: false
+
+  /hast-util-to-estree@2.3.3:
+    resolution: {integrity: sha512-ihhPIUPxN0v0w6M5+IiAZZrn0LH2uZomeWwhn7uP7avZC6TE7lIiEh2yBMPr5+zi1aUCXq6VoYRgs2Bw9xmycQ==}
+    dependencies:
+      '@types/estree': 1.0.2
+      '@types/estree-jsx': 1.0.1
+      '@types/hast': 2.3.6
+      '@types/unist': 2.0.8
+      comma-separated-tokens: 2.0.3
+      estree-util-attach-comments: 2.1.1
+      estree-util-is-identifier-name: 2.1.0
+      hast-util-whitespace: 2.0.1
+      mdast-util-mdx-expression: 1.3.2
+      mdast-util-mdxjs-esm: 1.3.1
+      property-information: 6.3.0
+      space-separated-tokens: 2.0.2
+      style-to-object: 0.4.1
+      unist-util-position: 4.0.4
+      zwitch: 2.0.4
+    transitivePeerDependencies:
+      - supports-color
+    dev: false
+
   /hast-util-to-html@8.0.4:
     resolution: {integrity: sha512-4tpQTUOr9BMjtYyNlt0P50mH7xj0Ks2xpo8M943Vykljf99HW6EzulIoJP1N3eKOSScEHzyzi9dm7/cn0RfGwA==}
     dependencies:
-      '@types/hast': 2.3.4
-      '@types/unist': 2.0.6
+      '@types/hast': 2.3.6
+      '@types/unist': 2.0.8
       ccount: 2.0.1
       comma-separated-tokens: 2.0.3
       hast-util-raw: 7.2.3
       hast-util-whitespace: 2.0.1
       html-void-elements: 2.0.1
-      property-information: 6.2.0
+      property-information: 6.3.0
       space-separated-tokens: 2.0.2
       stringify-entities: 4.0.3
       zwitch: 2.0.4
 
-  /hast-util-to-parse5@7.1.0:
-    resolution: {integrity: sha512-YNRgAJkH2Jky5ySkIqFXTQiaqcAtJyVE+D5lkN6CdtOqrnkLfGYYrEcKuHOJZlp+MwjSwuD3fZuawI+sic/RBw==}
+  /hast-util-to-html@9.0.0:
+    resolution: {integrity: sha512-IVGhNgg7vANuUA2XKrT6sOIIPgaYZnmLx3l/CCOAK0PtgfoHrZwX7jCSYyFxHTrGmC6S9q8aQQekjp4JPZF+cw==}
     dependencies:
-      '@types/hast': 2.3.4
+      '@types/hast': 3.0.1
+      '@types/unist': 3.0.0
+      ccount: 2.0.1
       comma-separated-tokens: 2.0.3
-      property-information: 6.2.0
+      hast-util-raw: 9.0.1
+      hast-util-whitespace: 3.0.0
+      html-void-elements: 3.0.0
+      mdast-util-to-hast: 13.0.2
+      property-information: 6.3.0
       space-separated-tokens: 2.0.2
-      web-namespaces: 2.0.1
+      stringify-entities: 4.0.3
       zwitch: 2.0.4
+    dev: false
+
+  /hast-util-to-parse5@7.1.0:
+    resolution: {integrity: sha512-YNRgAJkH2Jky5ySkIqFXTQiaqcAtJyVE+D5lkN6CdtOqrnkLfGYYrEcKuHOJZlp+MwjSwuD3fZuawI+sic/RBw==}
+    dependencies:
+      '@types/hast': 2.3.6
+      comma-separated-tokens: 2.0.3
+      property-information: 6.3.0
+      space-separated-tokens: 2.0.2
+      web-namespaces: 2.0.1
+      zwitch: 2.0.4
+
+  /hast-util-to-parse5@8.0.0:
+    resolution: {integrity: sha512-3KKrV5ZVI8if87DVSi1vDeByYrkGzg4mEfeu4alwgmmIeARiBLKCZS2uw5Gb6nU9x9Yufyj3iudm6i7nl52PFw==}
+    dependencies:
+      '@types/hast': 3.0.1
+      comma-separated-tokens: 2.0.3
+      devlop: 1.1.0
+      property-information: 6.3.0
+      space-separated-tokens: 2.0.2
+      web-namespaces: 2.0.1
+      zwitch: 2.0.4
+    dev: false
 
   /hast-util-whitespace@2.0.1:
     resolution: {integrity: sha512-nAxA0v8+vXSBDt3AnRUNjyRIQ0rD+ntpbAp4LnPkumc5M9yUbSMa4XDU9Q6etY4f1Wp4bNgvc1yjiZtsTTrSng==}
 
+  /hast-util-whitespace@3.0.0:
+    resolution: {integrity: sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==}
+    dependencies:
+      '@types/hast': 3.0.1
+    dev: false
+
   /hastscript@7.2.0:
     resolution: {integrity: sha512-TtYPq24IldU8iKoJQqvZOuhi5CyCQRAbvDOX0x1eW6rsHSxa/1i2CCiptNTotGHJ3VoHRGmqiv6/D3q113ikkw==}
     dependencies:
-      '@types/hast': 2.3.4
+      '@types/hast': 2.3.6
       comma-separated-tokens: 2.0.3
       hast-util-parse-selector: 3.1.1
-      property-information: 6.2.0
+      property-information: 6.3.0
       space-separated-tokens: 2.0.2
 
-  /headers-polyfill@3.1.2:
-    resolution: {integrity: sha512-tWCK4biJ6hcLqTviLXVR9DTRfYGQMXEIUj3gwJ2rZ5wO/at3XtkI4g8mCvFdUF9l1KMBNCfmNAdnahm1cgavQA==}
+  /hastscript@8.0.0:
+    resolution: {integrity: sha512-dMOtzCEd3ABUeSIISmrETiKuyydk1w0pa+gE/uormcTpSYuaNJPbX1NU3JLyscSLjwAQM8bWMhhIlnCqnRvDTw==}
+    dependencies:
+      '@types/hast': 3.0.1
+      comma-separated-tokens: 2.0.3
+      hast-util-parse-selector: 4.0.0
+      property-information: 6.3.0
+      space-separated-tokens: 2.0.2
+    dev: false
+
+  /headers-polyfill@3.3.0:
+    resolution: {integrity: sha512-5e57etwBpNcDc0b6KCVWEh/Ro063OxPvzVimUdM0/tsYM/T7Hfy3kknIGj78SFTOhNd8AZY41U8mOHoO4LzmIQ==}
     dev: false
 
   /hey-listen@1.0.8:
@@ -9436,6 +9634,10 @@ packages:
   /html-void-elements@2.0.1:
     resolution: {integrity: sha512-0quDb7s97CfemeJAnW9wC0hw78MtW7NU3hqtCD75g2vFlDLt36llsYD7uB7SUzojLMP24N5IatXf7ylGXiGG9A==}
 
+  /html-void-elements@3.0.0:
+    resolution: {integrity: sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==}
+    dev: false
+
   /htmlparser2@8.0.1:
     resolution: {integrity: sha512-4lVbmc1diZC7GUJQtRQ5yBAeUCL1exyMwmForWkRLnwyzWBFxN633SALPMGYaWZvKe9j1pRZJpauvmxENSp/EA==}
     dependencies:
@@ -9509,8 +9711,8 @@ packages:
       file-type: 18.5.0
     dev: false
 
-  /immutable@4.3.0:
-    resolution: {integrity: sha512-0AOCmOip+xgJwEVTQj1EfiDDOkPmuyllDuTuEX+DDXUgapLAsBIfkg3sxCYyCEA8mQqZrrxPUGjcOQ2JS3WLkg==}
+  /immutable@4.3.4:
+    resolution: {integrity: sha512-fsXeu4J4i6WNWSikpI88v/PcVflZz+6kMhUfIwc5SY+poQRPnaf5V7qds6SUyUN3cVxEzuCab7QIoLOQ+DQ1wA==}
 
   /import-fresh@3.3.0:
     resolution: {integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==}
@@ -9566,7 +9768,7 @@ packages:
     engines: {node: '>= 0.4'}
     dependencies:
       get-intrinsic: 1.2.1
-      has: 1.0.3
+      has: 1.0.4
       side-channel: 1.0.4
     dev: true
 
@@ -9620,8 +9822,19 @@ packages:
     engines: {node: '>= 0.10'}
     dev: false
 
-  /iron-webcrypto@0.7.1:
-    resolution: {integrity: sha512-K/UmlEhPCPXEHV5hAtH5C0tI5JnFuOrv4yO/j7ODPl3HaiiHBLbOLTde+ieUaAyfCATe4LoAnclyF+hmSCOVmQ==}
+  /iron-webcrypto@0.10.1:
+    resolution: {integrity: sha512-QGOS8MRMnj/UiOa+aMIgfyHcvkhqNUsUxb1XzskENvbo+rEfp6TOwqd1KPuDzXC4OnGHcMSVxDGRoilqB8ViqA==}
+    dev: false
+
+  /is-alphabetical@2.0.1:
+    resolution: {integrity: sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ==}
+    dev: false
+
+  /is-alphanumerical@2.0.1:
+    resolution: {integrity: sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw==}
+    dependencies:
+      is-alphabetical: 2.0.1
+      is-decimal: 2.0.1
     dev: false
 
   /is-array-buffer@3.0.2:
@@ -9629,7 +9842,7 @@ packages:
     dependencies:
       call-bind: 1.0.2
       get-intrinsic: 1.2.1
-      is-typed-array: 1.1.10
+      is-typed-array: 1.1.12
     dev: true
 
   /is-arrayish@0.2.1:
@@ -9678,16 +9891,10 @@ packages:
     engines: {node: '>= 0.4'}
     dev: true
 
-  /is-core-module@2.12.1:
-    resolution: {integrity: sha512-Q4ZuBAe2FUsKtyQJoQHlvP8OvBERxO3jEmy1I7hcRXcJBGGHFh/aJBswbXuS9sgrDH2QUO8ilkwNPHvHMd8clg==}
-    dependencies:
-      has: 1.0.3
-    dev: true
-
   /is-core-module@2.13.0:
     resolution: {integrity: sha512-Z7dk6Qo8pOCp3l4tsX2C5ZVas4V+UxwQodwZhLopL91TX8UyyHEXafPcyoeeWuLrwzHcr3igO78wNLwHJHsMCQ==}
     dependencies:
-      has: 1.0.3
+      has: 1.0.4
 
   /is-date-object@1.0.5:
     resolution: {integrity: sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==}
@@ -9696,6 +9903,10 @@ packages:
       has-tostringtag: 1.0.0
     dev: true
 
+  /is-decimal@2.0.1:
+    resolution: {integrity: sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A==}
+    dev: false
+
   /is-docker@2.2.1:
     resolution: {integrity: sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==}
     engines: {node: '>=8'}
@@ -9731,6 +9942,10 @@ packages:
     dependencies:
       is-extglob: 2.1.1
 
+  /is-hexadecimal@2.0.1:
+    resolution: {integrity: sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg==}
+    dev: false
+
   /is-html@2.0.0:
     resolution: {integrity: sha512-S+OpgB5i7wzIue/YSE5hg0e5ZYfG3hhpNh9KGl6ayJ38p7ED6wxQLd1TV91xHpcTvw90KMJ9EwN3F/iNflHBVg==}
     engines: {node: '>=8'}
@@ -9798,9 +10013,15 @@ packages:
   /is-reference@1.2.1:
     resolution: {integrity: sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ==}
     dependencies:
-      '@types/estree': 1.0.1
+      '@types/estree': 1.0.2
     dev: true
 
+  /is-reference@3.0.2:
+    resolution: {integrity: sha512-v3rht/LgVcsdZa3O2Nqs+NMowLOxeOm7Ay9+/ARQ2F+qEoANRcqrjAZKGN0v8ymUetZGgkp26LTnGT7H0Qo9Pg==}
+    dependencies:
+      '@types/estree': 1.0.2
+    dev: false
+
   /is-regex@1.1.4:
     resolution: {integrity: sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==}
     engines: {node: '>= 0.4'}
@@ -9837,15 +10058,11 @@ packages:
       has-symbols: 1.0.3
     dev: true
 
-  /is-typed-array@1.1.10:
-    resolution: {integrity: sha512-PJqgEHiWZvMpaFZ3uTc8kHPM4+4ADTlDniuQL7cU/UDA0Ql7F70yGfHph3cLNe+c9toaigv+DFzTJKhc2CtO6A==}
+  /is-typed-array@1.1.12:
+    resolution: {integrity: sha512-Z14TF2JNG8Lss5/HMqt0//T9JeHXttXy5pH/DBU4vi98ozO2btxzq9MwYDZYnKwU8nRsz/+GVFVRDq3DkVuSPg==}
     engines: {node: '>= 0.4'}
     dependencies:
-      available-typed-arrays: 1.0.5
-      call-bind: 1.0.2
-      for-each: 0.3.3
-      gopd: 1.0.1
-      has-tostringtag: 1.0.0
+      which-typed-array: 1.1.11
     dev: true
 
   /is-unicode-supported@0.1.0:
@@ -9878,16 +10095,20 @@ packages:
     dependencies:
       is-docker: 2.2.1
 
-  /is-wsl@3.0.0:
-    resolution: {integrity: sha512-TQ7xXW/fTBaz/HhGSV779AC99ocpvb9qJPuPwyIea+F+Z+htcQ1wouAA0xEQaa4saVqyP8mwkoYp5efeM/4Gbg==}
+  /is-wsl@3.1.0:
+    resolution: {integrity: sha512-UcVfVfaK4Sc4m7X3dUSoHoozQGBEFeDC+zVo06t98xe8CzHSZZBekNXH+tu0NalHolcJ/QAGqS46Hef7QXBIMw==}
     engines: {node: '>=16'}
     dependencies:
-      is-docker: 3.0.0
+      is-inside-container: 1.0.0
 
   /isarray@1.0.0:
     resolution: {integrity: sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==}
     dev: false
 
+  /isarray@2.0.5:
+    resolution: {integrity: sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==}
+    dev: true
+
   /isexe@2.0.0:
     resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==}
 
@@ -9899,8 +10120,8 @@ packages:
   /isomorphic-fetch@3.0.0:
     resolution: {integrity: sha512-qvUtwJ3j6qwsF3jLxkZ72qCgjMysPzDfeV240JHiGZsANBYd+EEuu35v7dfrJ9Up0Ak07D7GGSkGhCHTqg/5wA==}
     dependencies:
-      node-fetch: 2.6.12
-      whatwg-fetch: 3.6.17
+      node-fetch: 2.7.0
+      whatwg-fetch: 3.6.19
     transitivePeerDependencies:
       - encoding
     dev: false
@@ -9908,7 +10129,7 @@ packages:
   /isomorphic-unfetch@3.1.0:
     resolution: {integrity: sha512-geDJjpoZ8N0kWexiwkX8F9NkTsXhetLPVbZFQ+JTW239QNOwvB0gniuR1Wc6f0AMTn7/mFGyXvHTifrCp/GH8Q==}
     dependencies:
-      node-fetch: 2.6.12
+      node-fetch: 2.7.0
       unfetch: 4.2.0
     transitivePeerDependencies:
       - encoding
@@ -9918,8 +10139,8 @@ packages:
     resolution: {integrity: sha512-PIeMbHqMt4DnUP3MA/Flc0HElYjMXArsw1qwJZcm9sqR8mq3l8NYizFMty0pWwE/tzIGH3EKK5+jes5mAr85yw==}
     dev: false
 
-  /jackspeak@2.2.2:
-    resolution: {integrity: sha512-mgNtVv4vUuaKA97yxUHoA3+FkuhtxkjdXEWOyB/N76fjy0FjezEt34oy3epBtvCvS+7DyKwqCFWx/oJLV5+kCg==}
+  /jackspeak@2.3.6:
+    resolution: {integrity: sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==}
     engines: {node: '>=14'}
     dependencies:
       '@isaacs/cliui': 8.0.2
@@ -9927,21 +10148,16 @@ packages:
       '@pkgjs/parseargs': 0.11.0
     dev: false
 
-  /jiti@1.18.2:
-    resolution: {integrity: sha512-QAdOptna2NYiSSpv0O/BwoHBSmz4YhpzJHyi+fnMRTXFjp7B8i/YG5Z8IfusxB1ufjcD2Sre1F3R+nX3fvy7gg==}
-    hasBin: true
-    dev: true
-
-  /jiti@1.19.3:
-    resolution: {integrity: sha512-5eEbBDQT/jF1xg6l36P+mWGGoH9Spuy0PCdSr2dtWRDGC6ph/w9ZCL4lmESW8f8F7MwT3XKescfP0wnZWAKL9w==}
+  /jiti@1.20.0:
+    resolution: {integrity: sha512-3TV69ZbrvV6U5DfQimop50jE9Dl6J8O1ja1dvBbMba/sZ3YBEQqJ2VZRoQPVnhlzjNtU1vaXRZVrVjU4qtm8yA==}
     hasBin: true
 
   /jju@1.4.0:
     resolution: {integrity: sha512-8wb9Yw966OSxApiCt0K3yNJL8pnNeIv+OEq2YMidz4FKP6nonSRoOXc80iXY4JaN2FC11B9qsNmDsm+ZOfMROA==}
     dev: false
 
-  /joi@17.9.2:
-    resolution: {integrity: sha512-Itk/r+V4Dx0V3c7RLFdRh12IOjySm2/WGPMubBT92cQvRfYZhPM2W0hZlctjj72iES8jsRCwp7S/cRmWBnJ4nw==}
+  /joi@17.11.0:
+    resolution: {integrity: sha512-NgB+lZLNoqISVy1rZocE9PZI36bL/77ie924Ri43yEvi9GUUMPeyVIr8KdFTMUlby1p0PBYMk9spIxEUQYqrJQ==}
     dependencies:
       '@hapi/hoek': 9.3.0
       '@hapi/topo': 5.1.0
@@ -9988,6 +10204,10 @@ packages:
     engines: {node: '>=4'}
     hasBin: true
 
+  /json-buffer@3.0.1:
+    resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==}
+    dev: true
+
   /json-parse-even-better-errors@2.3.1:
     resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==}
 
@@ -10045,26 +10265,34 @@ packages:
     optionalDependencies:
       graceful-fs: 4.2.11
 
-  /jsonwebtoken@9.0.1:
-    resolution: {integrity: sha512-K8wx7eJ5TPvEjuiVSkv167EVboBDv9PZdDoF7BgeQnBLVvZWW9clr2PsQHVJDTKaEIH5JBIwHujGcHp7GgI2eg==}
+  /jsonwebtoken@9.0.2:
+    resolution: {integrity: sha512-PRp66vJ865SSqOlgqS8hujT5U4AOgMfhrwYIuIhfKaoSCZcirrmASQr8CX7cUg+RMih+hgznrjp99o+W4pJLHQ==}
     engines: {node: '>=12', npm: '>=6'}
     dependencies:
       jws: 3.2.2
-      lodash: 4.17.21
+      lodash.includes: 4.3.0
+      lodash.isboolean: 3.0.3
+      lodash.isinteger: 4.0.4
+      lodash.isnumber: 3.0.3
+      lodash.isplainobject: 4.0.6
+      lodash.isstring: 4.0.1
+      lodash.once: 4.1.1
       ms: 2.1.3
       semver: 7.5.4
     dev: false
 
-  /jssha@3.3.0:
-    resolution: {integrity: sha512-w9OtT4ALL+fbbwG3gw7erAO0jvS5nfvrukGPMWIAoea359B26ALXGpzy4YJSp9yGnpUvuvOw1nSjSoHDfWSr1w==}
+  /jssha@3.3.1:
+    resolution: {integrity: sha512-VCMZj12FCFMQYcFLPRm/0lOBbLi8uM2BhXPTqw3U4YAfs4AZfiApOoBLoN8cQE60Z50m1MYMTQVCfgF/KaCVhQ==}
     dev: false
 
-  /jsx-ast-utils@3.3.3:
-    resolution: {integrity: sha512-fYQHZTZ8jSfmWZ0iyzfwiU4WDX4HpHbMCZ3gPlWYiCl3BoeOTsqKBqnTVfH2rYT7eP5c3sVbeSPHnnJOaTrWiw==}
+  /jsx-ast-utils@3.3.5:
+    resolution: {integrity: sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==}
     engines: {node: '>=4.0'}
     dependencies:
-      array-includes: 3.1.6
+      array-includes: 3.1.7
+      array.prototype.flat: 1.3.2
       object.assign: 4.1.4
+      object.values: 1.1.7
     dev: true
 
   /jwa@1.4.1:
@@ -10090,6 +10318,12 @@ packages:
     resolution: {integrity: sha512-dcEQ7GDBpCjUQA8XZeWh3oBBLLmyn8aoeIQFGL/NTVkoEOsmlnXqA4QykUm/SncolAZYGsEk/PfUhLZ7mwMM2w==}
     dev: false
 
+  /keyv@4.5.4:
+    resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==}
+    dependencies:
+      json-buffer: 3.0.1
+    dev: true
+
   /kind-of@3.2.2:
     resolution: {integrity: sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==}
     engines: {node: '>=0.10.0'}
@@ -10132,16 +10366,16 @@ packages:
     resolution: {integrity: sha512-K1B/Yr/gIU0wm68hk/yB0p/mv6xM3ShD5aci42vOwcjof8slG8Kpo3Q7+1WTv7DaRHKWRgLPqrFDt+4GtuFAtA==}
     dev: false
 
-  /lib0@0.2.78:
-    resolution: {integrity: sha512-SV2nU43/6eaYnGH3l0lg2wg1ziB/TH3sAd2E8quXPGwrqo+aX98SNT2ZKucpUr5B8A52jD7ZMjAl+r87Fa/bLQ==}
+  /lib0@0.2.86:
+    resolution: {integrity: sha512-kxigQTM4Q7NwJkEgdqQvU21qiR37twcqqLmh+/SbiGbRLfPlLVbHyY9sWp7PwXh0Xus9ELDSjsUOwcrdt5yZ4w==}
     engines: {node: '>=16'}
     hasBin: true
     dependencies:
       isomorphic.js: 0.2.5
     dev: false
 
-  /light-my-request@5.10.0:
-    resolution: {integrity: sha512-ZU2D9GmAcOUculTTdH9/zryej6n8TzT+fNGdNtm6SDp5MMMpHrJJkvAdE3c6d8d2chE9i+a//dS9CWZtisknqA==}
+  /light-my-request@5.11.0:
+    resolution: {integrity: sha512-qkFCeloXCOMpmEdZ/MV91P8AT4fjwFXWaAFz3lUeStM8RcoM1ks4J/F8r1b3r6y/H4u3ACEJ1T+Gv5bopj7oDA==}
     dependencies:
       cookie: 0.5.0
       process-warning: 2.2.0
@@ -10215,19 +10449,48 @@ packages:
     resolution: {integrity: sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==}
     dev: true
 
+  /lodash.includes@4.3.0:
+    resolution: {integrity: sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==}
+    dev: false
+
   /lodash.isarguments@3.1.0:
     resolution: {integrity: sha512-chi4NHZlZqZD18a0imDHnZPrDeBbTtVN7GXMwuGdRH9qotxAjYs3aVLKc7zNOG9eddR5Ksd8rvFEBc9SsggPpg==}
     dev: false
 
+  /lodash.isboolean@3.0.3:
+    resolution: {integrity: sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==}
+    dev: false
+
+  /lodash.isinteger@4.0.4:
+    resolution: {integrity: sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA==}
+    dev: false
+
+  /lodash.isnumber@3.0.3:
+    resolution: {integrity: sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw==}
+    dev: false
+
+  /lodash.isplainobject@4.0.6:
+    resolution: {integrity: sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==}
+    dev: false
+
+  /lodash.isstring@4.0.1:
+    resolution: {integrity: sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==}
+    dev: false
+
   /lodash.merge@4.6.2:
     resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==}
 
+  /lodash.once@4.1.1:
+    resolution: {integrity: sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==}
+    dev: false
+
   /lodash.zip@4.2.0:
     resolution: {integrity: sha512-C7IOaBBK/0gMORRBd8OETNx3kmOkgIWIPvyDpZSCTwUrpYmgZwJkjZeOD8ww4xbOUOs4/attY+pciKvadNfFbg==}
     dev: true
 
   /lodash@4.17.21:
     resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==}
+    dev: true
 
   /log-symbols@4.1.0:
     resolution: {integrity: sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==}
@@ -10254,8 +10517,8 @@ packages:
       js-tokens: 4.0.0
     dev: false
 
-  /lru-cache@10.0.0:
-    resolution: {integrity: sha512-svTf/fzsKHffP42sujkO/Rjs37BCIsQVRCeNYIm9WN8rgT7ffoUnRtZCqU+6BqcSBdv8gwJeTz8knJpgACeQMw==}
+  /lru-cache@10.0.1:
+    resolution: {integrity: sha512-IJ4uwUTi2qCccrioU6g9g/5rvvVl13bsdczUUcqbciD9iLr095yj8DQKdObriEvuNSx325N1rV1O0sJFszx75g==}
     engines: {node: 14 || >=16.14}
     dev: false
 
@@ -10270,11 +10533,6 @@ packages:
     dependencies:
       yallist: 4.0.0
 
-  /lru-cache@9.1.2:
-    resolution: {integrity: sha512-ERJq3FOzJTxBbFjZ7iDs+NiK4VI9Wz+RdrrAB8dio1oV+YvdPzUEE4QNiT2VD51DkIbCYRUUzCRkssXCHqSnKQ==}
-    engines: {node: 14 || >=16.14}
-    dev: false
-
   /magic-string@0.27.0:
     resolution: {integrity: sha512-8UnnX2PeRAPZuN12svgR9j7M1uWMovg/CEnIwIG0LFkXSJJe4PdfUGiTGl8V9bsBHFUtfVINcSyYxd7q+kx9fA==}
     engines: {node: '>=12'}
@@ -10282,15 +10540,8 @@ packages:
       '@jridgewell/sourcemap-codec': 1.4.15
     dev: true
 
-  /magic-string@0.30.1:
-    resolution: {integrity: sha512-mbVKXPmS0z0G4XqFDCTllmDQ6coZzn94aMlb0o/A4HEHJCKcanlDZwYJgwnkmgD3jyWhUgj9VsPrfd972yPffA==}
-    engines: {node: '>=12'}
-    dependencies:
-      '@jridgewell/sourcemap-codec': 1.4.15
-    dev: true
-
-  /magic-string@0.30.3:
-    resolution: {integrity: sha512-B7xGbll2fG/VjP+SWg4sX3JynwIU0mjoTc6MPpKNuIvftk6u6vqhDnk1R80b8C2GBR6ywqy+1DcKBrevBg+bmw==}
+  /magic-string@0.30.4:
+    resolution: {integrity: sha512-Q/TKtsC5BPm0kGqgBIF9oXAs/xEf2vRKiIB4wCRQTJOQIByZ1d+NnUOotvJOvNpi5RNIgVOMC3pOuaP1ZTDlVg==}
     engines: {node: '>=12'}
     dependencies:
       '@jridgewell/sourcemap-codec': 1.4.15
@@ -10299,8 +10550,13 @@ packages:
     resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==}
     dev: false
 
-  /markdown-it@13.0.1:
-    resolution: {integrity: sha512-lTlxriVoy2criHP0JKRhO2VDG9c2ypWCsT237eDiLqi09rmbKoUetyGHq2uOIRoRS//kfoJckS0eUzzkDR+k2Q==}
+  /markdown-extensions@1.1.1:
+    resolution: {integrity: sha512-WWC0ZuMzCyDHYCasEGs4IPvLyTGftYwh6wIEOULOF0HXcqZlhwRzrK0w2VUlxWA98xnvb/jszw4ZSkJ6ADpM6Q==}
+    engines: {node: '>=0.10.0'}
+    dev: false
+
+  /markdown-it@13.0.2:
+    resolution: {integrity: sha512-FtwnEuuK+2yVU7goGn/MJ0WBZMM9ZPgU9spqlFs7/A/pDIUNSOQZhUgOqYCficIuR2QaFnrt8LHqBWsbTAoI5w==}
     hasBin: true
     dependencies:
       argparse: 2.0.1
@@ -10336,30 +10592,39 @@ packages:
   /mdast-util-definitions@5.1.2:
     resolution: {integrity: sha512-8SVPMuHqlPME/z3gqVwWY4zVXn8lqKv/pAhC57FuJ40ImXyBpmO5ukh98zB2v7Blql2FiHjHv9LVztSIqjY+MA==}
     dependencies:
-      '@types/mdast': 3.0.11
-      '@types/unist': 2.0.6
+      '@types/mdast': 3.0.13
+      '@types/unist': 2.0.8
       unist-util-visit: 4.1.2
 
   /mdast-util-definitions@6.0.0:
     resolution: {integrity: sha512-scTllyX6pnYNZH/AIp/0ePz6s4cZtARxImwoPJ7kS42n+MnVsI4XbnG6d4ibehRIldYMWM2LD7ImQblVhUejVQ==}
     dependencies:
-      '@types/mdast': 4.0.0
+      '@types/mdast': 4.0.1
       '@types/unist': 3.0.0
       unist-util-visit: 5.0.0
 
   /mdast-util-find-and-replace@2.2.2:
     resolution: {integrity: sha512-MTtdFRz/eMDHXzeK6W3dO7mXUlF82Gom4y0oOgvHhh/HXZAGvIQDUvQ0SuUx+j2tv44b8xTHOm8K/9OoRFnXKw==}
     dependencies:
-      '@types/mdast': 3.0.11
+      '@types/mdast': 3.0.13
       escape-string-regexp: 5.0.0
       unist-util-is: 5.2.1
       unist-util-visit-parents: 5.1.3
 
+  /mdast-util-find-and-replace@3.0.1:
+    resolution: {integrity: sha512-SG21kZHGC3XRTSUhtofZkBzZTJNM5ecCi0SK2IMKmSXR8vO3peL+kb1O0z7Zl83jKtutG4k5Wv/W7V3/YHvzPA==}
+    dependencies:
+      '@types/mdast': 4.0.1
+      escape-string-regexp: 5.0.0
+      unist-util-is: 6.0.0
+      unist-util-visit-parents: 6.0.1
+    dev: false
+
   /mdast-util-from-markdown@1.3.1:
     resolution: {integrity: sha512-4xTO/M8c82qBcnQc1tgpNtubGUW/Y1tBQ1B0i5CtSoelOLKFYlElIr3bvgREYYO5iRqbMY1YuqZng0GVOI8Qww==}
     dependencies:
-      '@types/mdast': 3.0.11
-      '@types/unist': 2.0.6
+      '@types/mdast': 3.0.13
+      '@types/unist': 2.0.8
       decode-named-character-reference: 1.0.2
       mdast-util-to-string: 3.2.0
       micromark: 3.2.0
@@ -10373,43 +10638,130 @@ packages:
     transitivePeerDependencies:
       - supports-color
 
+  /mdast-util-from-markdown@2.0.0:
+    resolution: {integrity: sha512-n7MTOr/z+8NAX/wmhhDji8O3bRvPTV/U0oTCaZJkjhPSKTPhS3xufVhKGF8s1pJ7Ox4QgoIU7KHseh09S+9rTA==}
+    dependencies:
+      '@types/mdast': 4.0.1
+      '@types/unist': 3.0.0
+      decode-named-character-reference: 1.0.2
+      devlop: 1.1.0
+      mdast-util-to-string: 4.0.0
+      micromark: 4.0.0
+      micromark-util-decode-numeric-character-reference: 2.0.0
+      micromark-util-decode-string: 2.0.0
+      micromark-util-normalize-identifier: 2.0.0
+      micromark-util-symbol: 2.0.0
+      micromark-util-types: 2.0.0
+      unist-util-stringify-position: 4.0.0
+    transitivePeerDependencies:
+      - supports-color
+    dev: false
+
+  /mdast-util-frontmatter@2.0.1:
+    resolution: {integrity: sha512-LRqI9+wdgC25P0URIJY9vwocIzCcksduHQ9OF2joxQoyTNVduwLAFUzjoopuRJbJAReaKrNQKAZKL3uCMugWJA==}
+    dependencies:
+      '@types/mdast': 4.0.1
+      devlop: 1.1.0
+      escape-string-regexp: 5.0.0
+      mdast-util-from-markdown: 2.0.0
+      mdast-util-to-markdown: 2.1.0
+      micromark-extension-frontmatter: 2.0.0
+    transitivePeerDependencies:
+      - supports-color
+    dev: false
+
   /mdast-util-gfm-autolink-literal@1.0.3:
     resolution: {integrity: sha512-My8KJ57FYEy2W2LyNom4n3E7hKTuQk/0SES0u16tjA9Z3oFkF4RrC/hPAPgjlSpezsOvI8ObcXcElo92wn5IGA==}
     dependencies:
-      '@types/mdast': 3.0.11
+      '@types/mdast': 3.0.13
       ccount: 2.0.1
       mdast-util-find-and-replace: 2.2.2
       micromark-util-character: 1.2.0
 
+  /mdast-util-gfm-autolink-literal@2.0.0:
+    resolution: {integrity: sha512-FyzMsduZZHSc3i0Px3PQcBT4WJY/X/RCtEJKuybiC6sjPqLv7h1yqAkmILZtuxMSsUyaLUWNp71+vQH2zqp5cg==}
+    dependencies:
+      '@types/mdast': 4.0.1
+      ccount: 2.0.1
+      devlop: 1.1.0
+      mdast-util-find-and-replace: 3.0.1
+      micromark-util-character: 2.0.1
+    dev: false
+
   /mdast-util-gfm-footnote@1.0.2:
     resolution: {integrity: sha512-56D19KOGbE00uKVj3sgIykpwKL179QsVFwx/DCW0u/0+URsryacI4MAdNJl0dh+u2PSsD9FtxPFbHCzJ78qJFQ==}
     dependencies:
-      '@types/mdast': 3.0.11
+      '@types/mdast': 3.0.13
       mdast-util-to-markdown: 1.5.0
       micromark-util-normalize-identifier: 1.1.0
 
+  /mdast-util-gfm-footnote@2.0.0:
+    resolution: {integrity: sha512-5jOT2boTSVkMnQ7LTrd6n/18kqwjmuYqo7JUPe+tRCY6O7dAuTFMtTPauYYrMPpox9hlN0uOx/FL8XvEfG9/mQ==}
+    dependencies:
+      '@types/mdast': 4.0.1
+      devlop: 1.1.0
+      mdast-util-from-markdown: 2.0.0
+      mdast-util-to-markdown: 2.1.0
+      micromark-util-normalize-identifier: 2.0.0
+    transitivePeerDependencies:
+      - supports-color
+    dev: false
+
   /mdast-util-gfm-strikethrough@1.0.3:
     resolution: {integrity: sha512-DAPhYzTYrRcXdMjUtUjKvW9z/FNAMTdU0ORyMcbmkwYNbKocDpdk+PX1L1dQgOID/+vVs1uBQ7ElrBQfZ0cuiQ==}
     dependencies:
-      '@types/mdast': 3.0.11
+      '@types/mdast': 3.0.13
       mdast-util-to-markdown: 1.5.0
 
+  /mdast-util-gfm-strikethrough@2.0.0:
+    resolution: {integrity: sha512-mKKb915TF+OC5ptj5bJ7WFRPdYtuHv0yTRxK2tJvi+BDqbkiG7h7u/9SI89nRAYcmap2xHQL9D+QG/6wSrTtXg==}
+    dependencies:
+      '@types/mdast': 4.0.1
+      mdast-util-from-markdown: 2.0.0
+      mdast-util-to-markdown: 2.1.0
+    transitivePeerDependencies:
+      - supports-color
+    dev: false
+
   /mdast-util-gfm-table@1.0.7:
     resolution: {integrity: sha512-jjcpmNnQvrmN5Vx7y7lEc2iIOEytYv7rTvu+MeyAsSHTASGCCRA79Igg2uKssgOs1i1po8s3plW0sTu1wkkLGg==}
     dependencies:
-      '@types/mdast': 3.0.11
+      '@types/mdast': 3.0.13
       markdown-table: 3.0.3
       mdast-util-from-markdown: 1.3.1
       mdast-util-to-markdown: 1.5.0
     transitivePeerDependencies:
       - supports-color
 
+  /mdast-util-gfm-table@2.0.0:
+    resolution: {integrity: sha512-78UEvebzz/rJIxLvE7ZtDd/vIQ0RHv+3Mh5DR96p7cS7HsBhYIICDBCu8csTNWNO6tBWfqXPWekRuj2FNOGOZg==}
+    dependencies:
+      '@types/mdast': 4.0.1
+      devlop: 1.1.0
+      markdown-table: 3.0.3
+      mdast-util-from-markdown: 2.0.0
+      mdast-util-to-markdown: 2.1.0
+    transitivePeerDependencies:
+      - supports-color
+    dev: false
+
   /mdast-util-gfm-task-list-item@1.0.2:
     resolution: {integrity: sha512-PFTA1gzfp1B1UaiJVyhJZA1rm0+Tzn690frc/L8vNX1Jop4STZgOE6bxUhnzdVSB+vm2GU1tIsuQcA9bxTQpMQ==}
     dependencies:
-      '@types/mdast': 3.0.11
+      '@types/mdast': 3.0.13
       mdast-util-to-markdown: 1.5.0
 
+  /mdast-util-gfm-task-list-item@2.0.0:
+    resolution: {integrity: sha512-IrtvNvjxC1o06taBAVJznEnkiHxLFTzgonUdy8hzFVeDun0uTjxxrRGVaNFqkU1wJR3RBPEfsxmU6jDWPofrTQ==}
+    dependencies:
+      '@types/mdast': 4.0.1
+      devlop: 1.1.0
+      mdast-util-from-markdown: 2.0.0
+      mdast-util-to-markdown: 2.1.0
+    transitivePeerDependencies:
+      - supports-color
+    dev: false
+
   /mdast-util-gfm@2.0.2:
     resolution: {integrity: sha512-qvZ608nBppZ4icQlhQQIAdc6S3Ffj9RGmzwUKUWuEICFnd1LVkN3EktF7ZHAgfcEdvZB5owU9tQgt99e2TlLjg==}
     dependencies:
@@ -10423,17 +10775,151 @@ packages:
     transitivePeerDependencies:
       - supports-color
 
+  /mdast-util-gfm@3.0.0:
+    resolution: {integrity: sha512-dgQEX5Amaq+DuUqf26jJqSK9qgixgd6rYDHAv4aTBuA92cTknZlKpPfa86Z/s8Dj8xsAQpFfBmPUHWJBWqS4Bw==}
+    dependencies:
+      mdast-util-from-markdown: 2.0.0
+      mdast-util-gfm-autolink-literal: 2.0.0
+      mdast-util-gfm-footnote: 2.0.0
+      mdast-util-gfm-strikethrough: 2.0.0
+      mdast-util-gfm-table: 2.0.0
+      mdast-util-gfm-task-list-item: 2.0.0
+      mdast-util-to-markdown: 2.1.0
+    transitivePeerDependencies:
+      - supports-color
+    dev: false
+
+  /mdast-util-mdx-expression@1.3.2:
+    resolution: {integrity: sha512-xIPmR5ReJDu/DHH1OoIT1HkuybIfRGYRywC+gJtI7qHjCJp/M9jrmBEJW22O8lskDWm562BX2W8TiAwRTb0rKA==}
+    dependencies:
+      '@types/estree-jsx': 1.0.1
+      '@types/hast': 2.3.6
+      '@types/mdast': 3.0.13
+      mdast-util-from-markdown: 1.3.1
+      mdast-util-to-markdown: 1.5.0
+    transitivePeerDependencies:
+      - supports-color
+    dev: false
+
+  /mdast-util-mdx-expression@2.0.0:
+    resolution: {integrity: sha512-fGCu8eWdKUKNu5mohVGkhBXCXGnOTLuFqOvGMvdikr+J1w7lDJgxThOKpwRWzzbyXAU2hhSwsmssOY4yTokluw==}
+    dependencies:
+      '@types/estree-jsx': 1.0.1
+      '@types/hast': 3.0.1
+      '@types/mdast': 4.0.1
+      devlop: 1.1.0
+      mdast-util-from-markdown: 2.0.0
+      mdast-util-to-markdown: 2.1.0
+    transitivePeerDependencies:
+      - supports-color
+    dev: false
+
+  /mdast-util-mdx-jsx@2.1.4:
+    resolution: {integrity: sha512-DtMn9CmVhVzZx3f+optVDF8yFgQVt7FghCRNdlIaS3X5Bnym3hZwPbg/XW86vdpKjlc1PVj26SpnLGeJBXD3JA==}
+    dependencies:
+      '@types/estree-jsx': 1.0.1
+      '@types/hast': 2.3.6
+      '@types/mdast': 3.0.13
+      '@types/unist': 2.0.8
+      ccount: 2.0.1
+      mdast-util-from-markdown: 1.3.1
+      mdast-util-to-markdown: 1.5.0
+      parse-entities: 4.0.1
+      stringify-entities: 4.0.3
+      unist-util-remove-position: 4.0.2
+      unist-util-stringify-position: 3.0.3
+      vfile-message: 3.1.4
+    transitivePeerDependencies:
+      - supports-color
+    dev: false
+
+  /mdast-util-mdx-jsx@3.0.0:
+    resolution: {integrity: sha512-XZuPPzQNBPAlaqsTTgRrcJnyFbSOBovSadFgbFu8SnuNgm+6Bdx1K+IWoitsmj6Lq6MNtI+ytOqwN70n//NaBA==}
+    dependencies:
+      '@types/estree-jsx': 1.0.1
+      '@types/hast': 3.0.1
+      '@types/mdast': 4.0.1
+      '@types/unist': 3.0.0
+      ccount: 2.0.1
+      devlop: 1.1.0
+      mdast-util-from-markdown: 2.0.0
+      mdast-util-to-markdown: 2.1.0
+      parse-entities: 4.0.1
+      stringify-entities: 4.0.3
+      unist-util-remove-position: 5.0.0
+      unist-util-stringify-position: 4.0.0
+      vfile-message: 4.0.2
+    transitivePeerDependencies:
+      - supports-color
+    dev: false
+
+  /mdast-util-mdx@2.0.1:
+    resolution: {integrity: sha512-38w5y+r8nyKlGvNjSEqWrhG0w5PmnRA+wnBvm+ulYCct7nsGYhFVb0lljS9bQav4psDAS1eGkP2LMVcZBi/aqw==}
+    dependencies:
+      mdast-util-from-markdown: 1.3.1
+      mdast-util-mdx-expression: 1.3.2
+      mdast-util-mdx-jsx: 2.1.4
+      mdast-util-mdxjs-esm: 1.3.1
+      mdast-util-to-markdown: 1.5.0
+    transitivePeerDependencies:
+      - supports-color
+    dev: false
+
+  /mdast-util-mdx@3.0.0:
+    resolution: {integrity: sha512-JfbYLAW7XnYTTbUsmpu0kdBUVe+yKVJZBItEjwyYJiDJuZ9w4eeaqks4HQO+R7objWgS2ymV60GYpI14Ug554w==}
+    dependencies:
+      mdast-util-from-markdown: 2.0.0
+      mdast-util-mdx-expression: 2.0.0
+      mdast-util-mdx-jsx: 3.0.0
+      mdast-util-mdxjs-esm: 2.0.1
+      mdast-util-to-markdown: 2.1.0
+    transitivePeerDependencies:
+      - supports-color
+    dev: false
+
+  /mdast-util-mdxjs-esm@1.3.1:
+    resolution: {integrity: sha512-SXqglS0HrEvSdUEfoXFtcg7DRl7S2cwOXc7jkuusG472Mmjag34DUDeOJUZtl+BVnyeO1frIgVpHlNRWc2gk/w==}
+    dependencies:
+      '@types/estree-jsx': 1.0.1
+      '@types/hast': 2.3.6
+      '@types/mdast': 3.0.13
+      mdast-util-from-markdown: 1.3.1
+      mdast-util-to-markdown: 1.5.0
+    transitivePeerDependencies:
+      - supports-color
+    dev: false
+
+  /mdast-util-mdxjs-esm@2.0.1:
+    resolution: {integrity: sha512-EcmOpxsZ96CvlP03NghtH1EsLtr0n9Tm4lPUJUBccV9RwUOneqSycg19n5HGzCf+10LozMRSObtVr3ee1WoHtg==}
+    dependencies:
+      '@types/estree-jsx': 1.0.1
+      '@types/hast': 3.0.1
+      '@types/mdast': 4.0.1
+      devlop: 1.1.0
+      mdast-util-from-markdown: 2.0.0
+      mdast-util-to-markdown: 2.1.0
+    transitivePeerDependencies:
+      - supports-color
+    dev: false
+
   /mdast-util-phrasing@3.0.1:
     resolution: {integrity: sha512-WmI1gTXUBJo4/ZmSk79Wcb2HcjPJBzM1nlI/OUWA8yk2X9ik3ffNbBGsU+09BFmXaL1IBb9fiuvq6/KMiNycSg==}
     dependencies:
-      '@types/mdast': 3.0.11
+      '@types/mdast': 3.0.13
       unist-util-is: 5.2.1
 
+  /mdast-util-phrasing@4.0.0:
+    resolution: {integrity: sha512-xadSsJayQIucJ9n053dfQwVu1kuXg7jCTdYsMK8rqzKZh52nLfSH/k0sAxE0u+pj/zKZX+o5wB+ML5mRayOxFA==}
+    dependencies:
+      '@types/mdast': 4.0.1
+      unist-util-is: 6.0.0
+    dev: false
+
   /mdast-util-to-hast@12.3.0:
     resolution: {integrity: sha512-pits93r8PhnIoU4Vy9bjW39M2jJ6/tdHyja9rrot9uujkN7UTU9SDnE6WNJz/IGyQk3XHX6yNNtrBH6cQzm8Hw==}
     dependencies:
-      '@types/hast': 2.3.4
-      '@types/mdast': 3.0.11
+      '@types/hast': 2.3.6
+      '@types/mdast': 3.0.13
       mdast-util-definitions: 5.1.2
       micromark-util-sanitize-uri: 1.2.0
       trim-lines: 3.0.1
@@ -10441,11 +10927,24 @@ packages:
       unist-util-position: 4.0.4
       unist-util-visit: 4.1.2
 
+  /mdast-util-to-hast@13.0.2:
+    resolution: {integrity: sha512-U5I+500EOOw9e3ZrclN3Is3fRpw8c19SMyNZlZ2IS+7vLsNzb2Om11VpIVOR+/0137GhZsFEF6YiKD5+0Hr2Og==}
+    dependencies:
+      '@types/hast': 3.0.1
+      '@types/mdast': 4.0.1
+      '@ungap/structured-clone': 1.2.0
+      devlop: 1.1.0
+      micromark-util-sanitize-uri: 2.0.0
+      trim-lines: 3.0.1
+      unist-util-position: 5.0.0
+      unist-util-visit: 5.0.0
+    dev: false
+
   /mdast-util-to-markdown@1.5.0:
     resolution: {integrity: sha512-bbv7TPv/WC49thZPg3jXuqzuvI45IL2EVAr/KxF0BSdHsU0ceFHOmwQn6evxAh1GaoK/6GQ1wp4R4oW2+LFL/A==}
     dependencies:
-      '@types/mdast': 3.0.11
-      '@types/unist': 2.0.6
+      '@types/mdast': 3.0.13
+      '@types/unist': 2.0.8
       longest-streak: 3.1.0
       mdast-util-phrasing: 3.0.1
       mdast-util-to-string: 3.2.0
@@ -10453,10 +10952,33 @@ packages:
       unist-util-visit: 4.1.2
       zwitch: 2.0.4
 
+  /mdast-util-to-markdown@2.1.0:
+    resolution: {integrity: sha512-SR2VnIEdVNCJbP6y7kVTJgPLifdr8WEU440fQec7qHoHOUz/oJ2jmNRqdDQ3rbiStOXb2mCDGTuwsK5OPUgYlQ==}
+    dependencies:
+      '@types/mdast': 4.0.1
+      '@types/unist': 3.0.0
+      longest-streak: 3.1.0
+      mdast-util-phrasing: 4.0.0
+      mdast-util-to-string: 4.0.0
+      micromark-util-decode-string: 2.0.0
+      unist-util-visit: 5.0.0
+      zwitch: 2.0.4
+    dev: false
+
   /mdast-util-to-string@3.2.0:
     resolution: {integrity: sha512-V4Zn/ncyN1QNSqSBxTrMOLpjr+IKdHl2v3KVLoWmDPscP4r9GcCi71gjgvUV1SFSKh92AjAG4peFuBl2/YgCJg==}
     dependencies:
-      '@types/mdast': 3.0.11
+      '@types/mdast': 3.0.13
+
+  /mdast-util-to-string@4.0.0:
+    resolution: {integrity: sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==}
+    dependencies:
+      '@types/mdast': 4.0.1
+    dev: false
+
+  /mdn-data@2.0.14:
+    resolution: {integrity: sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==}
+    dev: false
 
   /mdn-data@2.0.30:
     resolution: {integrity: sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==}
@@ -10516,6 +11038,36 @@ packages:
       micromark-util-types: 1.1.0
       uvu: 0.5.6
 
+  /micromark-core-commonmark@2.0.0:
+    resolution: {integrity: sha512-jThOz/pVmAYUtkroV3D5c1osFXAMv9e0ypGDOIZuCeAe91/sD6BoE2Sjzt30yuXtwOYUmySOhMas/PVyh02itA==}
+    dependencies:
+      decode-named-character-reference: 1.0.2
+      devlop: 1.1.0
+      micromark-factory-destination: 2.0.0
+      micromark-factory-label: 2.0.0
+      micromark-factory-space: 2.0.0
+      micromark-factory-title: 2.0.0
+      micromark-factory-whitespace: 2.0.0
+      micromark-util-character: 2.0.1
+      micromark-util-chunked: 2.0.0
+      micromark-util-classify-character: 2.0.0
+      micromark-util-html-tag-name: 2.0.0
+      micromark-util-normalize-identifier: 2.0.0
+      micromark-util-resolve-all: 2.0.0
+      micromark-util-subtokenize: 2.0.0
+      micromark-util-symbol: 2.0.0
+      micromark-util-types: 2.0.0
+    dev: false
+
+  /micromark-extension-frontmatter@2.0.0:
+    resolution: {integrity: sha512-C4AkuM3dA58cgZha7zVnuVxBhDsbttIMiytjgsM2XbHAB2faRVaHRle40558FBN+DJcrLNCoqG5mlrpdU4cRtg==}
+    dependencies:
+      fault: 2.0.1
+      micromark-util-character: 2.0.1
+      micromark-util-symbol: 2.0.0
+      micromark-util-types: 2.0.0
+    dev: false
+
   /micromark-extension-gfm-autolink-literal@1.0.5:
     resolution: {integrity: sha512-z3wJSLrDf8kRDOh2qBtoTRD53vJ+CWIyo7uyZuxf/JAbNJjiHsOpG1y5wxk8drtv3ETAHutCu6N3thkOOgueWg==}
     dependencies:
@@ -10524,6 +11076,15 @@ packages:
       micromark-util-symbol: 1.1.0
       micromark-util-types: 1.1.0
 
+  /micromark-extension-gfm-autolink-literal@2.0.0:
+    resolution: {integrity: sha512-rTHfnpt/Q7dEAK1Y5ii0W8bhfJlVJFnJMHIPisfPK3gpVNuOP0VnRl96+YJ3RYWV/P4gFeQoGKNlT3RhuvpqAg==}
+    dependencies:
+      micromark-util-character: 2.0.1
+      micromark-util-sanitize-uri: 2.0.0
+      micromark-util-symbol: 2.0.0
+      micromark-util-types: 2.0.0
+    dev: false
+
   /micromark-extension-gfm-footnote@1.1.2:
     resolution: {integrity: sha512-Yxn7z7SxgyGWRNa4wzf8AhYYWNrwl5q1Z8ii+CSTTIqVkmGZF1CElX2JI8g5yGoM3GAman9/PVCUFUSJ0kB/8Q==}
     dependencies:
@@ -10536,6 +11097,19 @@ packages:
       micromark-util-types: 1.1.0
       uvu: 0.5.6
 
+  /micromark-extension-gfm-footnote@2.0.0:
+    resolution: {integrity: sha512-6Rzu0CYRKDv3BfLAUnZsSlzx3ak6HAoI85KTiijuKIz5UxZxbUI+pD6oHgw+6UtQuiRwnGRhzMmPRv4smcz0fg==}
+    dependencies:
+      devlop: 1.1.0
+      micromark-core-commonmark: 2.0.0
+      micromark-factory-space: 2.0.0
+      micromark-util-character: 2.0.1
+      micromark-util-normalize-identifier: 2.0.0
+      micromark-util-sanitize-uri: 2.0.0
+      micromark-util-symbol: 2.0.0
+      micromark-util-types: 2.0.0
+    dev: false
+
   /micromark-extension-gfm-strikethrough@1.0.7:
     resolution: {integrity: sha512-sX0FawVE1o3abGk3vRjOH50L5TTLr3b5XMqnP9YDRb34M0v5OoZhG+OHFz1OffZ9dlwgpTBKaT4XW/AsUVnSDw==}
     dependencies:
@@ -10546,6 +11120,17 @@ packages:
       micromark-util-types: 1.1.0
       uvu: 0.5.6
 
+  /micromark-extension-gfm-strikethrough@2.0.0:
+    resolution: {integrity: sha512-c3BR1ClMp5fxxmwP6AoOY2fXO9U8uFMKs4ADD66ahLTNcwzSCyRVU4k7LPV5Nxo/VJiR4TdzxRQY2v3qIUceCw==}
+    dependencies:
+      devlop: 1.1.0
+      micromark-util-chunked: 2.0.0
+      micromark-util-classify-character: 2.0.0
+      micromark-util-resolve-all: 2.0.0
+      micromark-util-symbol: 2.0.0
+      micromark-util-types: 2.0.0
+    dev: false
+
   /micromark-extension-gfm-table@1.0.7:
     resolution: {integrity: sha512-3ZORTHtcSnMQEKtAOsBQ9/oHp9096pI/UvdPtN7ehKvrmZZ2+bbWhi0ln+I9drmwXMt5boocn6OlwQzNXeVeqw==}
     dependencies:
@@ -10555,11 +11140,27 @@ packages:
       micromark-util-types: 1.1.0
       uvu: 0.5.6
 
+  /micromark-extension-gfm-table@2.0.0:
+    resolution: {integrity: sha512-PoHlhypg1ItIucOaHmKE8fbin3vTLpDOUg8KAr8gRCF1MOZI9Nquq2i/44wFvviM4WuxJzc3demT8Y3dkfvYrw==}
+    dependencies:
+      devlop: 1.1.0
+      micromark-factory-space: 2.0.0
+      micromark-util-character: 2.0.1
+      micromark-util-symbol: 2.0.0
+      micromark-util-types: 2.0.0
+    dev: false
+
   /micromark-extension-gfm-tagfilter@1.0.2:
     resolution: {integrity: sha512-5XWB9GbAUSHTn8VPU8/1DBXMuKYT5uOgEjJb8gN3mW0PNW5OPHpSdojoqf+iq1xo7vWzw/P8bAHY0n6ijpXF7g==}
     dependencies:
       micromark-util-types: 1.1.0
 
+  /micromark-extension-gfm-tagfilter@2.0.0:
+    resolution: {integrity: sha512-xHlTOmuCSotIA8TW1mDIM6X2O1SiX5P9IuDtqGonFhEK0qgRI4yeC6vMxEV2dgyr2TiD+2PQ10o+cOhdVAcwfg==}
+    dependencies:
+      micromark-util-types: 2.0.0
+    dev: false
+
   /micromark-extension-gfm-task-list-item@1.0.5:
     resolution: {integrity: sha512-RMFXl2uQ0pNQy6Lun2YBYT9g9INXtWJULgbt01D/x8/6yJ2qpKyzdZD3pi6UIkzF++Da49xAelVKUeUMqd5eIQ==}
     dependencies:
@@ -10569,6 +11170,16 @@ packages:
       micromark-util-types: 1.1.0
       uvu: 0.5.6
 
+  /micromark-extension-gfm-task-list-item@2.0.1:
+    resolution: {integrity: sha512-cY5PzGcnULaN5O7T+cOzfMoHjBW7j+T9D2sucA5d/KbsBTPcYdebm9zUd9zzdgJGCwahV+/W78Z3nbulBYVbTw==}
+    dependencies:
+      devlop: 1.1.0
+      micromark-factory-space: 2.0.0
+      micromark-util-character: 2.0.1
+      micromark-util-symbol: 2.0.0
+      micromark-util-types: 2.0.0
+    dev: false
+
   /micromark-extension-gfm@2.0.3:
     resolution: {integrity: sha512-vb9OoHqrhCmbRidQv/2+Bc6pkP0FrtlhurxZofvOEy5o8RtuuvTq+RQ1Vw5ZDNrVraQZu3HixESqbG+0iKk/MQ==}
     dependencies:
@@ -10581,6 +11192,141 @@ packages:
       micromark-util-combine-extensions: 1.1.0
       micromark-util-types: 1.1.0
 
+  /micromark-extension-gfm@3.0.0:
+    resolution: {integrity: sha512-vsKArQsicm7t0z2GugkCKtZehqUm31oeGBV/KVSorWSy8ZlNAv7ytjFhvaryUiCUJYqs+NoE6AFhpQvBTM6Q4w==}
+    dependencies:
+      micromark-extension-gfm-autolink-literal: 2.0.0
+      micromark-extension-gfm-footnote: 2.0.0
+      micromark-extension-gfm-strikethrough: 2.0.0
+      micromark-extension-gfm-table: 2.0.0
+      micromark-extension-gfm-tagfilter: 2.0.0
+      micromark-extension-gfm-task-list-item: 2.0.1
+      micromark-util-combine-extensions: 2.0.0
+      micromark-util-types: 2.0.0
+    dev: false
+
+  /micromark-extension-mdx-expression@1.0.8:
+    resolution: {integrity: sha512-zZpeQtc5wfWKdzDsHRBY003H2Smg+PUi2REhqgIhdzAa5xonhP03FcXxqFSerFiNUr5AWmHpaNPQTBVOS4lrXw==}
+    dependencies:
+      '@types/estree': 1.0.2
+      micromark-factory-mdx-expression: 1.0.9
+      micromark-factory-space: 1.1.0
+      micromark-util-character: 1.2.0
+      micromark-util-events-to-acorn: 1.2.3
+      micromark-util-symbol: 1.1.0
+      micromark-util-types: 1.1.0
+      uvu: 0.5.6
+    dev: false
+
+  /micromark-extension-mdx-expression@2.0.0:
+    resolution: {integrity: sha512-hUI6PJCCVaymBF5paL29sOpcbtVXtumDdJgBDxN+tbHlXAqQwNl4EhhJfx4fe7bUpEZzcFRIBAeOiGq7hsZBXw==}
+    dependencies:
+      '@types/estree': 1.0.2
+      devlop: 1.1.0
+      micromark-factory-mdx-expression: 2.0.1
+      micromark-factory-space: 2.0.0
+      micromark-util-character: 2.0.1
+      micromark-util-events-to-acorn: 2.0.1
+      micromark-util-symbol: 2.0.0
+      micromark-util-types: 2.0.0
+    dev: false
+
+  /micromark-extension-mdx-jsx@1.0.5:
+    resolution: {integrity: sha512-gPH+9ZdmDflbu19Xkb8+gheqEDqkSpdCEubQyxuz/Hn8DOXiXvrXeikOoBA71+e8Pfi0/UYmU3wW3H58kr7akA==}
+    dependencies:
+      '@types/acorn': 4.0.6
+      '@types/estree': 1.0.2
+      estree-util-is-identifier-name: 2.1.0
+      micromark-factory-mdx-expression: 1.0.9
+      micromark-factory-space: 1.1.0
+      micromark-util-character: 1.2.0
+      micromark-util-symbol: 1.1.0
+      micromark-util-types: 1.1.0
+      uvu: 0.5.6
+      vfile-message: 3.1.4
+    dev: false
+
+  /micromark-extension-mdx-jsx@2.0.0:
+    resolution: {integrity: sha512-hp6ff4eympWcq3Jh9XIJmJPNpM2RNmBjz5vvU1YkND7h4UwjSZas7lXSrAJjtTG7Z56JMMTyowwcbPkAjZmwMg==}
+    dependencies:
+      '@types/acorn': 4.0.6
+      '@types/estree': 1.0.2
+      devlop: 1.1.0
+      estree-util-is-identifier-name: 2.1.0
+      micromark-factory-mdx-expression: 2.0.1
+      micromark-factory-space: 2.0.0
+      micromark-util-character: 2.0.1
+      micromark-util-symbol: 2.0.0
+      micromark-util-types: 2.0.0
+      vfile-message: 4.0.2
+    dev: false
+
+  /micromark-extension-mdx-md@1.0.1:
+    resolution: {integrity: sha512-7MSuj2S7xjOQXAjjkbjBsHkMtb+mDGVW6uI2dBL9snOBCbZmoNgDAeZ0nSn9j3T42UE/g2xVNMn18PJxZvkBEA==}
+    dependencies:
+      micromark-util-types: 1.1.0
+    dev: false
+
+  /micromark-extension-mdx-md@2.0.0:
+    resolution: {integrity: sha512-EpAiszsB3blw4Rpba7xTOUptcFeBFi+6PY8VnJ2hhimH+vCQDirWgsMpz7w1XcZE7LVrSAUGb9VJpG9ghlYvYQ==}
+    dependencies:
+      micromark-util-types: 2.0.0
+    dev: false
+
+  /micromark-extension-mdxjs-esm@1.0.5:
+    resolution: {integrity: sha512-xNRBw4aoURcyz/S69B19WnZAkWJMxHMT5hE36GtDAyhoyn/8TuAeqjFJQlwk+MKQsUD7b3l7kFX+vlfVWgcX1w==}
+    dependencies:
+      '@types/estree': 1.0.2
+      micromark-core-commonmark: 1.1.0
+      micromark-util-character: 1.2.0
+      micromark-util-events-to-acorn: 1.2.3
+      micromark-util-symbol: 1.1.0
+      micromark-util-types: 1.1.0
+      unist-util-position-from-estree: 1.1.2
+      uvu: 0.5.6
+      vfile-message: 3.1.4
+    dev: false
+
+  /micromark-extension-mdxjs-esm@2.0.1:
+    resolution: {integrity: sha512-HLPrY5XLYzFtG5KxEcZXfUV/SOy9Eu3R+dnpP1P6ko/ZO9xceGxmgJOAMq4r/rPLrHaEosfhNIOXDcvFSkVfKQ==}
+    dependencies:
+      '@types/estree': 1.0.2
+      devlop: 1.1.0
+      micromark-core-commonmark: 2.0.0
+      micromark-util-character: 2.0.1
+      micromark-util-events-to-acorn: 2.0.1
+      micromark-util-symbol: 2.0.0
+      micromark-util-types: 2.0.0
+      unist-util-position-from-estree: 2.0.0
+      vfile-message: 4.0.2
+    dev: false
+
+  /micromark-extension-mdxjs@1.0.1:
+    resolution: {integrity: sha512-7YA7hF6i5eKOfFUzZ+0z6avRG52GpWR8DL+kN47y3f2KhxbBZMhmxe7auOeaTBrW2DenbbZTf1ea9tA2hDpC2Q==}
+    dependencies:
+      acorn: 8.10.0
+      acorn-jsx: 5.3.2(acorn@8.10.0)
+      micromark-extension-mdx-expression: 1.0.8
+      micromark-extension-mdx-jsx: 1.0.5
+      micromark-extension-mdx-md: 1.0.1
+      micromark-extension-mdxjs-esm: 1.0.5
+      micromark-util-combine-extensions: 1.1.0
+      micromark-util-types: 1.1.0
+    dev: false
+
+  /micromark-extension-mdxjs@2.0.0:
+    resolution: {integrity: sha512-cICbQUdcgFvfg3JH9XTqZoa1ONCZI0GsiOvl9672Ka3SilIo9kMmaKLdSd/QrDgNGxrirWtZfFh19DSKJUivWQ==}
+    dependencies:
+      acorn: 8.10.0
+      acorn-jsx: 5.3.2(acorn@8.10.0)
+      micromark-extension-mdx-expression: 2.0.0
+      micromark-extension-mdx-jsx: 2.0.0
+      micromark-extension-mdx-md: 2.0.0
+      micromark-extension-mdxjs-esm: 2.0.1
+      micromark-util-combine-extensions: 2.0.0
+      micromark-util-types: 2.0.0
+    dev: false
+
   /micromark-factory-destination@1.1.0:
     resolution: {integrity: sha512-XaNDROBgx9SgSChd69pjiGKbV+nfHGDPVYFs5dOoDd7ZnMAE+Cuu91BCpsY8RT2NP9vo/B8pds2VQNCLiu0zhg==}
     dependencies:
@@ -10588,6 +11334,14 @@ packages:
       micromark-util-symbol: 1.1.0
       micromark-util-types: 1.1.0
 
+  /micromark-factory-destination@2.0.0:
+    resolution: {integrity: sha512-j9DGrQLm/Uhl2tCzcbLhy5kXsgkHUrjJHg4fFAeoMRwJmJerT9aw4FEhIbZStWN8A3qMwOp1uzHr4UL8AInxtA==}
+    dependencies:
+      micromark-util-character: 2.0.1
+      micromark-util-symbol: 2.0.0
+      micromark-util-types: 2.0.0
+    dev: false
+
   /micromark-factory-label@1.1.0:
     resolution: {integrity: sha512-OLtyez4vZo/1NjxGhcpDSbHQ+m0IIGnT8BoPamh+7jVlzLJBH98zzuCoUeMxvM6WsNeh8wx8cKvqLiPHEACn0w==}
     dependencies:
@@ -10596,12 +11350,54 @@ packages:
       micromark-util-types: 1.1.0
       uvu: 0.5.6
 
+  /micromark-factory-label@2.0.0:
+    resolution: {integrity: sha512-RR3i96ohZGde//4WSe/dJsxOX6vxIg9TimLAS3i4EhBAFx8Sm5SmqVfR8E87DPSR31nEAjZfbt91OMZWcNgdZw==}
+    dependencies:
+      devlop: 1.1.0
+      micromark-util-character: 2.0.1
+      micromark-util-symbol: 2.0.0
+      micromark-util-types: 2.0.0
+    dev: false
+
+  /micromark-factory-mdx-expression@1.0.9:
+    resolution: {integrity: sha512-jGIWzSmNfdnkJq05c7b0+Wv0Kfz3NJ3N4cBjnbO4zjXIlxJr+f8lk+5ZmwFvqdAbUy2q6B5rCY//g0QAAaXDWA==}
+    dependencies:
+      '@types/estree': 1.0.2
+      micromark-util-character: 1.2.0
+      micromark-util-events-to-acorn: 1.2.3
+      micromark-util-symbol: 1.1.0
+      micromark-util-types: 1.1.0
+      unist-util-position-from-estree: 1.1.2
+      uvu: 0.5.6
+      vfile-message: 3.1.4
+    dev: false
+
+  /micromark-factory-mdx-expression@2.0.1:
+    resolution: {integrity: sha512-F0ccWIUHRLRrYp5TC9ZYXmZo+p2AM13ggbsW4T0b5CRKP8KHVRB8t4pwtBgTxtjRmwrK0Irwm7vs2JOZabHZfg==}
+    dependencies:
+      '@types/estree': 1.0.2
+      devlop: 1.1.0
+      micromark-util-character: 2.0.1
+      micromark-util-events-to-acorn: 2.0.1
+      micromark-util-symbol: 2.0.0
+      micromark-util-types: 2.0.0
+      unist-util-position-from-estree: 2.0.0
+      vfile-message: 4.0.2
+    dev: false
+
   /micromark-factory-space@1.1.0:
     resolution: {integrity: sha512-cRzEj7c0OL4Mw2v6nwzttyOZe8XY/Z8G0rzmWQZTBi/jjwyw/U4uqKtUORXQrR5bAZZnbTI/feRV/R7hc4jQYQ==}
     dependencies:
       micromark-util-character: 1.2.0
       micromark-util-types: 1.1.0
 
+  /micromark-factory-space@2.0.0:
+    resolution: {integrity: sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==}
+    dependencies:
+      micromark-util-character: 2.0.1
+      micromark-util-types: 2.0.0
+    dev: false
+
   /micromark-factory-title@1.1.0:
     resolution: {integrity: sha512-J7n9R3vMmgjDOCY8NPw55jiyaQnH5kBdV2/UXCtZIpnHH3P6nHUKaH7XXEYuWwx/xUJcawa8plLBEjMPU24HzQ==}
     dependencies:
@@ -10610,6 +11406,15 @@ packages:
       micromark-util-symbol: 1.1.0
       micromark-util-types: 1.1.0
 
+  /micromark-factory-title@2.0.0:
+    resolution: {integrity: sha512-jY8CSxmpWLOxS+t8W+FG3Xigc0RDQA9bKMY/EwILvsesiRniiVMejYTE4wumNc2f4UbAa4WsHqe3J1QS1sli+A==}
+    dependencies:
+      micromark-factory-space: 2.0.0
+      micromark-util-character: 2.0.1
+      micromark-util-symbol: 2.0.0
+      micromark-util-types: 2.0.0
+    dev: false
+
   /micromark-factory-whitespace@1.1.0:
     resolution: {integrity: sha512-v2WlmiymVSp5oMg+1Q0N1Lxmt6pMhIHD457whWM7/GUlEks1hI9xj5w3zbc4uuMKXGisksZk8DzP2UyGbGqNsQ==}
     dependencies:
@@ -10618,17 +11423,39 @@ packages:
       micromark-util-symbol: 1.1.0
       micromark-util-types: 1.1.0
 
+  /micromark-factory-whitespace@2.0.0:
+    resolution: {integrity: sha512-28kbwaBjc5yAI1XadbdPYHX/eDnqaUFVikLwrO7FDnKG7lpgxnvk/XGRhX/PN0mOZ+dBSZ+LgunHS+6tYQAzhA==}
+    dependencies:
+      micromark-factory-space: 2.0.0
+      micromark-util-character: 2.0.1
+      micromark-util-symbol: 2.0.0
+      micromark-util-types: 2.0.0
+    dev: false
+
   /micromark-util-character@1.2.0:
     resolution: {integrity: sha512-lXraTwcX3yH/vMDaFWCQJP1uIszLVebzUa3ZHdrgxr7KEU/9mL4mVgCpGbyhvNLNlauROiNUq7WN5u7ndbY6xg==}
     dependencies:
       micromark-util-symbol: 1.1.0
       micromark-util-types: 1.1.0
 
+  /micromark-util-character@2.0.1:
+    resolution: {integrity: sha512-3wgnrmEAJ4T+mGXAUfMvMAbxU9RDG43XmGce4j6CwPtVxB3vfwXSZ6KhFwDzZ3mZHhmPimMAXg71veiBGzeAZw==}
+    dependencies:
+      micromark-util-symbol: 2.0.0
+      micromark-util-types: 2.0.0
+    dev: false
+
   /micromark-util-chunked@1.1.0:
     resolution: {integrity: sha512-Ye01HXpkZPNcV6FiyoW2fGZDUw4Yc7vT0E9Sad83+bEDiCJ1uXu0S3mr8WLpsz3HaG3x2q0HM6CTuPdcZcluFQ==}
     dependencies:
       micromark-util-symbol: 1.1.0
 
+  /micromark-util-chunked@2.0.0:
+    resolution: {integrity: sha512-anK8SWmNphkXdaKgz5hJvGa7l00qmcaUQoMYsBwDlSKFKjc6gjGXPDw3FNL3Nbwq5L8gE+RCbGqTw49FK5Qyvg==}
+    dependencies:
+      micromark-util-symbol: 2.0.0
+    dev: false
+
   /micromark-util-classify-character@1.1.0:
     resolution: {integrity: sha512-SL0wLxtKSnklKSUplok1WQFoGhUdWYKggKUiqhX+Swala+BtptGCu5iPRc+xvzJ4PXE/hwM3FNXsfEVgoZsWbw==}
     dependencies:
@@ -10636,17 +11463,38 @@ packages:
       micromark-util-symbol: 1.1.0
       micromark-util-types: 1.1.0
 
+  /micromark-util-classify-character@2.0.0:
+    resolution: {integrity: sha512-S0ze2R9GH+fu41FA7pbSqNWObo/kzwf8rN/+IGlW/4tC6oACOs8B++bh+i9bVyNnwCcuksbFwsBme5OCKXCwIw==}
+    dependencies:
+      micromark-util-character: 2.0.1
+      micromark-util-symbol: 2.0.0
+      micromark-util-types: 2.0.0
+    dev: false
+
   /micromark-util-combine-extensions@1.1.0:
     resolution: {integrity: sha512-Q20sp4mfNf9yEqDL50WwuWZHUrCO4fEyeDCnMGmG5Pr0Cz15Uo7KBs6jq+dq0EgX4DPwwrh9m0X+zPV1ypFvUA==}
     dependencies:
       micromark-util-chunked: 1.1.0
       micromark-util-types: 1.1.0
 
+  /micromark-util-combine-extensions@2.0.0:
+    resolution: {integrity: sha512-vZZio48k7ON0fVS3CUgFatWHoKbbLTK/rT7pzpJ4Bjp5JjkZeasRfrS9wsBdDJK2cJLHMckXZdzPSSr1B8a4oQ==}
+    dependencies:
+      micromark-util-chunked: 2.0.0
+      micromark-util-types: 2.0.0
+    dev: false
+
   /micromark-util-decode-numeric-character-reference@1.1.0:
     resolution: {integrity: sha512-m9V0ExGv0jB1OT21mrWcuf4QhP46pH1KkfWy9ZEezqHKAxkj4mPCy3nIH1rkbdMlChLHX531eOrymlwyZIf2iw==}
     dependencies:
       micromark-util-symbol: 1.1.0
 
+  /micromark-util-decode-numeric-character-reference@2.0.0:
+    resolution: {integrity: sha512-pIgcsGxpHEtTG/rPJRz/HOLSqp5VTuIIjXlPI+6JSDlK2oljApusG6KzpS8AF0ENUMCHlC/IBb5B9xdFiVlm5Q==}
+    dependencies:
+      micromark-util-symbol: 2.0.0
+    dev: false
+
   /micromark-util-decode-string@1.1.0:
     resolution: {integrity: sha512-YphLGCK8gM1tG1bd54azwyrQRjCFcmgj2S2GoJDNnh4vYtnL38JS8M4gpxzOPNyHdNEpheyWXCTnnTDY3N+NVQ==}
     dependencies:
@@ -10655,22 +11503,77 @@ packages:
       micromark-util-decode-numeric-character-reference: 1.1.0
       micromark-util-symbol: 1.1.0
 
+  /micromark-util-decode-string@2.0.0:
+    resolution: {integrity: sha512-r4Sc6leeUTn3P6gk20aFMj2ntPwn6qpDZqWvYmAG6NgvFTIlj4WtrAudLi65qYoaGdXYViXYw2pkmn7QnIFasA==}
+    dependencies:
+      decode-named-character-reference: 1.0.2
+      micromark-util-character: 2.0.1
+      micromark-util-decode-numeric-character-reference: 2.0.0
+      micromark-util-symbol: 2.0.0
+    dev: false
+
   /micromark-util-encode@1.1.0:
     resolution: {integrity: sha512-EuEzTWSTAj9PA5GOAs992GzNh2dGQO52UvAbtSOMvXTxv3Criqb6IOzJUBCmEqrrXSblJIJBbFFv6zPxpreiJw==}
 
+  /micromark-util-encode@2.0.0:
+    resolution: {integrity: sha512-pS+ROfCXAGLWCOc8egcBvT0kf27GoWMqtdarNfDcjb6YLuV5cM3ioG45Ys2qOVqeqSbjaKg72vU+Wby3eddPsA==}
+    dev: false
+
+  /micromark-util-events-to-acorn@1.2.3:
+    resolution: {integrity: sha512-ij4X7Wuc4fED6UoLWkmo0xJQhsktfNh1J0m8g4PbIMPlx+ek/4YdW5mvbye8z/aZvAPUoxgXHrwVlXAPKMRp1w==}
+    dependencies:
+      '@types/acorn': 4.0.6
+      '@types/estree': 1.0.2
+      '@types/unist': 2.0.8
+      estree-util-visit: 1.2.1
+      micromark-util-symbol: 1.1.0
+      micromark-util-types: 1.1.0
+      uvu: 0.5.6
+      vfile-message: 3.1.4
+    dev: false
+
+  /micromark-util-events-to-acorn@2.0.1:
+    resolution: {integrity: sha512-3pf0pxvFaTxzTwisMHmEk5lnW7oSU/oRZxpZcrdx/voJgCpPaspexc89mJodW4ekATo1UILtZvjESclKONSB6w==}
+    dependencies:
+      '@types/acorn': 4.0.6
+      '@types/estree': 1.0.2
+      '@types/unist': 3.0.0
+      devlop: 1.1.0
+      estree-util-visit: 1.2.1
+      micromark-util-symbol: 2.0.0
+      micromark-util-types: 2.0.0
+      vfile-message: 4.0.2
+    dev: false
+
   /micromark-util-html-tag-name@1.2.0:
     resolution: {integrity: sha512-VTQzcuQgFUD7yYztuQFKXT49KghjtETQ+Wv/zUjGSGBioZnkA4P1XXZPT1FHeJA6RwRXSF47yvJ1tsJdoxwO+Q==}
 
+  /micromark-util-html-tag-name@2.0.0:
+    resolution: {integrity: sha512-xNn4Pqkj2puRhKdKTm8t1YHC/BAjx6CEwRFXntTaRf/x16aqka6ouVoutm+QdkISTlT7e2zU7U4ZdlDLJd2Mcw==}
+    dev: false
+
   /micromark-util-normalize-identifier@1.1.0:
     resolution: {integrity: sha512-N+w5vhqrBihhjdpM8+5Xsxy71QWqGn7HYNUvch71iV2PM7+E3uWGox1Qp90loa1ephtCxG2ftRV/Conitc6P2Q==}
     dependencies:
       micromark-util-symbol: 1.1.0
 
+  /micromark-util-normalize-identifier@2.0.0:
+    resolution: {integrity: sha512-2xhYT0sfo85FMrUPtHcPo2rrp1lwbDEEzpx7jiH2xXJLqBuy4H0GgXk5ToU8IEwoROtXuL8ND0ttVa4rNqYK3w==}
+    dependencies:
+      micromark-util-symbol: 2.0.0
+    dev: false
+
   /micromark-util-resolve-all@1.1.0:
     resolution: {integrity: sha512-b/G6BTMSg+bX+xVCshPTPyAu2tmA0E4X98NSR7eIbeC6ycCqCeE7wjfDIgzEbkzdEVJXRtOG4FbEm/uGbCRouA==}
     dependencies:
       micromark-util-types: 1.1.0
 
+  /micromark-util-resolve-all@2.0.0:
+    resolution: {integrity: sha512-6KU6qO7DZ7GJkaCgwBNtplXCvGkJToU86ybBAUdavvgsCiG8lSSvYxr9MhwmQ+udpzywHsl4RpGJsYWG1pDOcA==}
+    dependencies:
+      micromark-util-types: 2.0.0
+    dev: false
+
   /micromark-util-sanitize-uri@1.2.0:
     resolution: {integrity: sha512-QO4GXv0XZfWey4pYFndLUKEAktKkG5kZTdUNaTAkzbuJxn2tNBOr+QtxR2XpWaMhbImT2dPzyLrPXLlPhph34A==}
     dependencies:
@@ -10678,6 +11581,14 @@ packages:
       micromark-util-encode: 1.1.0
       micromark-util-symbol: 1.1.0
 
+  /micromark-util-sanitize-uri@2.0.0:
+    resolution: {integrity: sha512-WhYv5UEcZrbAtlsnPuChHUAsu/iBPOVaEVsntLBIdpibO0ddy8OzavZz3iL2xVvBZOpolujSliP65Kq0/7KIYw==}
+    dependencies:
+      micromark-util-character: 2.0.1
+      micromark-util-encode: 2.0.0
+      micromark-util-symbol: 2.0.0
+    dev: false
+
   /micromark-util-subtokenize@1.1.0:
     resolution: {integrity: sha512-kUQHyzRoxvZO2PuLzMt2P/dwVsTiivCK8icYTeR+3WgbuPqfHgPPy7nFKbeqRivBvn/3N3GBiNC+JRTMSxEC7A==}
     dependencies:
@@ -10686,16 +11597,33 @@ packages:
       micromark-util-types: 1.1.0
       uvu: 0.5.6
 
+  /micromark-util-subtokenize@2.0.0:
+    resolution: {integrity: sha512-vc93L1t+gpR3p8jxeVdaYlbV2jTYteDje19rNSS/H5dlhxUYll5Fy6vJ2cDwP8RnsXi818yGty1ayP55y3W6fg==}
+    dependencies:
+      devlop: 1.1.0
+      micromark-util-chunked: 2.0.0
+      micromark-util-symbol: 2.0.0
+      micromark-util-types: 2.0.0
+    dev: false
+
   /micromark-util-symbol@1.1.0:
     resolution: {integrity: sha512-uEjpEYY6KMs1g7QfJ2eX1SQEV+ZT4rUD3UcF6l57acZvLNK7PBZL+ty82Z1qhK1/yXIY4bdx04FKMgR0g4IAag==}
 
+  /micromark-util-symbol@2.0.0:
+    resolution: {integrity: sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==}
+    dev: false
+
   /micromark-util-types@1.1.0:
     resolution: {integrity: sha512-ukRBgie8TIAcacscVHSiddHjO4k/q3pnedmzMQ4iwDcK0FtFCohKOlFbaOL/mPgfnPsL3C1ZyxJa4sbWrBl3jg==}
 
+  /micromark-util-types@2.0.0:
+    resolution: {integrity: sha512-oNh6S2WMHWRZrmutsRmDDfkzKtxF+bc2VxLC9dvtrDIRFln627VsFP6fLMgTryGDljgLPjkrzQSDcPrjPyDJ5w==}
+    dev: false
+
   /micromark@3.2.0:
     resolution: {integrity: sha512-uD66tJj54JLYq0De10AhWycZWGQNUvDI55xPgk2sQM5kn1JYlhbCMTtEeT27+vAhW2FBQxLlOmS3pmA7/2z4aA==}
     dependencies:
-      '@types/debug': 4.1.8
+      '@types/debug': 4.1.9
       debug: 4.3.4
       decode-named-character-reference: 1.0.2
       micromark-core-commonmark: 1.1.0
@@ -10715,6 +11643,30 @@ packages:
     transitivePeerDependencies:
       - supports-color
 
+  /micromark@4.0.0:
+    resolution: {integrity: sha512-o/sd0nMof8kYff+TqcDx3VSrgBTcZpSvYcAHIfHhv5VAuNmisCxjhx6YmxS8PFEpb9z5WKWKPdzf0jM23ro3RQ==}
+    dependencies:
+      '@types/debug': 4.1.9
+      debug: 4.3.4
+      decode-named-character-reference: 1.0.2
+      devlop: 1.1.0
+      micromark-core-commonmark: 2.0.0
+      micromark-factory-space: 2.0.0
+      micromark-util-character: 2.0.1
+      micromark-util-chunked: 2.0.0
+      micromark-util-combine-extensions: 2.0.0
+      micromark-util-decode-numeric-character-reference: 2.0.0
+      micromark-util-encode: 2.0.0
+      micromark-util-normalize-identifier: 2.0.0
+      micromark-util-resolve-all: 2.0.0
+      micromark-util-sanitize-uri: 2.0.0
+      micromark-util-subtokenize: 2.0.0
+      micromark-util-symbol: 2.0.0
+      micromark-util-types: 2.0.0
+    transitivePeerDependencies:
+      - supports-color
+    dev: false
+
   /micromatch@4.0.5:
     resolution: {integrity: sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==}
     engines: {node: '>=8.6'}
@@ -10792,8 +11744,8 @@ packages:
   /minimist@1.2.8:
     resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==}
 
-  /minipass@6.0.2:
-    resolution: {integrity: sha512-MzWSV5nYVT7mVyWCwn2o7JH13w2TBRmmSqSRCKzTw+lmft9X4z+3wjvs06Tzijo5z4W/kahUCDpRXTF+ZrmF/w==}
+  /minipass@7.0.4:
+    resolution: {integrity: sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==}
     engines: {node: '>=16 || 14 >=14.17'}
     dev: false
 
@@ -10811,45 +11763,37 @@ packages:
       minimist: 1.2.8
     dev: false
 
-  /mkdist@1.2.0(typescript@5.2.2):
-    resolution: {integrity: sha512-UTqu/bXmIk/+VKNVgufAeMyjUcNy1dn9Bl7wL1zZlCKVrpDgj/VllmZBeh3ZCC/2HWqUrt6frNFTKt9TRZbNvQ==}
+  /mkdist@1.3.0(typescript@5.2.2):
+    resolution: {integrity: sha512-ZQrUvcL7LkRdzMREpDyg9AT18N9Tl5jc2qeKAUeEw0KGsgykbHbuRvysGAzTuGtwuSg0WQyNit5jh/k+Er3JEg==}
     hasBin: true
     peerDependencies:
-      sass: ^1.60.0
-      typescript: '>=4.9.5'
+      sass: ^1.63.6
+      typescript: '>=5.1.6'
     peerDependenciesMeta:
       sass:
         optional: true
       typescript:
         optional: true
     dependencies:
+      citty: 0.1.4
       defu: 6.1.2
-      esbuild: 0.17.19
+      esbuild: 0.18.16
       fs-extra: 11.1.1
-      globby: 13.1.4
-      jiti: 1.19.3
+      globby: 13.2.2
+      jiti: 1.20.0
       mlly: 1.4.2
       mri: 1.2.0
       pathe: 1.1.1
       typescript: 5.2.2
     dev: true
 
-  /mlly@1.3.0:
-    resolution: {integrity: sha512-HT5mcgIQKkOrZecOjOX3DJorTikWXwsBfpcr/MGBkhfWcjiqvnaL/9ppxvIUXfjT6xt4DVIAsN9fMUz1ev4bIw==}
-    dependencies:
-      acorn: 8.10.0
-      pathe: 1.1.1
-      pkg-types: 1.0.3
-      ufo: 1.3.0
-    dev: true
-
   /mlly@1.4.2:
     resolution: {integrity: sha512-i/Ykufi2t1EZ6NaPLdfnZk2AX8cs0d+mTzVKuPfqPKPatxLApaBoxJQ9x1/uckXtrS/U5oisPMDkNs0yQTaBRg==}
     dependencies:
       acorn: 8.10.0
       pathe: 1.1.1
       pkg-types: 1.0.3
-      ufo: 1.3.0
+      ufo: 1.3.1
 
   /mnemonist@0.39.5:
     resolution: {integrity: sha512-FPUtkhtJ0efmEFGpU14x7jGbTB+s18LrzRL2KgoWz9YvcY3cPomz8tih01GbHwnGk/OmkOKfqd/RAQoc8Lm7DQ==}
@@ -10857,8 +11801,8 @@ packages:
       obliterator: 2.0.4
     dev: false
 
-  /monaco-editor@0.40.0:
-    resolution: {integrity: sha512-1wymccLEuFSMBvCk/jT1YDW/GuxMLYwnFwF9CDyYCxoTw2Pt379J3FUhwy9c43j51JdcxVPjwk0jm0EVDsBS2g==}
+  /monaco-editor@0.43.0:
+    resolution: {integrity: sha512-cnoqwQi/9fml2Szamv1XbSJieGJ1Dc8tENVMD26Kcfl7xGQWp7OBKMjlwKVGYFJ3/AXJjSOGvcqK7Ry/j9BM1Q==}
     dev: false
 
   /mongodb-connection-string-url@2.6.0:
@@ -10889,7 +11833,7 @@ packages:
       snappy:
         optional: true
     dependencies:
-      bson: 5.4.0
+      bson: 5.5.0
       mongodb-connection-string-url: 2.6.0
       socks: 2.7.1
     optionalDependencies:
@@ -10957,7 +11901,7 @@ packages:
     dependencies:
       debug: 3.2.7
       iconv-lite: 0.4.24
-      sax: 1.2.4
+      sax: 1.3.0
     transitivePeerDependencies:
       - supports-color
 
@@ -10980,7 +11924,7 @@ packages:
   /nlcst-to-string@3.1.1:
     resolution: {integrity: sha512-63mVyqaqt0cmn2VcI2aH6kxe1rLAmSROqHMA0i4qqg1tidkfExgpb0FGMikMCn86mw5dFtBtEANfmSSK7TjNHw==}
     dependencies:
-      '@types/nlcst': 1.0.0
+      '@types/nlcst': 1.0.2
 
   /node-abi@3.47.0:
     resolution: {integrity: sha512-2s6B2CWZM//kPgwnuI0KrYwNjfdByE25zvAaEpq9IH4zcNsarH8Ihu/UuX6XMPEogDAxkuUFeZn60pXNHAqn3A==}
@@ -10999,8 +11943,8 @@ packages:
   /node-fetch-native@1.4.0:
     resolution: {integrity: sha512-F5kfEj95kX8tkDhUCYdV8dg3/8Olx/94zB8+ZNthFs6Bz31UpUi8Xh40TN3thLwXgrwXry1pEg9lJ++tLWTcqA==}
 
-  /node-fetch@2.6.12:
-    resolution: {integrity: sha512-C/fGU2E8ToujUivIO0H+tpQ6HWo4eEmchoPIoXtxCrVghxdKq+QOHqEZW7tuP3KlV3bC8FRMO5nMCC7Zm1VP6g==}
+  /node-fetch@2.7.0:
+    resolution: {integrity: sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==}
     engines: {node: 4.x || >=6.0.0}
     peerDependencies:
       encoding: ^0.1.0
@@ -11011,9 +11955,18 @@ packages:
       whatwg-url: 5.0.0
     dev: false
 
-  /node-mocks-http@1.12.2:
-    resolution: {integrity: sha512-xhWwC0dh35R9rf0j3bRZXuISXdHxxtMx0ywZQBwjrg3yl7KpRETzogfeCamUIjltpn0Fxvs/ZhGJul1vPLrdJQ==}
-    engines: {node: '>=0.6'}
+  /node-fetch@3.3.2:
+    resolution: {integrity: sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==}
+    engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
+    dependencies:
+      data-uri-to-buffer: 4.0.1
+      fetch-blob: 3.2.0
+      formdata-polyfill: 4.0.10
+    dev: false
+
+  /node-mocks-http@1.13.0:
+    resolution: {integrity: sha512-lArD6sJMPJ53WF50GX0nJ89B1nkV1TdMvNwq8WXXFrUXF80ujSyye1T30mgiHh4h2It0/svpF3C4kZ2OAONVlg==}
+    engines: {node: '>=14'}
     dependencies:
       accepts: 1.3.8
       content-disposition: 0.5.4
@@ -11047,8 +12000,8 @@ packages:
     resolution: {integrity: sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==}
     dependencies:
       hosted-git-info: 2.8.9
-      resolve: 1.22.4
-      semver: 5.7.1
+      resolve: 1.22.6
+      semver: 5.7.2
       validate-npm-package-license: 3.0.4
 
   /normalize-path@3.0.0:
@@ -11091,7 +12044,7 @@ packages:
     engines: {node: '>= 0.4'}
     dependencies:
       call-bind: 1.0.2
-      define-properties: 1.2.0
+      define-properties: 1.2.1
       has-symbols: 1.0.3
       object-keys: 1.1.1
     dev: true
@@ -11110,13 +12063,13 @@ packages:
       isobject: 3.0.1
     dev: false
 
-  /object.values@1.1.6:
-    resolution: {integrity: sha512-FVVTkD1vENCsAcwNs9k6jea2uHC/X0+JcjG8YA60FN5CMaJmG95wT9jek/xX9nornqGRrBkKtzuAu2wuHpKqvw==}
+  /object.values@1.1.7:
+    resolution: {integrity: sha512-aU6xnDFYT3x17e/f0IiiwlGPTy2jzMySGfUB4fq6z7CV8l85CWHDk5ErhyhpfDHhrOMwGFhSQkhMGHaIotA6Ng==}
     engines: {node: '>= 0.4'}
     dependencies:
       call-bind: 1.0.2
-      define-properties: 1.2.0
-      es-abstract: 1.21.2
+      define-properties: 1.2.1
+      es-abstract: 1.22.2
     dev: true
 
   /obliterator@2.0.4:
@@ -11127,14 +12080,14 @@ packages:
     resolution: {integrity: sha512-kcFJmUreomSGA//1KfH7Ci+Xh8XO8yH/GbtTm6R0gB+JyIgjw5qL4DupMSzeTsvByxIBhoXE2PM5ZRXeJa1dDw==}
     engines: {node: '>= 18'}
     dependencies:
-      '@octokit/app': 14.0.0
-      '@octokit/core': 5.0.0
+      '@octokit/app': 14.0.1
+      '@octokit/core': 5.0.1
       '@octokit/oauth-app': 6.0.0
-      '@octokit/plugin-paginate-rest': 8.0.0(@octokit/core@5.0.0)
-      '@octokit/plugin-rest-endpoint-methods': 9.0.0(@octokit/core@5.0.0)
-      '@octokit/plugin-retry': 6.0.0(@octokit/core@5.0.0)
-      '@octokit/plugin-throttling': 7.0.0(@octokit/core@5.0.0)
-      '@octokit/request-error': 5.0.0
+      '@octokit/plugin-paginate-rest': 8.0.0(@octokit/core@5.0.1)
+      '@octokit/plugin-rest-endpoint-methods': 9.0.0(@octokit/core@5.0.1)
+      '@octokit/plugin-retry': 6.0.1(@octokit/core@5.0.1)
+      '@octokit/plugin-throttling': 7.0.0(@octokit/core@5.0.1)
+      '@octokit/request-error': 5.0.1
       '@octokit/types': 11.1.0
     dev: false
 
@@ -11143,10 +12096,11 @@ packages:
     dependencies:
       destr: 2.0.1
       node-fetch-native: 1.4.0
-      ufo: 1.3.0
+      ufo: 1.3.1
 
-  /on-exit-leak-free@2.1.0:
-    resolution: {integrity: sha512-VuCaZZAjReZ3vUwgOB8LxAosIurDiAW0s13rI1YwmaP++jvcxP77AWoQvenZebpCA2m8WC1/EosPYPMjnRAp/w==}
+  /on-exit-leak-free@2.1.2:
+    resolution: {integrity: sha512-0eJJY6hXLGf1udHwfNftBqH+g73EU4B504nZeKpz1sYRKafAghwxEJunB2O7rDZkL4PGfsMVnTXZ2EjibbqcsA==}
+    engines: {node: '>=14.0.0'}
     dev: false
 
   /on-finished@2.4.1:
@@ -11179,8 +12133,8 @@ packages:
     dependencies:
       chardet: 1.6.0
       cheerio: 1.0.0-rc.12
-      undici: 5.22.1
-      validator: 13.9.0
+      undici: 5.25.4
+      validator: 13.11.0
     dev: false
 
   /open@9.1.0:
@@ -11196,14 +12150,14 @@ packages:
     resolution: {integrity: sha512-UHv70gIw20pxu9tiUueE9iS+4U4eTGiTgQr+zlJ5aX4oj6LUUp+7mBn0xAqilawftwUB/biohPth2vcZFmoNYw==}
     hasBin: true
     dependencies:
-      '@types/node': 18.17.5
-      '@types/node-fetch': 2.6.4
+      '@types/node': 18.18.4
+      '@types/node-fetch': 2.6.6
       abort-controller: 3.0.0
       agentkeepalive: 4.5.0
       digest-fetch: 1.3.0
       form-data-encoder: 1.7.2
       formdata-node: 4.4.1
-      node-fetch: 2.6.12
+      node-fetch: 2.7.0
     transitivePeerDependencies:
       - encoding
     dev: false
@@ -11231,7 +12185,7 @@ packages:
       bl: 4.1.0
       chalk: 4.1.2
       cli-cursor: 3.1.0
-      cli-spinners: 2.9.0
+      cli-spinners: 2.9.1
       is-interactive: 1.0.0
       is-unicode-supported: 0.1.0
       log-symbols: 4.1.0
@@ -11245,7 +12199,7 @@ packages:
     dependencies:
       chalk: 5.3.0
       cli-cursor: 4.0.0
-      cli-spinners: 2.9.0
+      cli-spinners: 2.9.1
       is-interactive: 2.0.0
       is-unicode-supported: 1.3.0
       log-symbols: 5.1.0
@@ -11259,7 +12213,7 @@ packages:
     dependencies:
       chalk: 5.3.0
       cli-cursor: 4.0.0
-      cli-spinners: 2.9.0
+      cli-spinners: 2.9.1
       is-interactive: 2.0.0
       is-unicode-supported: 1.3.0
       log-symbols: 5.1.0
@@ -11274,7 +12228,7 @@ packages:
   /otpauth@9.1.4:
     resolution: {integrity: sha512-T6T0E1WlzwKWESq8K0Ja47u01XjmDmRY/AiUoMAc6xZI/OsTsD4cqBrfpt2WfJ29W5pRiWkuUuyHdNQl0/Ic+Q==}
     dependencies:
-      jssha: 3.3.0
+      jssha: 3.3.1
     dev: false
 
   /p-limit@2.3.0:
@@ -11323,6 +12277,19 @@ packages:
       callsites: 3.1.0
     dev: true
 
+  /parse-entities@4.0.1:
+    resolution: {integrity: sha512-SWzvYcSJh4d/SGLIOQfZ/CoNv6BTlI6YEQ7Nj82oDVnRpwe/Z/F1EMx42x3JAOwGBlCjeCH0BRJQbQ/opHL17w==}
+    dependencies:
+      '@types/unist': 2.0.8
+      character-entities: 2.0.2
+      character-entities-legacy: 3.0.0
+      character-reference-invalid: 2.0.1
+      decode-named-character-reference: 1.0.2
+      is-alphanumerical: 2.0.1
+      is-decimal: 2.0.1
+      is-hexadecimal: 2.0.1
+    dev: false
+
   /parse-json@5.2.0:
     resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==}
     engines: {node: '>=8'}
@@ -11397,8 +12364,8 @@ packages:
     resolution: {integrity: sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ==}
     engines: {node: '>=16 || 14 >=14.17'}
     dependencies:
-      lru-cache: 9.1.2
-      minipass: 6.0.2
+      lru-cache: 10.0.1
+      minipass: 7.0.4
     dev: false
 
   /path-to-regexp@6.2.1:
@@ -11427,6 +12394,14 @@ packages:
   /perfect-debounce@1.0.0:
     resolution: {integrity: sha512-xCy9V055GLEqoFaHoC1SoLIaLmWctgCUaBaWxDZ7/Zx4CTyX7cJQLJOok/orfjZAh9kEYpjJa4d0KcJmCbctZA==}
 
+  /periscopic@3.1.0:
+    resolution: {integrity: sha512-vKiQ8RRtkl9P+r/+oefh25C3fhybptkHKCZSPlcXiJux2tJF55GnEj3BVn4A5gKfq9NWWXXrxkHBwVPUfH0opw==}
+    dependencies:
+      '@types/estree': 1.0.2
+      estree-walker: 3.0.3
+      is-reference: 3.0.2
+    dev: false
+
   /picocolors@1.0.0:
     resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==}
 
@@ -11443,32 +12418,32 @@ packages:
     resolution: {integrity: sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==}
     engines: {node: '>=6'}
 
-  /pino-abstract-transport@1.0.0:
-    resolution: {integrity: sha512-c7vo5OpW4wIS42hUVcT5REsL8ZljsUfBjqV/e2sFxmFEFZiq1XLUp5EYLtuDH6PEHq9W1egWqRbnLUP5FuZmOA==}
+  /pino-abstract-transport@1.1.0:
+    resolution: {integrity: sha512-lsleG3/2a/JIWUtf9Q5gUNErBqwIu1tUKTT3dUzaf5DySw9ra1wcqKjJjLX1VTY64Wk1eEOYsVGSaGfCK85ekA==}
     dependencies:
-      readable-stream: 4.4.0
+      readable-stream: 4.4.2
       split2: 4.2.0
     dev: false
 
-  /pino-std-serializers@6.2.1:
-    resolution: {integrity: sha512-wHuWB+CvSVb2XqXM0W/WOYUkVSPbiJb9S5fNB7TBhd8s892Xq910bRxwHtC4l71hgztObTjXL6ZheZXFjhDrDQ==}
+  /pino-std-serializers@6.2.2:
+    resolution: {integrity: sha512-cHjPPsE+vhj/tnhCy/wiMh3M3z3h/j15zHQX+S9GkTBgqJuTuJzYJ4gUyACLhDaJ7kk9ba9iRDmbH2tJU03OiA==}
     dev: false
 
-  /pino@8.14.1:
-    resolution: {integrity: sha512-8LYNv7BKWXSfS+k6oEc6occy5La+q2sPwU3q2ljTX5AZk7v+5kND2o5W794FyRaqha6DJajmkNRsWtPpFyMUdw==}
+  /pino@8.15.6:
+    resolution: {integrity: sha512-GuxHr61R0ZFD1npu58tB3a3FSVjuy21OwN/haw4OuKiZBL63Pg11Y51WWeD52RENS2mjwPZOwt+2OQOSkck6kQ==}
     hasBin: true
     dependencies:
       atomic-sleep: 1.0.0
-      fast-redact: 3.2.0
-      on-exit-leak-free: 2.1.0
-      pino-abstract-transport: 1.0.0
-      pino-std-serializers: 6.2.1
+      fast-redact: 3.3.0
+      on-exit-leak-free: 2.1.2
+      pino-abstract-transport: 1.1.0
+      pino-std-serializers: 6.2.2
       process-warning: 2.2.0
       quick-format-unescaped: 4.0.4
       real-require: 0.2.0
       safe-stable-stringify: 2.4.3
-      sonic-boom: 3.3.0
-      thread-stream: 2.3.0
+      sonic-boom: 3.6.1
+      thread-stream: 2.4.1
     dev: false
 
   /pkg-dir@4.2.0:
@@ -11514,7 +12489,7 @@ packages:
       postcss: 8.4.21
       postcss-value-parser: 4.2.0
       read-cache: 1.0.0
-      resolve: 1.22.4
+      resolve: 1.22.6
     dev: false
 
   /postcss-js@4.0.1(postcss@8.4.21):
@@ -11575,17 +12550,8 @@ packages:
       source-map-js: 1.0.2
     dev: false
 
-  /postcss@8.4.26:
-    resolution: {integrity: sha512-jrXHFF8iTloAenySjM/ob3gSj7pCu0Ji49hnjqzsgSRa50hkWCKD0HQ+gMNJkW38jBI68MpAAg7ZWwHwX8NMMw==}
-    engines: {node: ^10 || ^12 || >=14}
-    dependencies:
-      nanoid: 3.3.6
-      picocolors: 1.0.0
-      source-map-js: 1.0.2
-    dev: true
-
-  /postcss@8.4.29:
-    resolution: {integrity: sha512-cbI+jaqIeu/VGqXEarWkRCCffhjgXc0qjBtXpqJhTBohMUjUQnbBr0xqX3vEKudc4iviTewcJo5ajcec5+wdJw==}
+  /postcss@8.4.31:
+    resolution: {integrity: sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==}
     engines: {node: ^10 || ^12 || >=14}
     dependencies:
       nanoid: 3.3.6
@@ -11610,16 +12576,6 @@ packages:
       tar-fs: 2.1.1
       tunnel-agent: 0.6.0
 
-  /preferred-pm@3.0.3:
-    resolution: {integrity: sha512-+wZgbxNES/KlJs9q40F/1sfOd/j7f1O9JaHcW5Dsn3aUUOZg3L2bjpVUcKV2jvtElYfoTuQiNeMfQJ4kwUAhCQ==}
-    engines: {node: '>=10'}
-    dependencies:
-      find-up: 5.0.0
-      find-yarn-workspace-root2: 1.2.16
-      path-exists: 4.0.0
-      which-pm: 2.0.0
-    dev: true
-
   /preferred-pm@3.1.2:
     resolution: {integrity: sha512-nk7dKrcW8hfCZ4H6klWcdRknBOXWzNQByJ0oJyX97BOupsYD+FzLS4hflgEu/uPUEHZCuRfMxzCBsuWd7OzT8Q==}
     engines: {node: '>=10'}
@@ -11645,9 +12601,9 @@ packages:
     resolution: {integrity: sha512-rl2hJ4Kty/aEfGjk3i4JS+bpng9MjgvwqLRNzeb9NqYhqKoWNwOR39cIJXFjU1vR3zYOPnwWNRMelKb0orunYA==}
     engines: {node: ^14.15.0 || >=16.0.0, pnpm: '>=7.14.0'}
     dependencies:
-      '@astrojs/compiler': 1.6.2
+      '@astrojs/compiler': 1.8.2
       prettier: 3.0.2
-      sass-formatter: 0.7.6
+      sass-formatter: 0.7.8
     dev: true
 
   /prettier-plugin-astro@0.9.1:
@@ -11656,7 +12612,7 @@ packages:
     dependencies:
       '@astrojs/compiler': 1.8.2
       prettier: 2.8.8
-      sass-formatter: 0.7.6
+      sass-formatter: 0.7.8
       synckit: 0.8.5
 
   /prettier@2.8.8:
@@ -11674,8 +12630,8 @@ packages:
     engines: {node: '>=6'}
     dev: false
 
-  /pretty-bytes@6.1.0:
-    resolution: {integrity: sha512-Rk753HI8f4uivXi4ZCIYdhmG1V+WKzvRMg/X+M42a6t7D07RcmopXJMDNk6N++7Bl75URRGsb40ruvg7Hcp2wQ==}
+  /pretty-bytes@6.1.1:
+    resolution: {integrity: sha512-mQUvGU6aUFQ+rNvTIAcZuWGRT9a6f6Yrg9bHs4ImKF+HZCEK+plBvnAZYSIQztknZF2qnzNtr6F8s0+IuptdlQ==}
     engines: {node: ^14.13.1 || >=16.0.0}
     dev: true
 
@@ -11721,13 +12677,13 @@ packages:
       kleur: 3.0.3
       sisteransi: 1.0.5
 
-  /property-information@6.2.0:
-    resolution: {integrity: sha512-kma4U7AFCTwpqq5twzC1YVIDXSqg6qQK6JN0smOw8fgRy1OkMi0CYSzFmsy6dnqSenamAtj0CyXMUJ1Mf6oROg==}
+  /property-information@6.3.0:
+    resolution: {integrity: sha512-gVNZ74nqhRMiIUYWGQdosYetaKc83x8oT41a0LlV3AAFCAZwCpg4vmGkq8t34+cUhp3cnM4XDiU/7xlgK7HGrg==}
 
   /prosemirror-changeset@2.2.1:
     resolution: {integrity: sha512-J7msc6wbxB4ekDFj+n9gTW/jav/p53kdlivvuppHsrZXCaQdVgRghoZbSS3kwrRyAstRVQ4/+u5k7YfLgkkQvQ==}
     dependencies:
-      prosemirror-transform: 1.7.3
+      prosemirror-transform: 1.8.0
     dev: false
 
   /prosemirror-collab@1.3.1:
@@ -11739,34 +12695,34 @@ packages:
   /prosemirror-commands@1.5.2:
     resolution: {integrity: sha512-hgLcPaakxH8tu6YvVAaILV2tXYsW3rAdDR8WNkeKGcgeMVQg3/TMhPdVoh7iAmfgVjZGtcOSjKiQaoeKjzd2mQ==}
     dependencies:
-      prosemirror-model: 1.19.2
+      prosemirror-model: 1.19.3
       prosemirror-state: 1.4.3
-      prosemirror-transform: 1.7.3
+      prosemirror-transform: 1.8.0
     dev: false
 
   /prosemirror-dropcursor@1.8.1:
     resolution: {integrity: sha512-M30WJdJZLyXHi3N8vxN6Zh5O8ZBbQCz0gURTfPmTIBNQ5pxrdU7A58QkNqfa98YEjSAL1HUyyU34f6Pm5xBSGw==}
     dependencies:
       prosemirror-state: 1.4.3
-      prosemirror-transform: 1.7.3
-      prosemirror-view: 1.31.4
+      prosemirror-transform: 1.8.0
+      prosemirror-view: 1.32.0
     dev: false
 
   /prosemirror-gapcursor@1.3.2:
     resolution: {integrity: sha512-wtjswVBd2vaQRrnYZaBCbyDqr232Ed4p2QPtRIUK5FuqHYKGWkEwl08oQM4Tw7DOR0FsasARV5uJFvMZWxdNxQ==}
     dependencies:
       prosemirror-keymap: 1.2.2
-      prosemirror-model: 1.19.2
+      prosemirror-model: 1.19.3
       prosemirror-state: 1.4.3
-      prosemirror-view: 1.31.4
+      prosemirror-view: 1.32.0
     dev: false
 
   /prosemirror-history@1.3.2:
     resolution: {integrity: sha512-/zm0XoU/N/+u7i5zepjmZAEnpvjDtzoPWW6VmKptcAnPadN/SStsBjMImdCEbb3seiNTpveziPTIrXQbHLtU1g==}
     dependencies:
       prosemirror-state: 1.4.3
-      prosemirror-transform: 1.7.3
-      prosemirror-view: 1.31.4
+      prosemirror-transform: 1.8.0
+      prosemirror-view: 1.32.0
       rope-sequence: 1.3.4
     dev: false
 
@@ -11774,7 +12730,7 @@ packages:
     resolution: {integrity: sha512-3LrWJX1+ULRh5SZvbIQlwZafOXqp1XuV21MGBu/i5xsztd+9VD15x6OtN6mdqSFI7/8Y77gYUbQ6vwwJ4mr6QQ==}
     dependencies:
       prosemirror-state: 1.4.3
-      prosemirror-transform: 1.7.3
+      prosemirror-transform: 1.8.0
     dev: false
 
   /prosemirror-keymap@1.2.2:
@@ -11784,15 +12740,15 @@ packages:
       w3c-keyname: 2.2.8
     dev: false
 
-  /prosemirror-markdown@1.11.0:
-    resolution: {integrity: sha512-yP9mZqPRstjZhhf3yykCQNE3AijxARrHe4e7esV9A+gp4cnGOH4QvrKYPpXLHspNWyvJJ+0URH+iIvV5qP1I2Q==}
+  /prosemirror-markdown@1.11.2:
+    resolution: {integrity: sha512-Eu5g4WPiCdqDTGhdSsG9N6ZjACQRYrsAkrF9KYfdMaCmjIApH75aVncsWYOJvEk2i1B3i8jZppv3J/tnuHGiUQ==}
     dependencies:
-      markdown-it: 13.0.1
-      prosemirror-model: 1.19.2
+      markdown-it: 13.0.2
+      prosemirror-model: 1.19.3
     dev: false
 
-  /prosemirror-menu@1.2.2:
-    resolution: {integrity: sha512-437HIWTq4F9cTX+kPfqZWWm+luJm95Aut/mLUy+9OMrOml0bmWDS26ceC6SNfb2/S94et1sZ186vLO7pDHzxSw==}
+  /prosemirror-menu@1.2.4:
+    resolution: {integrity: sha512-S/bXlc0ODQup6aiBbWVsX/eM+xJgCTAfMq/nLqaO5ID/am4wS0tTCIkzwytmao7ypEtjj39i7YbJjAgO20mIqA==}
     dependencies:
       crelt: 1.0.6
       prosemirror-commands: 1.5.2
@@ -11800,8 +12756,8 @@ packages:
       prosemirror-state: 1.4.3
     dev: false
 
-  /prosemirror-model@1.19.2:
-    resolution: {integrity: sha512-RXl0Waiss4YtJAUY3NzKH0xkJmsZupCIccqcIFoLTIKFlKNbIvFDRl27/kQy1FP8iUAxrjRRfIVvOebnnXJgqQ==}
+  /prosemirror-model@1.19.3:
+    resolution: {integrity: sha512-tgSnwN7BS7/UM0sSARcW+IQryx2vODKX4MI7xpqY2X+iaepJdKBPc7I4aACIsDV/LTaTjt12Z56MhDr9LsyuZQ==}
     dependencies:
       orderedmap: 2.1.1
     dev: false
@@ -11809,65 +12765,62 @@ packages:
   /prosemirror-schema-basic@1.2.2:
     resolution: {integrity: sha512-/dT4JFEGyO7QnNTe9UaKUhjDXbTNkiWTq/N4VpKaF79bBjSExVV2NXmJpcM7z/gD7mbqNjxbmWW5nf1iNSSGnw==}
     dependencies:
-      prosemirror-model: 1.19.2
+      prosemirror-model: 1.19.3
     dev: false
 
   /prosemirror-schema-list@1.3.0:
     resolution: {integrity: sha512-Hz/7gM4skaaYfRPNgr421CU4GSwotmEwBVvJh5ltGiffUJwm7C8GfN/Bc6DR1EKEp5pDKhODmdXXyi9uIsZl5A==}
     dependencies:
-      prosemirror-model: 1.19.2
+      prosemirror-model: 1.19.3
       prosemirror-state: 1.4.3
-      prosemirror-transform: 1.7.3
+      prosemirror-transform: 1.8.0
     dev: false
 
   /prosemirror-state@1.4.3:
     resolution: {integrity: sha512-goFKORVbvPuAQaXhpbemJFRKJ2aixr+AZMGiquiqKxaucC6hlpHNZHWgz5R7dS4roHiwq9vDctE//CZ++o0W1Q==}
     dependencies:
-      prosemirror-model: 1.19.2
-      prosemirror-transform: 1.7.3
-      prosemirror-view: 1.31.4
+      prosemirror-model: 1.19.3
+      prosemirror-transform: 1.8.0
+      prosemirror-view: 1.32.0
     dev: false
 
-  /prosemirror-tables@1.3.3:
-    resolution: {integrity: sha512-t10hbu4sNDInic3AQYd8ouPN457zVJIhVDqSdqgsVXNoa1watYXBxqNSVrNQoGOFG4Ivreyp3hQE3KG1f9bSpw==}
+  /prosemirror-tables@1.3.4:
+    resolution: {integrity: sha512-z6uLSQ1BLC3rgbGwZmpfb+xkdvD7W/UOsURDfognZFYaTtc0gsk7u/t71Yijp2eLflVpffMk6X0u0+u+MMDvIw==}
     dependencies:
       prosemirror-keymap: 1.2.2
-      prosemirror-model: 1.19.2
+      prosemirror-model: 1.19.3
       prosemirror-state: 1.4.3
-      prosemirror-transform: 1.7.3
-      prosemirror-view: 1.31.4
+      prosemirror-transform: 1.8.0
+      prosemirror-view: 1.32.0
     dev: false
 
-  /prosemirror-trailing-node@2.0.4(prosemirror-model@1.19.2)(prosemirror-state@1.4.3)(prosemirror-view@1.31.4):
-    resolution: {integrity: sha512-0Yl9w7IdHkaCdqR+NE3FOucePME4OmiGcybnF1iasarEILP5U8+4xTnl53yafULjmwcg1SrSG65Hg7Zk2H2v3g==}
+  /prosemirror-trailing-node@2.0.7(prosemirror-model@1.19.3)(prosemirror-state@1.4.3)(prosemirror-view@1.32.0):
+    resolution: {integrity: sha512-8zcZORYj/8WEwsGo6yVCRXFMOfBo0Ub3hCUvmoWIZYfMP26WqENU0mpEP27w7mt8buZWuGrydBewr0tOArPb1Q==}
     peerDependencies:
       prosemirror-model: ^1.19.0
       prosemirror-state: ^1.4.2
-      prosemirror-view: ^1.30.2
+      prosemirror-view: ^1.31.2
     dependencies:
-      '@babel/runtime': 7.22.5
-      '@remirror/core-constants': 2.0.1
-      '@remirror/core-helpers': 2.0.3
+      '@remirror/core-constants': 2.0.2
+      '@remirror/core-helpers': 3.0.0
       escape-string-regexp: 4.0.0
-      prosemirror-model: 1.19.2
+      prosemirror-model: 1.19.3
       prosemirror-state: 1.4.3
-      prosemirror-view: 1.31.4
-    transitivePeerDependencies:
-      - supports-color
+      prosemirror-view: 1.32.0
     dev: false
 
-  /prosemirror-transform@1.7.3:
-    resolution: {integrity: sha512-qDapyx5lqYfxVeUWEw0xTGgeP2S8346QtE7DxkalsXlX89lpzkY6GZfulgfHyk1n4tf74sZ7CcXgcaCcGjsUtA==}
+  /prosemirror-transform@1.8.0:
+    resolution: {integrity: sha512-BaSBsIMv52F1BVVMvOmp1yzD3u65uC3HTzCBQV1WDPqJRQ2LuHKcyfn0jwqodo8sR9vVzMzZyI+Dal5W9E6a9A==}
     dependencies:
-      prosemirror-model: 1.19.2
+      prosemirror-model: 1.19.3
     dev: false
 
-  /prosemirror-view@1.31.4:
-    resolution: {integrity: sha512-nJzH2LpYbonSTYFqQ1BUdEhbd1WPN/rp/K9T9qxBEYpgg3jK3BvEUCR45Ymc9IHpO0m3nBJwPm19RBxZdoBVuw==}
+  /prosemirror-view@1.32.0:
+    resolution: {integrity: sha512-HwW7IWgca6ehiW2PA48H/8yl0TakA0Ms5LgN5Krc97oar7GfjIKE/NocUsLe74Jq4mwyWKUNoBljE8WkXKZwng==}
     dependencies:
-      prosemirror-model: 1.19.2
+      prosemirror-model: 1.19.3
       prosemirror-state: 1.4.3
-      prosemirror-transform: 1.7.3
+      prosemirror-transform: 1.8.0
     dev: false
 
   /proto-list@1.2.4:
@@ -11918,8 +12871,8 @@ packages:
     engines: {node: '>=10'}
     dev: false
 
-  /radix3@1.0.1:
-    resolution: {integrity: sha512-y+AcwZ3HcUIGc9zGsNVf5+BY/LxL+z+4h4J3/pp8jxSmy1STaCocPS3qrj4tA5ehUSzqtqK+0Aygvz/r/8vy4g==}
+  /radix3@1.1.0:
+    resolution: {integrity: sha512-pNsHDxbGORSvuSScqNJ+3Km6QAVqk8CfsCBIEoDgpqLrkD2f3QM4I7d1ozJJ172OmIcoUcerZaNWqtLkRXTV3A==}
     dev: false
 
   /range-parser@1.2.1:
@@ -12010,7 +12963,7 @@ packages:
     resolution: {integrity: sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==}
     engines: {node: '>=8'}
     dependencies:
-      '@types/normalize-package-data': 2.4.1
+      '@types/normalize-package-data': 2.4.2
       normalize-package-data: 2.5.0
       parse-json: 5.2.0
       type-fest: 0.6.0
@@ -12045,14 +12998,15 @@ packages:
       string_decoder: 1.3.0
       util-deprecate: 1.0.2
 
-  /readable-stream@4.4.0:
-    resolution: {integrity: sha512-kDMOq0qLtxV9f/SQv522h8cxZBqNZXuXNyjyezmfAAuribMyVXziljpQ/uQhfE1XLg2/TLTW2DsnoE4VAi/krg==}
+  /readable-stream@4.4.2:
+    resolution: {integrity: sha512-Lk/fICSyIhodxy1IDK2HazkeGjSmezAWX2egdtJnYhtzKEsBPJowlI6F6LPb5tqIQILrMbx22S5o3GuJavPusA==}
     engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
     dependencies:
       abort-controller: 3.0.0
       buffer: 6.0.3
       events: 3.3.0
       process: 0.11.10
+      string_decoder: 1.3.0
     dev: false
 
   /readable-web-to-node-stream@3.0.2:
@@ -12077,7 +13031,7 @@ packages:
     resolution: {integrity: sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==}
     engines: {node: '>= 0.10'}
     dependencies:
-      resolve: 1.22.4
+      resolve: 1.22.6
     dev: false
 
   /redis-commands@1.7.0:
@@ -12103,8 +13057,8 @@ packages:
       bluebird: 3.7.2
     dev: false
 
-  /regenerator-runtime@0.13.11:
-    resolution: {integrity: sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==}
+  /regenerator-runtime@0.14.0:
+    resolution: {integrity: sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA==}
     dev: false
 
   /regexp-tree@0.1.27:
@@ -12112,13 +13066,13 @@ packages:
     hasBin: true
     dev: true
 
-  /regexp.prototype.flags@1.5.0:
-    resolution: {integrity: sha512-0SutC3pNudRKgquxGoRGIz946MZVHqbNfPjBdxeOhBrdgDKlRoXmYLQN9xRbrR09ZXWeGAdPuif7egofn6v5LA==}
+  /regexp.prototype.flags@1.5.1:
+    resolution: {integrity: sha512-sy6TXMN+hnP/wMy+ISxg3krXx7BAtWVO4UouuCN/ziM9UEne0euamVNafDfvC83bRNr95y0V5iijeDQFUNpvrg==}
     engines: {node: '>= 0.4'}
     dependencies:
       call-bind: 1.0.2
-      define-properties: 1.2.0
-      functions-have-names: 1.2.3
+      define-properties: 1.2.1
+      set-function-name: 2.0.1
     dev: true
 
   /regexpp@3.2.0:
@@ -12131,10 +13085,10 @@ packages:
     engines: {node: '>=0.1.14'}
     dev: true
 
-  /rehype-parse@8.0.4:
-    resolution: {integrity: sha512-MJJKONunHjoTh4kc3dsM1v3C9kGrrxvA3U8PxZlP2SjH8RNUSrb+lF7Y0KVaUDnGH2QZ5vAn7ulkiajM9ifuqg==}
+  /rehype-parse@8.0.5:
+    resolution: {integrity: sha512-Ds3RglaY/+clEX2U2mHflt7NlMA72KspZ0JLUJgBBLpRddBcEw3H8uYZQliQriku22NZpYMfjDdSgHcjxue24A==}
     dependencies:
-      '@types/hast': 2.3.4
+      '@types/hast': 2.3.6
       hast-util-from-parse5: 7.1.2
       parse5: 6.0.1
       unified: 10.1.2
@@ -12142,49 +13096,69 @@ packages:
   /rehype-raw@6.1.1:
     resolution: {integrity: sha512-d6AKtisSRtDRX4aSPsJGTfnzrX2ZkHQLE5kiUuGOeEoLpbEulFF4hj0mLPbsa+7vmguDKOVVEQdHKDSwoaIDsQ==}
     dependencies:
-      '@types/hast': 2.3.4
+      '@types/hast': 2.3.6
       hast-util-raw: 7.2.3
       unified: 10.1.2
 
   /rehype-stringify@9.0.4:
     resolution: {integrity: sha512-Uk5xu1YKdqobe5XpSskwPvo1XeHUUucWEQSl8hTrXt5selvca1e8K1EZ37E6YoZ4BT8BCqCdVfQW7OfHfthtVQ==}
     dependencies:
-      '@types/hast': 2.3.4
+      '@types/hast': 2.3.6
       hast-util-to-html: 8.0.4
       unified: 10.1.2
 
   /rehype@12.0.1:
     resolution: {integrity: sha512-ey6kAqwLM3X6QnMDILJthGvG1m1ULROS9NT4uG9IDCuv08SFyLlreSuvOa//DgEvbXx62DS6elGVqusWhRUbgw==}
     dependencies:
-      '@types/hast': 2.3.4
-      rehype-parse: 8.0.4
+      '@types/hast': 2.3.6
+      rehype-parse: 8.0.5
       rehype-stringify: 9.0.4
       unified: 10.1.2
 
   /remark-gfm@3.0.1:
     resolution: {integrity: sha512-lEFDoi2PICJyNrACFOfDD3JlLkuSbOa5Wd8EPt06HUdptv8Gn0bxYTdbU/XXQ3swAPkEaGxxPN9cbnMHvVu1Ig==}
     dependencies:
-      '@types/mdast': 3.0.11
+      '@types/mdast': 3.0.13
       mdast-util-gfm: 2.0.2
       micromark-extension-gfm: 2.0.3
       unified: 10.1.2
     transitivePeerDependencies:
       - supports-color
 
+  /remark-mdx@2.3.0:
+    resolution: {integrity: sha512-g53hMkpM0I98MU266IzDFMrTD980gNF3BJnkyFcmN+dD873mQeD5rdMO3Y2X+x8umQfbSE0PcoEDl7ledSA+2g==}
+    dependencies:
+      mdast-util-mdx: 2.0.1
+      micromark-extension-mdxjs: 1.0.1
+    transitivePeerDependencies:
+      - supports-color
+    dev: false
+
   /remark-parse@10.0.2:
     resolution: {integrity: sha512-3ydxgHa/ZQzG8LvC7jTXccARYDcRld3VfcgIIFs7bI6vbRSxJJmzgLEIIoYKyrfhaY+ujuWaf/PJiMZXoiCXgw==}
     dependencies:
-      '@types/mdast': 3.0.11
+      '@types/mdast': 3.0.13
       mdast-util-from-markdown: 1.3.1
       unified: 10.1.2
     transitivePeerDependencies:
       - supports-color
 
+  /remark-parse@11.0.0:
+    resolution: {integrity: sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA==}
+    dependencies:
+      '@types/mdast': 4.0.1
+      mdast-util-from-markdown: 2.0.0
+      micromark-util-types: 2.0.0
+      unified: 11.0.3
+    transitivePeerDependencies:
+      - supports-color
+    dev: false
+
   /remark-rehype@10.1.0:
     resolution: {integrity: sha512-EFmR5zppdBp0WQeDVZ/b66CWJipB2q2VLNFMabzDSGR66Z2fQii83G5gTBbgGEnEEA0QRussvrFHxk1HWGJskw==}
     dependencies:
-      '@types/hast': 2.3.4
-      '@types/mdast': 3.0.11
+      '@types/hast': 2.3.6
+      '@types/mdast': 3.0.13
       mdast-util-to-hast: 12.3.0
       unified: 10.1.2
 
@@ -12196,6 +13170,25 @@ packages:
       retext-smartypants: 5.2.0
       unist-util-visit: 4.1.2
 
+  /remark-stringify@11.0.0:
+    resolution: {integrity: sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw==}
+    dependencies:
+      '@types/mdast': 4.0.1
+      mdast-util-to-markdown: 2.1.0
+      unified: 11.0.3
+    dev: false
+
+  /remark@15.0.1:
+    resolution: {integrity: sha512-Eht5w30ruCXgFmxVUSlNWQ9iiimq07URKeFS3hNc8cUWy1llX4KDWfyEDZRycMc+znsN9Ux5/tJ/BFdgdOwA3A==}
+    dependencies:
+      '@types/mdast': 4.0.1
+      remark-parse: 11.0.0
+      remark-stringify: 11.0.0
+      unified: 11.0.3
+    transitivePeerDependencies:
+      - supports-color
+    dev: false
+
   /require-from-string@2.0.2:
     resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==}
     engines: {node: '>=0.10.0'}
@@ -12210,17 +13203,20 @@ packages:
     engines: {node: '>=4'}
     dev: true
 
-  /resolve@1.22.2:
-    resolution: {integrity: sha512-Sb+mjNHOULsBv818T40qSPeRiuWLyaGMa5ewydRLFimneixmVy2zdivRl+AF6jaYPC8ERxGDmFSiqui6SfPd+g==}
-    hasBin: true
+  /resolve-from@5.0.0:
+    resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==}
+    engines: {node: '>=8'}
+    dev: false
+
+  /resolve-pkg@2.0.0:
+    resolution: {integrity: sha512-+1lzwXehGCXSeryaISr6WujZzowloigEofRB+dj75y9RRa/obVcYgbHJd53tdYw8pvZj8GojXaaENws8Ktw/hQ==}
+    engines: {node: '>=8'}
     dependencies:
-      is-core-module: 2.12.1
-      path-parse: 1.0.7
-      supports-preserve-symlinks-flag: 1.0.0
-    dev: true
+      resolve-from: 5.0.0
+    dev: false
 
-  /resolve@1.22.4:
-    resolution: {integrity: sha512-PXNdCiPqDqeUou+w1C2eTQbNfxKSuMxqTCuvlmmMsk1NWHL5fRrhY6Pl0qEYYc6+QqGClco1Qj8XnjPego4wfg==}
+  /resolve@1.22.6:
+    resolution: {integrity: sha512-njhxM7mV12JfufShqGy3Rz8j11RPdLy4xi15UurGJeoHLfJpVXKdh3ueuOqbYUcDZnffr6X739JBo5LzyahEsw==}
     hasBin: true
     dependencies:
       is-core-module: 2.13.0
@@ -12250,7 +13246,7 @@ packages:
   /retext-latin@3.1.0:
     resolution: {integrity: sha512-5MrD1tuebzO8ppsja5eEu+ZbBeUNCjoEarn70tkXOS7Bdsdf6tNahsv2bY0Z8VooFF6cw7/6S+d3yI/TMlMVVQ==}
     dependencies:
-      '@types/nlcst': 1.0.0
+      '@types/nlcst': 1.0.2
       parse-latin: 5.0.1
       unherit: 3.0.1
       unified: 10.1.2
@@ -12258,7 +13254,7 @@ packages:
   /retext-smartypants@5.2.0:
     resolution: {integrity: sha512-Do8oM+SsjrbzT2UNIKgheP0hgUQTDDQYyZaIY3kfq0pdFzoPk+ZClYJ+OERNXveog4xf1pZL4PfRxNoVL7a/jw==}
     dependencies:
-      '@types/nlcst': 1.0.0
+      '@types/nlcst': 1.0.2
       nlcst-to-string: 3.1.1
       unified: 10.1.2
       unist-util-visit: 4.1.2
@@ -12266,14 +13262,14 @@ packages:
   /retext-stringify@3.1.0:
     resolution: {integrity: sha512-767TLOaoXFXyOnjx/EggXlb37ZD2u4P1n0GJqVdpipqACsQP+20W+BNpMYrlJkq7hxffnFk+jc6mAK9qrbuB8w==}
     dependencies:
-      '@types/nlcst': 1.0.0
+      '@types/nlcst': 1.0.2
       nlcst-to-string: 3.1.1
       unified: 10.1.2
 
   /retext@8.1.0:
     resolution: {integrity: sha512-N9/Kq7YTn6ZpzfiGW45WfEGJqFf1IM1q8OsRa1CGzIebCJBNCANDRmOrholiDRGKo/We7ofKR4SEvcGAWEMD3Q==}
     dependencies:
-      '@types/nlcst': 1.0.0
+      '@types/nlcst': 1.0.2
       retext-latin: 3.1.0
       retext-stringify: 3.1.0
       unified: 10.1.2
@@ -12300,33 +13296,26 @@ packages:
       glob: 7.2.3
     dev: true
 
-  /rollup-plugin-dts@5.3.0(rollup@3.26.2)(typescript@5.2.2):
-    resolution: {integrity: sha512-8FXp0ZkyZj1iU5klkIJYLjIq/YZSwBoERu33QBDxm/1yw5UU4txrEtcmMkrq+ZiKu3Q4qvPCNqc3ovX6rjqzbQ==}
-    engines: {node: '>=v14'}
+  /rollup-plugin-dts@5.3.1(rollup@3.29.4)(typescript@5.2.2):
+    resolution: {integrity: sha512-gusMi+Z4gY/JaEQeXnB0RUdU82h1kF0WYzCWgVmV4p3hWXqelaKuCvcJawfeg+EKn2T1Ie+YWF2OiN1/L8bTVg==}
+    engines: {node: '>=v14.21.3'}
     peerDependencies:
-      rollup: ^3.0.0
+      rollup: ^3.0
       typescript: ^4.1 || ^5.0
     dependencies:
-      magic-string: 0.30.3
-      rollup: 3.26.2
+      magic-string: 0.30.4
+      rollup: 3.29.4
       typescript: 5.2.2
     optionalDependencies:
       '@babel/code-frame': 7.22.13
     dev: true
 
-  /rollup@3.26.2:
-    resolution: {integrity: sha512-6umBIGVz93er97pMgQO08LuH3m6PUb3jlDUUGFsNJB6VgTCUaDFpupf5JfU30529m/UKOgmiX+uY6Sx8cOYpLA==}
+  /rollup@3.29.4:
+    resolution: {integrity: sha512-oWzmBZwvYrU0iJHtDmhsm662rC15FRXmcjCk1xD771dFDx5jJ02ufAQQTn0etB2emNk4J9EZg/yWKpsn9BWGRw==}
     engines: {node: '>=14.18.0', npm: '>=8.0.0'}
     hasBin: true
     optionalDependencies:
-      fsevents: 2.3.2
-
-  /rollup@3.29.0:
-    resolution: {integrity: sha512-nszM8DINnx1vSS+TpbWKMkxem0CDWk3cSit/WWCBVs9/JZ1I/XLwOsiUglYuYReaeWWSsW9kge5zE5NZtf/a4w==}
-    engines: {node: '>=14.18.0', npm: '>=8.0.0'}
-    hasBin: true
-    optionalDependencies:
-      fsevents: 2.3.2
+      fsevents: 2.3.3
 
   /rope-sequence@1.3.4:
     resolution: {integrity: sha512-UT5EDe2cu2E/6O4igUr5PSFs23nvvukicWHx6GnOPlHAiiYbzNuCRQCuiUdHJQcqKalLKlrYJnjY0ySGsXNQXQ==}
@@ -12356,6 +13345,16 @@ packages:
     dependencies:
       mri: 1.2.0
 
+  /safe-array-concat@1.0.1:
+    resolution: {integrity: sha512-6XbUAseYE2KtOuGueyeobCySj9L4+66Tn6KQMOPQJrAJEowYKW/YR/MGJZl7FdydUdaFu4LYyDZjxf4/Nmo23Q==}
+    engines: {node: '>=0.4'}
+    dependencies:
+      call-bind: 1.0.2
+      get-intrinsic: 1.2.1
+      has-symbols: 1.0.3
+      isarray: 2.0.5
+    dev: true
+
   /safe-buffer@5.1.2:
     resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==}
     dev: false
@@ -12394,13 +13393,12 @@ packages:
   /saslprep@1.0.3:
     resolution: {integrity: sha512-/MY/PEMbk2SuY5sScONwhUDsV2p77Znkb/q3nSVstq/yQzYJOH/Azh29p9oJLsl3LnQwSvZDKagDGBsBwSooag==}
     engines: {node: '>=6'}
-    requiresBuild: true
     dependencies:
       sparse-bitfield: 3.0.3
     dev: false
 
-  /sass-formatter@0.7.6:
-    resolution: {integrity: sha512-hXdxU6PCkiV3XAiSnX+XLqz2ohHoEnVUlrd8LEVMAI80uB1+OTScIkH9n6qQwImZpTye1r1WG1rbGUteHNhoHg==}
+  /sass-formatter@0.7.8:
+    resolution: {integrity: sha512-7fI2a8THglflhhYis7k06eUf92VQuJoXzEs2KRP0r1bluFxKFvLx0Ns7c478oYGM0fPfrr846ZRWVi2MAgHt9Q==}
     dependencies:
       suf-log: 2.5.3
 
@@ -12410,11 +13408,11 @@ packages:
     hasBin: true
     dependencies:
       chokidar: 3.5.3
-      immutable: 4.3.0
+      immutable: 4.3.4
       source-map-js: 1.0.2
 
-  /sax@1.2.4:
-    resolution: {integrity: sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==}
+  /sax@1.3.0:
+    resolution: {integrity: sha512-0s+oAmw9zLl1V1cS9BtZN7JAd0cW5e0QH4W3LWEK6a4LaLEA2OTpGYWDY+6XasBLtz6wkm3u1xRw95mRuJ59WA==}
 
   /scheduler@0.23.0:
     resolution: {integrity: sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==}
@@ -12453,15 +13451,10 @@ packages:
       parseley: 0.12.1
     dev: false
 
-  /semver@5.7.1:
-    resolution: {integrity: sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==}
+  /semver@5.7.2:
+    resolution: {integrity: sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==}
     hasBin: true
 
-  /semver@6.3.0:
-    resolution: {integrity: sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==}
-    hasBin: true
-    dev: true
-
   /semver@6.3.1:
     resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==}
     hasBin: true
@@ -12505,6 +13498,15 @@ packages:
     resolution: {integrity: sha512-RVnVQxTXuerk653XfuliOxBP81Sf0+qfQE73LIYKcyMYHG94AuH0kgrQpRDuTZnSmjpysHmzxJXKNfa6PjFhyQ==}
     dev: false
 
+  /set-function-name@2.0.1:
+    resolution: {integrity: sha512-tMNCiqYVkXIZgc2Hnoy2IvC/f8ezc5koaRFkCjrpWzGpCd3qbZXPzVy9MAZzK1ch/X0jvSkojys3oqJN0qCmdA==}
+    engines: {node: '>= 0.4'}
+    dependencies:
+      define-data-property: 1.1.0
+      functions-have-names: 1.2.3
+      has-property-descriptors: 1.0.0
+    dev: true
+
   /setimmediate@1.0.5:
     resolution: {integrity: sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==}
     dev: false
@@ -12549,7 +13551,7 @@ packages:
   /shiki@0.14.4:
     resolution: {integrity: sha512-IXCRip2IQzKwxArNNq1S+On4KPML3Yyn8Zzs/xRgcgOWIr8ntIK3IKzjFPfjy/7kt9ZMjc+FItfqHRBg8b6tNQ==}
     dependencies:
-      ansi-sequence-parser: 1.1.0
+      ansi-sequence-parser: 1.1.1
       jsonc-parser: 3.2.0
       vscode-oniguruma: 1.7.0
       vscode-textmate: 8.0.0
@@ -12564,11 +13566,6 @@ packages:
   /signal-exit@3.0.7:
     resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==}
 
-  /signal-exit@4.0.2:
-    resolution: {integrity: sha512-MY2/qGx4enyjprQnFaZsHib3Yadh3IXyV2C321GY0pjGfVBu4un0uDJkwgdxqO+Rdx8JMT8IfJIRwbYVz3Ob3Q==}
-    engines: {node: '>=14'}
-    dev: false
-
   /signal-exit@4.1.0:
     resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==}
     engines: {node: '>=14'}
@@ -12589,7 +13586,7 @@ packages:
       '@hapi/hoek': 10.0.1
       '@hapi/wreck': 18.0.1
       debug: 4.3.4
-      joi: 17.9.2
+      joi: 17.11.0
     transitivePeerDependencies:
       - supports-color
     dev: false
@@ -12603,7 +13600,7 @@ packages:
     resolution: {integrity: sha512-O9jm9BsID1P+0HOi81VpXPoDxYP374pkOLzACAoyUQ/3OUVndNpsz6wMnY2z+yOxzbllCKZrM+9QrWsv4THnyA==}
     engines: {node: '>= 10'}
     dependencies:
-      '@polka/url': 1.0.0-next.21
+      '@polka/url': 1.0.0-next.23
       mrmime: 1.0.1
       totalist: 3.0.1
 
@@ -12616,9 +13613,9 @@ packages:
     hasBin: true
     dependencies:
       '@types/node': 17.0.45
-      '@types/sax': 1.2.4
+      '@types/sax': 1.2.5
       arg: 5.0.2
-      sax: 1.2.4
+      sax: 1.3.0
     dev: false
 
   /slash@3.0.0:
@@ -12648,38 +13645,19 @@ packages:
     dependencies:
       csstype: 3.1.2
       seroval: 0.5.1
-    dev: false
-
-  /solid-js@1.7.8:
-    resolution: {integrity: sha512-XHBWk1FvFd0JMKljko7FfhefJMTSgYEuVKcQ2a8hzRXfiuSJAGsrPPafqEo+f6l+e8Oe3cROSpIL6kbzjC1fjQ==}
-    dependencies:
-      csstype: 3.1.2
-      seroval: 0.5.1
 
   /solid-refresh@0.5.3(solid-js@1.7.11):
     resolution: {integrity: sha512-Otg5it5sjOdZbQZJnvo99TEBAr6J7PQ5AubZLNU6szZzg3RQQ5MX04oteBIIGDs0y2Qv8aXKm9e44V8z+UnFdw==}
     peerDependencies:
       solid-js: ^1.3
     dependencies:
-      '@babel/generator': 7.22.5
-      '@babel/helper-module-imports': 7.22.5
-      '@babel/types': 7.22.5
+      '@babel/generator': 7.23.0
+      '@babel/helper-module-imports': 7.22.15
+      '@babel/types': 7.23.0
       solid-js: 1.7.11
-    dev: false
-
-  /solid-refresh@0.5.3(solid-js@1.7.8):
-    resolution: {integrity: sha512-Otg5it5sjOdZbQZJnvo99TEBAr6J7PQ5AubZLNU6szZzg3RQQ5MX04oteBIIGDs0y2Qv8aXKm9e44V8z+UnFdw==}
-    peerDependencies:
-      solid-js: ^1.3
-    dependencies:
-      '@babel/generator': 7.22.5
-      '@babel/helper-module-imports': 7.22.5
-      '@babel/types': 7.22.5
-      solid-js: 1.7.8
-    dev: true
 
-  /sonic-boom@3.3.0:
-    resolution: {integrity: sha512-LYxp34KlZ1a2Jb8ZQgFCK3niIHzibdwtwNUWKg0qQRzsDoJ3Gfgkf8KdBTFU3SkejDEIlWwnSnpVdOZIhFMl/g==}
+  /sonic-boom@3.6.1:
+    resolution: {integrity: sha512-QV+p5nXPiUiSMxn/k5bOL+hzCpafdj1voL+hywPZhheRSYyYp7CF15rNdz1evOXCUn/tFb7R62PDX1yJmtoTgg==}
     dependencies:
       atomic-sleep: 1.0.0
     dev: false
@@ -12697,12 +13675,16 @@ packages:
     dependencies:
       buffer-from: 1.1.2
       source-map: 0.6.1
-    dev: true
 
   /source-map@0.6.1:
     resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==}
     engines: {node: '>=0.10.0'}
 
+  /source-map@0.7.4:
+    resolution: {integrity: sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==}
+    engines: {node: '>= 8'}
+    dev: false
+
   /space-separated-tokens@2.0.2:
     resolution: {integrity: sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==}
 
@@ -12716,7 +13698,7 @@ packages:
     resolution: {integrity: sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==}
     dependencies:
       spdx-expression-parse: 3.0.1
-      spdx-license-ids: 3.0.13
+      spdx-license-ids: 3.0.16
 
   /spdx-exceptions@2.3.0:
     resolution: {integrity: sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==}
@@ -12725,10 +13707,10 @@ packages:
     resolution: {integrity: sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==}
     dependencies:
       spdx-exceptions: 2.3.0
-      spdx-license-ids: 3.0.13
+      spdx-license-ids: 3.0.16
 
-  /spdx-license-ids@3.0.13:
-    resolution: {integrity: sha512-XkD+zwiqXHikFZm4AX/7JSCXA98U5Db4AFd5XUg/+9UNtnH75+Z9KxtpYiJZx36mUDVOwH83pl7yvCer6ewM3w==}
+  /spdx-license-ids@3.0.16:
+    resolution: {integrity: sha512-eWN+LnM3GR6gPu35WxNgbGl8rmY1AEmoMDvL/QD6zYmPWgywxWqJWNdLGT+ke8dKNWrcYgYjPpG5gbTfghP8rw==}
 
   /split2@4.2.0:
     resolution: {integrity: sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==}
@@ -12738,6 +13720,11 @@ packages:
   /sprintf-js@1.0.3:
     resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==}
 
+  /stable@0.1.8:
+    resolution: {integrity: sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==}
+    deprecated: 'Modern JS already guarantees Array#sort() is a stable sort, so this library is deprecated. See the compatibility table on MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort#browser_compatibility'
+    dev: false
+
   /standard-as-callback@2.1.0:
     resolution: {integrity: sha512-qoRRSyROncaz1z0mvYqIE4lCd9p2R90i6GxW3uZv5ucSu8tU7B5HXUP1gG8pVZsYNVaXjk8ClXHPttLyxAL48A==}
     dev: false
@@ -12774,10 +13761,6 @@ packages:
     engines: {node: '>=4.0.0'}
     dev: false
 
-  /streamsearch@1.1.0:
-    resolution: {integrity: sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==}
-    engines: {node: '>=10.0.0'}
-
   /streamx@2.15.1:
     resolution: {integrity: sha512-fQMzy2O/Q47rgwErk/eGeLu/roaFWV0jVsogDmrszM9uIw8L5OA+t+V93MgYlufNptfjmYR1tOMWhei/Eh7TQA==}
     dependencies:
@@ -12808,29 +13791,29 @@ packages:
       emoji-regex: 10.2.1
       strip-ansi: 7.1.0
 
-  /string.prototype.trim@1.2.7:
-    resolution: {integrity: sha512-p6TmeT1T3411M8Cgg9wBTMRtY2q9+PNy9EV1i2lIXUN/btt763oIfxwN3RR8VU6wHX8j/1CFy0L+YuThm6bgOg==}
+  /string.prototype.trim@1.2.8:
+    resolution: {integrity: sha512-lfjY4HcixfQXOfaqCvcBuOIapyaroTXhbkfJN3gcB1OtyupngWK4sEET9Knd0cXd28kTUqu/kHoV4HKSJdnjiQ==}
     engines: {node: '>= 0.4'}
     dependencies:
       call-bind: 1.0.2
-      define-properties: 1.2.0
-      es-abstract: 1.21.2
+      define-properties: 1.2.1
+      es-abstract: 1.22.2
     dev: true
 
-  /string.prototype.trimend@1.0.6:
-    resolution: {integrity: sha512-JySq+4mrPf9EsDBEDYMOb/lM7XQLulwg5R/m1r0PXEFqrV0qHvl58sdTilSXtKOflCsK2E8jxf+GKC0T07RWwQ==}
+  /string.prototype.trimend@1.0.7:
+    resolution: {integrity: sha512-Ni79DqeB72ZFq1uH/L6zJ+DKZTkOtPIHovb3YZHQViE+HDouuU4mBrLOLDn5Dde3RF8qw5qVETEjhu9locMLvA==}
     dependencies:
       call-bind: 1.0.2
-      define-properties: 1.2.0
-      es-abstract: 1.21.2
+      define-properties: 1.2.1
+      es-abstract: 1.22.2
     dev: true
 
-  /string.prototype.trimstart@1.0.6:
-    resolution: {integrity: sha512-omqjMDaY92pbn5HOX7f9IccLA+U1tA9GvtU4JrodiXFfYB7jPzzHpRzpglLAjtUV6bB557zwClJezTqnAiYnQA==}
+  /string.prototype.trimstart@1.0.7:
+    resolution: {integrity: sha512-NGhtDFu3jCEm7B4Fy0DpLewdJQOZcQ0rGbwQ/+stjnrp2i+rlKeCvos9hOIeCmqwratM47OBxY7uFZzjxHXmrg==}
     dependencies:
       call-bind: 1.0.2
-      define-properties: 1.2.0
-      es-abstract: 1.21.2
+      define-properties: 1.2.1
+      es-abstract: 1.22.2
     dev: true
 
   /string_decoder@1.1.1:
@@ -12942,12 +13925,26 @@ packages:
     resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==}
     engines: {node: '>= 0.4'}
 
+  /svgo@2.8.0:
+    resolution: {integrity: sha512-+N/Q9kV1+F+UeWYoSiULYo4xYSDQlTgb+ayMobAXPwMnLvop7oxKMo9OzIrX5x3eS4L4f2UHhc9axXwY8DpChg==}
+    engines: {node: '>=10.13.0'}
+    hasBin: true
+    dependencies:
+      '@trysound/sax': 0.2.0
+      commander: 7.2.0
+      css-select: 4.3.0
+      css-tree: 1.1.3
+      csso: 4.2.0
+      picocolors: 1.0.0
+      stable: 0.1.8
+    dev: false
+
   /synckit@0.8.5:
     resolution: {integrity: sha512-L1dapNV6vu2s/4Sputv8xGsCdAVlb5nRDMFU/E27D44l5U6cw1g0dGd45uLc+OXjNMmF4ntiMdCimzcjFKQI8Q==}
     engines: {node: ^14.18.0 || >=16.0.0}
     dependencies:
-      '@pkgr/utils': 2.4.1
-      tslib: 2.5.3
+      '@pkgr/utils': 2.4.2
+      tslib: 2.6.2
 
   /tailwindcss@3.2.7(postcss@8.4.21):
     resolution: {integrity: sha512-B6DLqJzc21x7wntlH/GsZwEXTBttVSl1FtCzC8WP4oBc/NKef7kaax5jeihkkCEWc831/5NDJ9gRNDK6NEioQQ==}
@@ -12978,7 +13975,7 @@ packages:
       postcss-selector-parser: 6.0.13
       postcss-value-parser: 4.2.0
       quick-lru: 5.1.1
-      resolve: 1.22.4
+      resolve: 1.22.6
     transitivePeerDependencies:
       - ts-node
     dev: false
@@ -13020,11 +14017,10 @@ packages:
     engines: {node: '>=10'}
     hasBin: true
     dependencies:
-      '@jridgewell/source-map': 0.3.3
+      '@jridgewell/source-map': 0.3.5
       acorn: 8.10.0
       commander: 2.20.3
       source-map-support: 0.5.21
-    dev: true
 
   /text-decoding@1.0.0:
     resolution: {integrity: sha512-/0TJD42KDnVwKmDK6jj3xP7E2MG7SHAOG4tyTgyUCRPdHwvkquYNLEQltmdMa3owq3TkddCVcTsoctJI8VQNKA==}
@@ -13034,8 +14030,8 @@ packages:
     resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==}
     dev: true
 
-  /thread-stream@2.3.0:
-    resolution: {integrity: sha512-kaDqm1DET9pp3NXwR8382WHbnpXnRkN9xGN9dQt3B2+dmXiW8X1SOwmFOxAErEQ47ObhZ96J6yhZNXuyCOL7KA==}
+  /thread-stream@2.4.1:
+    resolution: {integrity: sha512-d/Ex2iWd1whipbT681JmTINKw0ZwOUBZm7+Gjs64DHuX34mmw8vJL2bFAaNacaW72zYiTJxSHi5abUuOi5nsfg==}
     dependencies:
       real-require: 0.2.0
     dev: false
@@ -13045,8 +14041,8 @@ packages:
     engines: {node: '>=10'}
     dev: false
 
-  /tiny-lru@11.0.1:
-    resolution: {integrity: sha512-iNgFugVuQgBKrqeO/mpiTTgmBsTP0WL6yeuLfLs/Ctf0pI/ixGqIRm8sDCwMcXGe9WWvt2sGXI5mNqZbValmJg==}
+  /tiny-lru@11.2.2:
+    resolution: {integrity: sha512-1An82KBJOUKCfRhsk4tHe4rNblnhAUzisesWBGf/0pztaVoNYM7eJxouN+mq6WkV/qNG21AFbrsgQfvBk0X9ng==}
     engines: {node: '>=12'}
     dev: false
 
@@ -13128,15 +14124,15 @@ packages:
     dependencies:
       '@trpc/server': 10.35.0
       co-body: 6.1.0
-      h3: 1.7.1
+      h3: 1.8.2
       lodash.clonedeep: 4.5.0
-      node-mocks-http: 1.12.2
+      node-mocks-http: 1.13.0
       openapi-types: 12.1.3
       zod: 3.21.4
       zod-to-json-schema: 3.21.4(zod@3.21.4)
     dev: false
 
-  /trpc-openapi@1.2.0(@trpc/server@10.35.0)(zod@3.22.2):
+  /trpc-openapi@1.2.0(@trpc/server@10.35.0)(zod@3.22.4):
     resolution: {integrity: sha512-pfYoCd/3KYXWXvUPZBKJw455OOwngKN/6SIcj7Yit19OMLJ+8yVZkEvGEeg5wUSwfsiTdRsKuvqkRPXVSwV7ew==}
     peerDependencies:
       '@trpc/server': ^10.0.0
@@ -13144,24 +14140,24 @@ packages:
     dependencies:
       '@trpc/server': 10.35.0
       co-body: 6.1.0
-      h3: 1.7.1
+      h3: 1.8.2
       lodash.clonedeep: 4.5.0
-      node-mocks-http: 1.12.2
+      node-mocks-http: 1.13.0
       openapi-types: 12.1.3
-      zod: 3.22.2
-      zod-to-json-schema: 3.21.4(zod@3.22.2)
+      zod: 3.22.4
+      zod-to-json-schema: 3.21.4(zod@3.22.4)
     dev: false
 
-  /ts-api-utils@1.0.1(typescript@5.1.6):
-    resolution: {integrity: sha512-lC/RGlPmwdrIBFTX59wwNzqh7aR2otPNPR/5brHZm/XKFYKsfqxihXUe9pU3JI+3vGkl+vyCoNNnPhJn3aLK1A==}
+  /ts-api-utils@1.0.3(typescript@5.2.2):
+    resolution: {integrity: sha512-wNMeqtMz5NtwpT/UZGY5alT+VoKdSsOOP/kqHFcUW1P/VRhH2wJ48+DN2WwUliNbQ976ETwDL0Ifd2VVvgonvg==}
     engines: {node: '>=16.13.0'}
     peerDependencies:
       typescript: '>=4.2.0'
     dependencies:
-      typescript: 5.1.6
+      typescript: 5.2.2
     dev: true
 
-  /tsconfck@2.1.2(typescript@5.1.6):
+  /tsconfck@2.1.2(typescript@5.2.2):
     resolution: {integrity: sha512-ghqN1b0puy3MhhviwO2kGF8SeMDNhEbnKxjK7h6+fvY9JAxqvXi8y5NAHSQv687OVboS2uZIByzGd45/YxrRHg==}
     engines: {node: ^14.13.1 || ^16 || >=18}
     hasBin: true
@@ -13171,7 +14167,7 @@ packages:
       typescript:
         optional: true
     dependencies:
-      typescript: 5.1.6
+      typescript: 5.2.2
     dev: true
 
   /tsconfig-paths@3.14.2:
@@ -13187,17 +14183,17 @@ packages:
     resolution: {integrity: sha512-ZHqlstlQF449v8glscGRXzL6l2dZvASPCdXJRWG4gHEZlUVx2Jtmr+a2zeVG4LCsKhDXKRj5R3h0C/98UcVAQg==}
     dependencies:
       '@types/json5': 0.0.30
-      '@types/resolve': 1.20.2
+      '@types/resolve': 1.20.3
       json5: 2.2.3
-      resolve: 1.22.4
+      resolve: 1.22.6
       strip-bom: 4.0.0
       type-fest: 0.13.1
 
   /tslib@1.14.1:
     resolution: {integrity: sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==}
 
-  /tslib@2.5.3:
-    resolution: {integrity: sha512-mSxlJJwl3BMEQCUNnxXBU9jP4JBktcEGhURcPR6VQVlnP0FdDEsIaz0C35dXNGLyRfrATNofF0F5p2KPxQgB+w==}
+  /tslib@2.6.2:
+    resolution: {integrity: sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==}
 
   /tsm@2.3.0:
     resolution: {integrity: sha512-++0HFnmmR+gMpDtKTnW3XJ4yv9kVGi20n+NfyQWB9qwJvTaIWY9kBmzek2YUQK5APTQ/1DTrXmm4QtFPmW9Rzw==}
@@ -13207,14 +14203,14 @@ packages:
       esbuild: 0.15.18
     dev: true
 
-  /tsutils@3.21.0(typescript@5.1.6):
+  /tsutils@3.21.0(typescript@5.2.2):
     resolution: {integrity: sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==}
     engines: {node: '>= 6'}
     peerDependencies:
       typescript: '>=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta'
     dependencies:
       tslib: 1.14.1
-      typescript: 5.1.6
+      typescript: 5.2.2
     dev: true
 
   /tunnel-agent@0.6.0:
@@ -13331,19 +14327,44 @@ packages:
       mime-types: 2.1.35
     dev: false
 
+  /typed-array-buffer@1.0.0:
+    resolution: {integrity: sha512-Y8KTSIglk9OZEr8zywiIHG/kmQ7KWyjseXs1CbSo8vC42w7hg2HgYTxSWwP0+is7bWDc1H+Fo026CpHFwm8tkw==}
+    engines: {node: '>= 0.4'}
+    dependencies:
+      call-bind: 1.0.2
+      get-intrinsic: 1.2.1
+      is-typed-array: 1.1.12
+    dev: true
+
+  /typed-array-byte-length@1.0.0:
+    resolution: {integrity: sha512-Or/+kvLxNpeQ9DtSydonMxCx+9ZXOswtwJn17SNLvhptaXYDJvkFFP5zbfU/uLmvnBJlI4yrnXRxpdWH/M5tNA==}
+    engines: {node: '>= 0.4'}
+    dependencies:
+      call-bind: 1.0.2
+      for-each: 0.3.3
+      has-proto: 1.0.1
+      is-typed-array: 1.1.12
+    dev: true
+
+  /typed-array-byte-offset@1.0.0:
+    resolution: {integrity: sha512-RD97prjEt9EL8YgAgpOkf3O4IF9lhJFr9g0htQkm0rchFp/Vx7LW5Q8fSXXub7BXAODyUQohRMyOc3faCPd0hg==}
+    engines: {node: '>= 0.4'}
+    dependencies:
+      available-typed-arrays: 1.0.5
+      call-bind: 1.0.2
+      for-each: 0.3.3
+      has-proto: 1.0.1
+      is-typed-array: 1.1.12
+    dev: true
+
   /typed-array-length@1.0.4:
     resolution: {integrity: sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng==}
     dependencies:
       call-bind: 1.0.2
       for-each: 0.3.3
-      is-typed-array: 1.1.10
+      is-typed-array: 1.1.12
     dev: true
 
-  /typescript@5.1.6:
-    resolution: {integrity: sha512-zaWCozRZ6DLEWAWFrVDz1H6FVXzUSfTy5FUMWsQlU8Ym5JP9eO4xkTIROFCQvhQf61z6O/G6ugw3SgAnvvm+HA==}
-    engines: {node: '>=14.17'}
-    hasBin: true
-
   /typescript@5.2.2:
     resolution: {integrity: sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==}
     engines: {node: '>=14.17'}
@@ -13353,12 +14374,8 @@ packages:
     resolution: {integrity: sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==}
     dev: false
 
-  /ufo@1.1.2:
-    resolution: {integrity: sha512-TrY6DsjTQQgyS3E3dBaOXf0TpPD8u9FVrVYmKVegJuFw51n/YB9XPt+U6ydzFG5ZIN7+DIjPbNmXoBj9esYhgQ==}
-    dev: false
-
-  /ufo@1.3.0:
-    resolution: {integrity: sha512-bRn3CsoojyNStCZe0BG0Mt4Nr/4KF+rhFlnNXybgqt5pXHNFRlqinSoQaTrGyzE4X8aHplSb+TorH+COin9Yxw==}
+  /ufo@1.3.1:
+    resolution: {integrity: sha512-uY/99gMLIOlJPwATcMVYfqDSxUR9//AUcgZMzwfSTJPDKzA1S8mX4VLqa+fiAtveraQUBCz4FFcwVZBGbwBXIw==}
 
   /uglify-js@3.17.4:
     resolution: {integrity: sha512-T9q82TJI9e/C1TAxYvfb16xO120tMVFZrGA3f9/P4424DNu6ypK103y0GPFVa17yotwSyZW5iYXgjYHkGrJW/g==}
@@ -13381,60 +14398,63 @@ packages:
     resolution: {integrity: sha512-J4efk69Aye43tWcBPCsLK7TIRppGrEN4pAlDzRKo3HSE6MgTSTBxSEuE3ccx7ixc62JvGQ/CoFXYqqF2AHozow==}
     hasBin: true
     dependencies:
-      '@rollup/plugin-alias': 5.0.0(rollup@3.26.2)
-      '@rollup/plugin-commonjs': 24.1.0(rollup@3.26.2)
-      '@rollup/plugin-json': 6.0.0(rollup@3.26.2)
-      '@rollup/plugin-node-resolve': 15.1.0(rollup@3.26.2)
-      '@rollup/plugin-replace': 5.0.2(rollup@3.26.2)
-      '@rollup/pluginutils': 5.0.2(rollup@3.26.2)
+      '@rollup/plugin-alias': 5.0.1(rollup@3.29.4)
+      '@rollup/plugin-commonjs': 24.1.0(rollup@3.29.4)
+      '@rollup/plugin-json': 6.0.1(rollup@3.29.4)
+      '@rollup/plugin-node-resolve': 15.2.2(rollup@3.29.4)
+      '@rollup/plugin-replace': 5.0.3(rollup@3.29.4)
+      '@rollup/pluginutils': 5.0.5(rollup@3.29.4)
       chalk: 5.3.0
       consola: 3.2.3
       defu: 6.1.2
       esbuild: 0.17.19
-      globby: 13.1.4
+      globby: 13.2.2
       hookable: 5.5.3
-      jiti: 1.18.2
-      magic-string: 0.30.1
-      mkdist: 1.2.0(typescript@5.2.2)
-      mlly: 1.3.0
+      jiti: 1.20.0
+      magic-string: 0.30.4
+      mkdist: 1.3.0(typescript@5.2.2)
+      mlly: 1.4.2
       mri: 1.2.0
       pathe: 1.1.1
       pkg-types: 1.0.3
-      pretty-bytes: 6.1.0
-      rollup: 3.26.2
-      rollup-plugin-dts: 5.3.0(rollup@3.26.2)(typescript@5.2.2)
+      pretty-bytes: 6.1.1
+      rollup: 3.29.4
+      rollup-plugin-dts: 5.3.1(rollup@3.29.4)(typescript@5.2.2)
       scule: 1.0.0
       typescript: 5.2.2
-      untyped: 1.3.2
+      untyped: 1.4.0
     transitivePeerDependencies:
       - sass
       - supports-color
     dev: true
 
-  /unconfig@0.3.10:
-    resolution: {integrity: sha512-tj317lhIq2iZF/NXrJnU1t2UaGUKKz1eL1sK2t63Oq66V9BxqvZV12m55fp/fpQJ+DDmVlLgo7cnLVOZkhlO/A==}
+  /unconfig@0.3.11:
+    resolution: {integrity: sha512-bV/nqePAKv71v3HdVUn6UefbsDKQWRX+bJIkiSm0+twIds6WiD2bJLWWT3i214+J/B4edufZpG2w7Y63Vbwxow==}
     dependencies:
       '@antfu/utils': 0.7.6
       defu: 6.1.2
-      jiti: 1.19.3
+      jiti: 1.20.0
       mlly: 1.4.2
 
   /uncrypto@0.1.3:
     resolution: {integrity: sha512-Ql87qFHB3s/De2ClA9e0gsnS6zXG27SkTiSJwjCc9MebbfapQfuPzumMIUMi38ezPZVNFcHI9sUIepeQfw8J8Q==}
     dev: false
 
-  /undici@5.22.1:
-    resolution: {integrity: sha512-Ji2IJhFXZY0x/0tVBXeQwgPlLWw13GVzpsWPQ3rV50IFMMof2I55PZZxtm4P6iNq+L5znYN9nSTAq0ZyE6lSJw==}
+  /undici@5.25.4:
+    resolution: {integrity: sha512-450yJxT29qKMf3aoudzFpIciqpx6Pji3hEWaXqXmanbXF58LTAGCKxcJjxMXWu3iG+Mudgo3ZUfDB6YDFd/dAw==}
     engines: {node: '>=14.0'}
     dependencies:
-      busboy: 1.6.0
-    dev: false
+      '@fastify/busboy': 2.0.0
 
-  /undici@5.23.0:
-    resolution: {integrity: sha512-1D7w+fvRsqlQ9GscLBwcAJinqcZGHUKjbOmXdlE/v8BvEGXjeWAax+341q44EuTcHXXnfyKNbKRq4Lg7OzhMmg==}
-    engines: {node: '>=14.0'}
+  /unenv@1.7.4:
+    resolution: {integrity: sha512-fjYsXYi30It0YCQYqLOcT6fHfMXsBr2hw9XC7ycf8rTG7Xxpe3ZssiqUnD0khrjiZEmkBXWLwm42yCSCH46fMw==}
     dependencies:
-      busboy: 1.6.0
+      consola: 3.2.3
+      defu: 6.1.2
+      mime: 3.0.0
+      node-fetch-native: 1.4.0
+      pathe: 1.1.1
+    dev: false
 
   /unfetch@4.2.0:
     resolution: {integrity: sha512-F9p7yYCn6cIW9El1zi0HI6vqpeIvBsr3dSuRO6Xuppb1u5rXpCPmMvLSyECLhybr9isec8Ohl0hPekMVrEinDA==}
@@ -13446,7 +14466,7 @@ packages:
   /unified@10.1.2:
     resolution: {integrity: sha512-pUSWAi/RAnVy1Pif2kAoeWNBa3JVrx0MId2LASj8G+7AiHWoKZNTomq6LG326T68U7/e263X6fTdcXIy7XnF7Q==}
     dependencies:
-      '@types/unist': 2.0.6
+      '@types/unist': 2.0.8
       bail: 2.0.2
       extend: 3.0.2
       is-buffer: 2.0.5
@@ -13454,13 +14474,25 @@ packages:
       trough: 2.1.0
       vfile: 5.3.7
 
+  /unified@11.0.3:
+    resolution: {integrity: sha512-jlCV402P+YDcFcB2VcN/n8JasOddqIiaxv118wNBoZXEhOn+lYG7BR4Bfg2BwxvlK58dwbuH2w7GX2esAjL6Mg==}
+    dependencies:
+      '@types/unist': 3.0.0
+      bail: 2.0.2
+      devlop: 1.1.0
+      extend: 3.0.2
+      is-plain-obj: 4.1.0
+      trough: 2.1.0
+      vfile: 6.0.1
+    dev: false
+
   /unist-util-generated@2.0.1:
     resolution: {integrity: sha512-qF72kLmPxAw0oN2fwpWIqbXAVyEqUzDHMsbtPvOudIlUzXYFIeQIuxXQCRCFh22B7cixvU0MG7m3MW8FTq/S+A==}
 
   /unist-util-is@5.2.1:
     resolution: {integrity: sha512-u9njyyfEh43npf1M+yGKDGVPbY/JWEemg5nH05ncKPfi+kBbKBJoTdsogMu33uhytuLlv9y0O7GH7fEdwLdLQw==}
     dependencies:
-      '@types/unist': 2.0.6
+      '@types/unist': 2.0.8
 
   /unist-util-is@6.0.0:
     resolution: {integrity: sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==}
@@ -13470,28 +14502,66 @@ packages:
   /unist-util-modify-children@3.1.1:
     resolution: {integrity: sha512-yXi4Lm+TG5VG+qvokP6tpnk+r1EPwyYL04JWDxLvgvPV40jANh7nm3udk65OOWquvbMDe+PL9+LmkxDpTv/7BA==}
     dependencies:
-      '@types/unist': 2.0.6
+      '@types/unist': 2.0.8
       array-iterate: 2.0.1
 
+  /unist-util-position-from-estree@1.1.2:
+    resolution: {integrity: sha512-poZa0eXpS+/XpoQwGwl79UUdea4ol2ZuCYguVaJS4qzIOMDzbqz8a3erUCOmubSZkaOuGamb3tX790iwOIROww==}
+    dependencies:
+      '@types/unist': 2.0.8
+    dev: false
+
+  /unist-util-position-from-estree@2.0.0:
+    resolution: {integrity: sha512-KaFVRjoqLyF6YXCbVLNad/eS4+OfPQQn2yOd7zF/h5T/CSL2v8NpN6a5TPvtbXthAGw5nG+PuTtq+DdIZr+cRQ==}
+    dependencies:
+      '@types/unist': 3.0.0
+    dev: false
+
   /unist-util-position@4.0.4:
     resolution: {integrity: sha512-kUBE91efOWfIVBo8xzh/uZQ7p9ffYRtUbMRZBNFYwf0RK8koUMx6dGUfwylLOKmaT2cs4wSW96QoYUSXAyEtpg==}
     dependencies:
-      '@types/unist': 2.0.6
+      '@types/unist': 2.0.8
+
+  /unist-util-position@5.0.0:
+    resolution: {integrity: sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==}
+    dependencies:
+      '@types/unist': 3.0.0
+    dev: false
+
+  /unist-util-remove-position@4.0.2:
+    resolution: {integrity: sha512-TkBb0HABNmxzAcfLf4qsIbFbaPDvMO6wa3b3j4VcEzFVaw1LBKwnW4/sRJ/atSLSzoIg41JWEdnE7N6DIhGDGQ==}
+    dependencies:
+      '@types/unist': 2.0.8
+      unist-util-visit: 4.1.2
+    dev: false
+
+  /unist-util-remove-position@5.0.0:
+    resolution: {integrity: sha512-Hp5Kh3wLxv0PHj9m2yZhhLt58KzPtEYKQQ4yxfYFEO7EvHwzyDYnduhHnY1mDxoqr7VUwVuHXk9RXKIiYS1N8Q==}
+    dependencies:
+      '@types/unist': 3.0.0
+      unist-util-visit: 5.0.0
+    dev: false
 
   /unist-util-stringify-position@3.0.3:
     resolution: {integrity: sha512-k5GzIBZ/QatR8N5X2y+drfpWG8IDBzdnVj6OInRNWm1oXrzydiaAT2OQiA8DPRRZyAKb9b6I2a6PxYklZD0gKg==}
     dependencies:
-      '@types/unist': 2.0.6
+      '@types/unist': 2.0.8
+
+  /unist-util-stringify-position@4.0.0:
+    resolution: {integrity: sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==}
+    dependencies:
+      '@types/unist': 3.0.0
+    dev: false
 
   /unist-util-visit-children@2.0.2:
     resolution: {integrity: sha512-+LWpMFqyUwLGpsQxpumsQ9o9DG2VGLFrpz+rpVXYIEdPy57GSy5HioC0g3bg/8WP9oCLlapQtklOzQ8uLS496Q==}
     dependencies:
-      '@types/unist': 2.0.6
+      '@types/unist': 2.0.8
 
   /unist-util-visit-parents@5.1.3:
     resolution: {integrity: sha512-x6+y8g7wWMyQhL1iZfhIPhDAs7Xwbn9nRosDXl7qoPTSCy0yNxnKc+hWokFifWQIDGi154rdUqKvbCa4+1kLhg==}
     dependencies:
-      '@types/unist': 2.0.6
+      '@types/unist': 2.0.8
       unist-util-is: 5.2.1
 
   /unist-util-visit-parents@6.0.1:
@@ -13503,7 +14573,7 @@ packages:
   /unist-util-visit@4.1.2:
     resolution: {integrity: sha512-MSd8OUGISqHdVvfY9TPhyK2VdUrPgxkUtWSuMHF6XAAFuL4LokseigBnZtPnJMu+FbynTkFNnFlyjxpVKujMRg==}
     dependencies:
-      '@types/unist': 2.0.6
+      '@types/unist': 2.0.8
       unist-util-is: 5.2.1
       unist-util-visit-parents: 5.1.3
 
@@ -13517,8 +14587,8 @@ packages:
   /universal-github-app-jwt@1.1.1:
     resolution: {integrity: sha512-G33RTLrIBMFmlDV4u4CBF7dh71eWwykck4XgaxaIVeZKOYZRAAxvcGMRFTUclVY6xoUPQvO4Ne5wKGxYm/Yy9w==}
     dependencies:
-      '@types/jsonwebtoken': 9.0.2
-      jsonwebtoken: 9.0.1
+      '@types/jsonwebtoken': 9.0.3
+      jsonwebtoken: 9.0.2
     dev: false
 
   /universal-user-agent@6.0.0:
@@ -13534,46 +14604,7 @@ packages:
     resolution: {integrity: sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==}
     engines: {node: '>= 10.0.0'}
 
-  /unocss@0.55.7(postcss@8.4.29)(vite@4.4.7):
-    resolution: {integrity: sha512-3W9P7vj2EhSk/4oPCHBS0VgrwSf5zZL6Az1/XARVOpBnRJtCM2szFInYxHkMgt9pkZTsW8SFCuk/g+QIJ6A8tg==}
-    engines: {node: '>=14'}
-    peerDependencies:
-      '@unocss/webpack': 0.55.7
-      vite: ^2.9.0 || ^3.0.0-0 || ^4.0.0
-    peerDependenciesMeta:
-      '@unocss/webpack':
-        optional: true
-      vite:
-        optional: true
-    dependencies:
-      '@unocss/astro': 0.55.7(vite@4.4.7)
-      '@unocss/cli': 0.55.7
-      '@unocss/core': 0.55.7
-      '@unocss/extractor-arbitrary-variants': 0.55.7
-      '@unocss/postcss': 0.55.7(postcss@8.4.29)
-      '@unocss/preset-attributify': 0.55.7
-      '@unocss/preset-icons': 0.55.7
-      '@unocss/preset-mini': 0.55.7
-      '@unocss/preset-tagify': 0.55.7
-      '@unocss/preset-typography': 0.55.7
-      '@unocss/preset-uno': 0.55.7
-      '@unocss/preset-web-fonts': 0.55.7
-      '@unocss/preset-wind': 0.55.7
-      '@unocss/reset': 0.55.7
-      '@unocss/transformer-attributify-jsx': 0.55.7
-      '@unocss/transformer-attributify-jsx-babel': 0.55.7
-      '@unocss/transformer-compile-class': 0.55.7
-      '@unocss/transformer-directives': 0.55.7
-      '@unocss/transformer-variant-group': 0.55.7
-      '@unocss/vite': 0.55.7(vite@4.4.7)
-      vite: 4.4.7(@types/node@20.4.4)(sass@1.64.1)(terser@5.19.2)
-    transitivePeerDependencies:
-      - postcss
-      - rollup
-      - supports-color
-    dev: true
-
-  /unocss@0.55.7(postcss@8.4.29)(vite@4.4.9):
+  /unocss@0.55.7(postcss@8.4.31)(vite@4.4.9):
     resolution: {integrity: sha512-3W9P7vj2EhSk/4oPCHBS0VgrwSf5zZL6Az1/XARVOpBnRJtCM2szFInYxHkMgt9pkZTsW8SFCuk/g+QIJ6A8tg==}
     engines: {node: '>=14'}
     peerDependencies:
@@ -13589,7 +14620,7 @@ packages:
       '@unocss/cli': 0.55.7
       '@unocss/core': 0.55.7
       '@unocss/extractor-arbitrary-variants': 0.55.7
-      '@unocss/postcss': 0.55.7(postcss@8.4.29)
+      '@unocss/postcss': 0.55.7(postcss@8.4.31)
       '@unocss/preset-attributify': 0.55.7
       '@unocss/preset-icons': 0.55.7
       '@unocss/preset-mini': 0.55.7
@@ -13605,12 +14636,11 @@ packages:
       '@unocss/transformer-directives': 0.55.7
       '@unocss/transformer-variant-group': 0.55.7
       '@unocss/vite': 0.55.7(vite@4.4.9)
-      vite: 4.4.9(sass@1.64.1)
+      vite: 4.4.9(@types/node@20.4.4)(sass@1.64.1)(terser@5.19.2)
     transitivePeerDependencies:
       - postcss
       - rollup
       - supports-color
-    dev: false
 
   /unpipe@1.0.0:
     resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==}
@@ -13621,15 +14651,15 @@ packages:
     resolution: {integrity: sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw==}
     engines: {node: '>=8'}
 
-  /untyped@1.3.2:
-    resolution: {integrity: sha512-z219Z65rOGD6jXIvIhpZFfwWdqQckB8sdZec2NO+TkcH1Bph7gL0hwLzRJs1KsOo4Jz4mF9guBXhsEnyEBGVfw==}
+  /untyped@1.4.0:
+    resolution: {integrity: sha512-Egkr/s4zcMTEuulcIb7dgURS6QpN7DyqQYdf+jBtiaJvQ+eRsrtWUoX84SbvQWuLkXsOjM+8sJC9u6KoMK/U7Q==}
     hasBin: true
     dependencies:
-      '@babel/core': 7.22.5
-      '@babel/standalone': 7.22.5
-      '@babel/types': 7.22.15
+      '@babel/core': 7.23.0
+      '@babel/standalone': 7.23.1
+      '@babel/types': 7.23.0
       defu: 6.1.2
-      jiti: 1.19.3
+      jiti: 1.20.0
       mri: 1.2.0
       scule: 1.0.0
     transitivePeerDependencies:
@@ -13651,13 +14681,13 @@ packages:
       setimmediate: 1.0.5
     dev: false
 
-  /update-browserslist-db@1.0.11(browserslist@4.21.10):
-    resolution: {integrity: sha512-dCwEFf0/oT85M1fHBg4F0jtLwJrutGoHSQXCh7u4o2t1drG+c0a9Flnqww6XUKSfQMPpJBRjU8d4RXB09qtvaA==}
+  /update-browserslist-db@1.0.13(browserslist@4.22.1):
+    resolution: {integrity: sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==}
     hasBin: true
     peerDependencies:
       browserslist: '>= 4.21.0'
     dependencies:
-      browserslist: 4.21.10
+      browserslist: 4.22.1
       escalade: 3.1.1
       picocolors: 1.0.0
 
@@ -13679,8 +14709,8 @@ packages:
     hasBin: true
     dev: false
 
-  /uuid@9.0.0:
-    resolution: {integrity: sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg==}
+  /uuid@9.0.1:
+    resolution: {integrity: sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==}
     hasBin: true
     dev: false
 
@@ -13710,70 +14740,72 @@ packages:
       spdx-correct: 3.2.0
       spdx-expression-parse: 3.0.1
 
-  /validator@13.9.0:
-    resolution: {integrity: sha512-B+dGG8U3fdtM0/aNK4/X8CXq/EcxU2WPrPEkJGslb47qyHsxmbggTWK0yEA4qnYVNF+nxNlN88o14hIcPmSIEA==}
+  /validator@13.11.0:
+    resolution: {integrity: sha512-Ii+sehpSfZy+At5nPdnyMhx78fEoPDkR2XW/zimHEL3MyGJQOCQ7WeP20jPYRz7ZCpcKLB21NxuXHF3bxjStBQ==}
     engines: {node: '>= 0.10'}
     dev: false
 
   /vfile-location@4.1.0:
     resolution: {integrity: sha512-YF23YMyASIIJXpktBa4vIGLJ5Gs88UB/XePgqPmTa7cDA+JeO3yclbpheQYCHjVHBn/yePzrXuygIL+xbvRYHw==}
     dependencies:
-      '@types/unist': 2.0.6
+      '@types/unist': 2.0.8
       vfile: 5.3.7
 
+  /vfile-location@5.0.2:
+    resolution: {integrity: sha512-NXPYyxyBSH7zB5U6+3uDdd6Nybz6o6/od9rk8bp9H8GR3L+cm/fC0uUTbqBmUTnMCUDslAGBOIKNfvvb+gGlDg==}
+    dependencies:
+      '@types/unist': 3.0.0
+      vfile: 6.0.1
+    dev: false
+
   /vfile-message@3.1.4:
     resolution: {integrity: sha512-fa0Z6P8HUrQN4BZaX05SIVXic+7kE3b05PWAtPuYP9QLHsLKYR7/AlLW3NtOrpXRLeawpDLMsVkmk5DG0NXgWw==}
     dependencies:
-      '@types/unist': 2.0.6
+      '@types/unist': 2.0.8
       unist-util-stringify-position: 3.0.3
 
+  /vfile-message@4.0.2:
+    resolution: {integrity: sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw==}
+    dependencies:
+      '@types/unist': 3.0.0
+      unist-util-stringify-position: 4.0.0
+    dev: false
+
   /vfile@5.3.7:
     resolution: {integrity: sha512-r7qlzkgErKjobAmyNIkkSpizsFPYiUPuJb5pNW1RB4JcYVZhs4lIbVqk8XPk033CV/1z8ss5pkax8SuhGpcG8g==}
     dependencies:
-      '@types/unist': 2.0.6
+      '@types/unist': 2.0.8
       is-buffer: 2.0.5
       unist-util-stringify-position: 3.0.3
       vfile-message: 3.1.4
 
+  /vfile@6.0.1:
+    resolution: {integrity: sha512-1bYqc7pt6NIADBJ98UiG0Bn/CHIVOoZ/IyEkqIruLg0mE1BKzkOXY2D6CSqQIcKqgadppE5lrxgWXJmXd7zZJw==}
+    dependencies:
+      '@types/unist': 3.0.0
+      unist-util-stringify-position: 4.0.0
+      vfile-message: 4.0.2
+    dev: false
+
   /vite-plugin-solid@2.7.0(solid-js@1.7.11)(vite@4.4.9):
     resolution: {integrity: sha512-avp/Jl5zOp/Itfo67xtDB2O61U7idviaIp4mLsjhCa13PjKNasz+IID0jYTyqUp9SFx6/PmBr6v4KgDppqompg==}
     peerDependencies:
       solid-js: ^1.7.2
       vite: ^3.0.0 || ^4.0.0
     dependencies:
-      '@babel/core': 7.22.5
-      '@babel/preset-typescript': 7.22.5(@babel/core@7.22.5)
-      '@types/babel__core': 7.20.1
-      babel-preset-solid: 1.7.4(@babel/core@7.22.5)
+      '@babel/core': 7.23.0
+      '@babel/preset-typescript': 7.23.0(@babel/core@7.23.0)
+      '@types/babel__core': 7.20.2
+      babel-preset-solid: 1.7.12(@babel/core@7.23.0)
       merge-anything: 5.1.7
       solid-js: 1.7.11
       solid-refresh: 0.5.3(solid-js@1.7.11)
-      vite: 4.4.9(sass@1.64.1)
+      vite: 4.4.9(@types/node@20.4.4)(sass@1.64.1)(terser@5.19.2)
       vitefu: 0.2.4(vite@4.4.9)
     transitivePeerDependencies:
       - supports-color
-    dev: false
-
-  /vite-plugin-solid@2.7.0(solid-js@1.7.8)(vite@4.4.7):
-    resolution: {integrity: sha512-avp/Jl5zOp/Itfo67xtDB2O61U7idviaIp4mLsjhCa13PjKNasz+IID0jYTyqUp9SFx6/PmBr6v4KgDppqompg==}
-    peerDependencies:
-      solid-js: ^1.7.2
-      vite: ^3.0.0 || ^4.0.0
-    dependencies:
-      '@babel/core': 7.22.5
-      '@babel/preset-typescript': 7.22.5(@babel/core@7.22.5)
-      '@types/babel__core': 7.20.1
-      babel-preset-solid: 1.7.4(@babel/core@7.22.5)
-      merge-anything: 5.1.7
-      solid-js: 1.7.8
-      solid-refresh: 0.5.3(solid-js@1.7.8)
-      vite: 4.4.7(@types/node@20.4.4)(sass@1.64.1)(terser@5.19.2)
-      vitefu: 0.2.4(vite@4.4.7)
-    transitivePeerDependencies:
-      - supports-color
-    dev: true
 
-  /vite-tsconfig-paths@4.2.0(typescript@5.1.6)(vite@4.4.7):
+  /vite-tsconfig-paths@4.2.0(typescript@5.2.2)(vite@4.4.9):
     resolution: {integrity: sha512-jGpus0eUy5qbbMVGiTxCL1iB9ZGN6Bd37VGLJU39kTDD6ZfULTTb1bcc5IeTWqWJKiWV5YihCaibeASPiGi8kw==}
     peerDependencies:
       vite: '*'
@@ -13783,15 +14815,15 @@ packages:
     dependencies:
       debug: 4.3.4
       globrex: 0.1.2
-      tsconfck: 2.1.2(typescript@5.1.6)
-      vite: 4.4.7(@types/node@20.4.4)(sass@1.64.1)(terser@5.19.2)
+      tsconfck: 2.1.2(typescript@5.2.2)
+      vite: 4.4.9(@types/node@20.4.4)(sass@1.64.1)(terser@5.19.2)
     transitivePeerDependencies:
       - supports-color
       - typescript
     dev: true
 
-  /vite@4.4.7(@types/node@20.4.4)(sass@1.64.1)(terser@5.19.2):
-    resolution: {integrity: sha512-6pYf9QJ1mHylfVh39HpuSfMPojPSKVxZvnclX1K1FyZ1PXDOcLBibdq5t1qxJSnL63ca8Wf4zts6mD8u8oc9Fw==}
+  /vite@4.4.9(@types/node@20.4.4)(sass@1.64.1)(terser@5.19.2):
+    resolution: {integrity: sha512-2mbUn2LlUmNASWwSCNSJ/EG2HuSRTnVNaydp6vMCm5VIqJsjMfbIWtbH2kDuwUVW5mMUKKZvGPX/rqeqVvv1XA==}
     engines: {node: ^14.18.0 || >=16.0.0}
     hasBin: true
     peerDependencies:
@@ -13820,59 +14852,12 @@ packages:
     dependencies:
       '@types/node': 20.4.4
       esbuild: 0.18.16
-      postcss: 8.4.26
-      rollup: 3.26.2
+      postcss: 8.4.31
+      rollup: 3.29.4
       sass: 1.64.1
       terser: 5.19.2
     optionalDependencies:
-      fsevents: 2.3.2
-    dev: true
-
-  /vite@4.4.9(sass@1.64.1):
-    resolution: {integrity: sha512-2mbUn2LlUmNASWwSCNSJ/EG2HuSRTnVNaydp6vMCm5VIqJsjMfbIWtbH2kDuwUVW5mMUKKZvGPX/rqeqVvv1XA==}
-    engines: {node: ^14.18.0 || >=16.0.0}
-    hasBin: true
-    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
-    dependencies:
-      esbuild: 0.18.16
-      postcss: 8.4.29
-      rollup: 3.29.0
-      sass: 1.64.1
-    optionalDependencies:
-      fsevents: 2.3.2
-
-  /vitefu@0.2.4(vite@4.4.7):
-    resolution: {integrity: sha512-fanAXjSaf9xXtOOeno8wZXIhgia+CZury481LsDaV++lSvcU2R9Ch2bPh3PYFyoHW+w9LqAeYRISVQjUIew14g==}
-    peerDependencies:
-      vite: ^3.0.0 || ^4.0.0
-    peerDependenciesMeta:
-      vite:
-        optional: true
-    dependencies:
-      vite: 4.4.7(@types/node@20.4.4)(sass@1.64.1)(terser@5.19.2)
-    dev: true
+      fsevents: 2.3.3
 
   /vitefu@0.2.4(vite@4.4.9):
     resolution: {integrity: sha512-fanAXjSaf9xXtOOeno8wZXIhgia+CZury481LsDaV++lSvcU2R9Ch2bPh3PYFyoHW+w9LqAeYRISVQjUIew14g==}
@@ -13882,40 +14867,53 @@ packages:
       vite:
         optional: true
     dependencies:
-      vite: 4.4.9(sass@1.64.1)
+      vite: 4.4.9(@types/node@20.4.4)(sass@1.64.1)(terser@5.19.2)
 
-  /vscode-css-languageservice@6.2.6:
-    resolution: {integrity: sha512-SA2WkeOecIpUiEbZnjOsP/fI5CRITZEiQGSHXKiDQDwLApfKcnLhZwMtOBbIifSzESVcQa7b/shX/nbnF4NoCg==}
+  /vscode-css-languageservice@6.2.9:
+    resolution: {integrity: sha512-9MsOvAi+VycKomQ7KEq4o/hLtjHHrtRLLl8lM9nMcH8cxfNI7/6jVXmsV/7pdbDWu9L3DZhsspN1eMXZwiOymw==}
     dependencies:
-      '@vscode/l10n': 0.0.14
-      vscode-languageserver-textdocument: 1.0.8
+      '@vscode/l10n': 0.0.16
+      vscode-languageserver-textdocument: 1.0.11
       vscode-languageserver-types: 3.17.3
-      vscode-uri: 3.0.7
+      vscode-uri: 3.0.8
 
-  /vscode-html-languageservice@5.0.6:
-    resolution: {integrity: sha512-gCixNg6fjPO7+kwSMBAVXcwDRHdjz1WOyNfI0n5Wx0J7dfHG8ggb3zD1FI8E2daTZrwS1cooOiSoc1Xxph4qRQ==}
+  /vscode-html-languageservice@5.1.0:
+    resolution: {integrity: sha512-cGOu5+lrz+2dDXSGS15y24lDtPaML1T8K/SfqgFbLmCZ1btYOxceFieR+ybTS2es/A67kRc62m2cKFLUQPWG5g==}
     dependencies:
-      '@vscode/l10n': 0.0.14
-      vscode-languageserver-textdocument: 1.0.8
-      vscode-languageserver-types: 3.17.3
-      vscode-uri: 3.0.7
+      '@vscode/l10n': 0.0.16
+      vscode-languageserver-textdocument: 1.0.11
+      vscode-languageserver-types: 3.17.5
+      vscode-uri: 3.0.8
 
   /vscode-jsonrpc@8.1.0:
     resolution: {integrity: sha512-6TDy/abTQk+zDGYazgbIPc+4JoXdwC8NHU9Pbn4UJP1fehUyZmM4RHp5IthX7A6L5KS30PRui+j+tbbMMMafdw==}
     engines: {node: '>=14.0.0'}
 
+  /vscode-jsonrpc@8.2.0:
+    resolution: {integrity: sha512-C+r0eKJUIfiDIfwJhria30+TYWPtuHJXHtI7J0YlOmKAo7ogxP20T0zxB7HZQIFhIyvoBPwWskjxrvAtfjyZfA==}
+    engines: {node: '>=14.0.0'}
+
   /vscode-languageserver-protocol@3.17.3:
     resolution: {integrity: sha512-924/h0AqsMtA5yK22GgMtCYiMdCOtWTSGgUOkgEDX+wk2b0x4sAfLiO4NxBxqbiVtz7K7/1/RgVrVI0NClZwqA==}
     dependencies:
       vscode-jsonrpc: 8.1.0
       vscode-languageserver-types: 3.17.3
 
-  /vscode-languageserver-textdocument@1.0.8:
-    resolution: {integrity: sha512-1bonkGqQs5/fxGT5UchTgjGVnfysL0O8v1AYMBjqTbWQTFn721zaPGDYFkOKtfDgFiSgXM3KwaG3FMGfW4Ed9Q==}
+  /vscode-languageserver-protocol@3.17.5:
+    resolution: {integrity: sha512-mb1bvRJN8SVznADSGWM9u/b07H7Ecg0I3OgXDuLdn307rl/J3A9YD6/eYOssqhecL27hK1IPZAsaqh00i/Jljg==}
+    dependencies:
+      vscode-jsonrpc: 8.2.0
+      vscode-languageserver-types: 3.17.5
+
+  /vscode-languageserver-textdocument@1.0.11:
+    resolution: {integrity: sha512-X+8T3GoiwTVlJbicx/sIAF+yuJAqz8VvwJyoMVhwEMoEKE/fkDmrqUgDMyBECcM2A2frVZIUj5HI/ErRXCfOeA==}
 
   /vscode-languageserver-types@3.17.3:
     resolution: {integrity: sha512-SYU4z1dL0PyIMd4Vj8YOqFvHu7Hz/enbWtpfnVbJHU4Nd1YNYx8u0ennumc6h48GQNeOLxmwySmnADouT/AuZA==}
 
+  /vscode-languageserver-types@3.17.5:
+    resolution: {integrity: sha512-Ld1VelNuX9pdF39h2Hgaeb5hEZM2Z3jUrrMgWQAu82jMtZp7p3vJT3BzToKtZI7NgQssZje5o0zryOrhQvzQAg==}
+
   /vscode-languageserver@8.1.0:
     resolution: {integrity: sha512-eUt8f1z2N2IEUDBsKaNapkz7jl5QpskN2Y0G01T/ItMxBxw1fJwvtySGB9QMecatne8jFIWJGWI61dWjyTLQsw==}
     hasBin: true
@@ -13931,8 +14929,8 @@ packages:
   /vscode-uri@2.1.2:
     resolution: {integrity: sha512-8TEXQxlldWAuIODdukIb+TR5s+9Ds40eSJrw+1iDDA9IFORPjMELarNQE3myz5XIkWWpdprmJjm1/SxMlWOC8A==}
 
-  /vscode-uri@3.0.7:
-    resolution: {integrity: sha512-eOpPHogvorZRobNqJGhapa0JdwaxpjVvyBp0QIUMRMSf8ZAlqOdEquKuRmw9Qwu0qXtJIWqFtMkmvJjUZmMjVA==}
+  /vscode-uri@3.0.8:
+    resolution: {integrity: sha512-AyFQ0EVmsOZOlAnxoFOGOq1SQDWAB7C6aqMGS23svWAllfOaxbuFvcT8D1i8z3Gyn8fraVeZNNmN6e9bxxXkKw==}
 
   /w3c-keyname@2.2.8:
     resolution: {integrity: sha512-dpojBhNsCNN7T82Tm7k26A6G9ML3NkhDsnw9n/eoxSRlVBB4CEtIQ/KTCLI2Fwf3ataSXRhYFkQi3SlnFwPvPQ==}
@@ -13943,13 +14941,13 @@ packages:
     dependencies:
       defaults: 1.0.4
 
-  /weaviate-ts-client@1.4.0(graphql@16.7.1):
+  /weaviate-ts-client@1.4.0(graphql@16.8.1):
     resolution: {integrity: sha512-G2V/IWMHXDjoJeATUYKkZXzAs7iRj4GE8B3AX59XDqMRW12X7VUkRgo4xWcHH1bjpLIHUYTzD5qZXcB8P9Hdmw==}
     engines: {node: '>=16.0.0'}
     dependencies:
-      graphql-request: 5.2.0(graphql@16.7.1)
+      graphql-request: 5.2.0(graphql@16.8.1)
       isomorphic-fetch: 3.0.0
-      uuid: 9.0.0
+      uuid: 9.0.1
     transitivePeerDependencies:
       - encoding
       - graphql
@@ -13958,6 +14956,11 @@ packages:
   /web-namespaces@2.0.1:
     resolution: {integrity: sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ==}
 
+  /web-streams-polyfill@3.2.1:
+    resolution: {integrity: sha512-e0MO3wdXWKrLbL0DgGnUV7WHVuw9OUvL4hjgnPkIeEvESk74gAITi5G606JtZPp39cd8HA9VQzCIvA49LpPN5Q==}
+    engines: {node: '>= 8'}
+    dev: false
+
   /web-streams-polyfill@4.0.0-beta.3:
     resolution: {integrity: sha512-QW95TCTaHmsYfHDybGMwO5IJIM93I/6vTRk+daHTWFPhwh+C8Cg7j7XyKrwrj8Ib6vYXe0ocYNrmzY4xAAN6ug==}
     engines: {node: '>= 14'}
@@ -13972,8 +14975,8 @@ packages:
     engines: {node: '>=12'}
     dev: false
 
-  /whatwg-fetch@3.6.17:
-    resolution: {integrity: sha512-c4ghIvG6th0eudYwKZY5keb81wtFz9/WeAHAoy8+r18kcWlitUIrmGFQ2rWEl4UCKUilD3zCLHOIPheHx5ypRQ==}
+  /whatwg-fetch@3.6.19:
+    resolution: {integrity: sha512-d67JP4dHSbm2TrpFj8AbO8DnL1JXL5J9u0Kq2xW6d0TFDbCA3Muhdt8orXC22utleTVj7Prqt82baN6RBvnEgw==}
     dev: false
 
   /whatwg-url@11.0.0:
@@ -14019,8 +15022,8 @@ packages:
       load-yaml-file: 0.2.0
       path-exists: 4.0.0
 
-  /which-typed-array@1.1.9:
-    resolution: {integrity: sha512-w9c4xkx6mPidwp7180ckYWfMmvxpjlZuIudNtDf4N/tTAUB8VJbX25qZoAsrtGuYNnGw3pa0AXgbGKRB8/EceA==}
+  /which-typed-array@1.1.11:
+    resolution: {integrity: sha512-qe9UWWpkeG5yzZ0tNYxDmd7vo58HDBc39mZ0xWWpolAGADdFOzkfamWLDxkOWcvHQKVmdTyQdLD4NOfjLWTKew==}
     engines: {node: '>= 0.4'}
     dependencies:
       available-typed-arrays: 1.0.5
@@ -14028,7 +15031,6 @@ packages:
       for-each: 0.3.3
       gopd: 1.0.1
       has-tostringtag: 1.0.0
-      is-typed-array: 1.1.10
     dev: true
 
   /which@2.0.2:
@@ -14081,8 +15083,8 @@ packages:
         optional: true
     dev: false
 
-  /ws@8.13.0:
-    resolution: {integrity: sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA==}
+  /ws@8.14.2:
+    resolution: {integrity: sha512-wEBG1ftX4jcglPxgFCMJmZ2PLtSbJ2Peg6TmpJFTbe9GZYOQCDPdMYu/Tm0/bGZkw8paZnJY45J4K2PZrLYq8g==}
     engines: {node: '>=10.0.0'}
     peerDependencies:
       bufferutil: ^4.0.1
@@ -14099,7 +15101,7 @@ packages:
     engines: {node: '>=0.4'}
     dev: false
 
-  /y-prosemirror@1.0.20(prosemirror-model@1.19.2)(prosemirror-state@1.4.3)(prosemirror-view@1.31.4)(y-protocols@1.0.5)(yjs@13.6.7):
+  /y-prosemirror@1.0.20(prosemirror-model@1.19.3)(prosemirror-state@1.4.3)(prosemirror-view@1.32.0)(y-protocols@1.0.5)(yjs@13.6.7):
     resolution: {integrity: sha512-LVMtu3qWo0emeYiP+0jgNcvZkqhzE/otOoro+87q0iVKxy/sMKuiJZnokfJdR4cn9qKx0Un5fIxXqbAlR2bFkA==}
     peerDependencies:
       prosemirror-model: ^1.7.1
@@ -14108,15 +15110,15 @@ packages:
       y-protocols: ^1.0.1
       yjs: ^13.3.2
     dependencies:
-      lib0: 0.2.78
-      prosemirror-model: 1.19.2
+      lib0: 0.2.86
+      prosemirror-model: 1.19.3
       prosemirror-state: 1.4.3
-      prosemirror-view: 1.31.4
+      prosemirror-view: 1.32.0
       y-protocols: 1.0.5
       yjs: 13.6.7
     dev: false
 
-  /y-prosemirror@1.2.1(prosemirror-model@1.19.2)(prosemirror-state@1.4.3)(prosemirror-view@1.31.4)(y-protocols@1.0.5)(yjs@13.6.7):
+  /y-prosemirror@1.2.1(prosemirror-model@1.19.3)(prosemirror-state@1.4.3)(prosemirror-view@1.32.0)(y-protocols@1.0.5)(yjs@13.6.7):
     resolution: {integrity: sha512-czMBfB1eL2awqmOSxQM8cS/fsUOGE6fjvyPLInrh4crPxFiw67wDpwIW+EGBYKRa04sYbS0ScGj7ZgvWuDrmBQ==}
     peerDependencies:
       prosemirror-model: ^1.7.1
@@ -14125,10 +15127,10 @@ packages:
       y-protocols: ^1.0.1
       yjs: ^13.5.38
     dependencies:
-      lib0: 0.2.78
-      prosemirror-model: 1.19.2
+      lib0: 0.2.86
+      prosemirror-model: 1.19.3
       prosemirror-state: 1.4.3
-      prosemirror-view: 1.31.4
+      prosemirror-view: 1.32.0
       y-protocols: 1.0.5
       yjs: 13.6.7
     dev: false
@@ -14136,7 +15138,7 @@ packages:
   /y-protocols@1.0.5:
     resolution: {integrity: sha512-Wil92b7cGk712lRHDqS4T90IczF6RkcvCwAD0A2OPg+adKmOe+nOiT/N2hvpQIWS3zfjmtL4CPaH5sIW1Hkm/A==}
     dependencies:
-      lib0: 0.2.78
+      lib0: 0.2.86
     dev: false
 
   /yallist@3.1.1:
@@ -14163,7 +15165,7 @@ packages:
     resolution: {integrity: sha512-mCZTh4kjvUS2DnaktsYN6wLH3WZCJBLqrTdkWh1bIDpA/sB/GNFaLA/dyVJj2Hc7KwONuuoC/vWe9bwBBosZLQ==}
     engines: {node: '>=16.0.0', npm: '>=8.0.0'}
     dependencies:
-      lib0: 0.2.78
+      lib0: 0.2.86
     dev: false
 
   /yocto-queue@0.1.0:
@@ -14189,12 +15191,12 @@ packages:
       zod: 3.21.4
     dev: false
 
-  /zod-to-json-schema@3.21.4(zod@3.22.2):
+  /zod-to-json-schema@3.21.4(zod@3.22.4):
     resolution: {integrity: sha512-fjUZh4nQ1s6HMccgIeE0VP4QG/YRGPmyjO9sAh890aQKPEk3nqbfUXhMFaC+Dr5KvYBm8BCyvfpZf2jY9aGSsw==}
     peerDependencies:
       zod: ^3.21.4
     dependencies:
-      zod: 3.22.2
+      zod: 3.22.4
     dev: false
 
   /zod@3.21.1:
@@ -14203,8 +15205,8 @@ packages:
   /zod@3.21.4:
     resolution: {integrity: sha512-m46AKbrzKVzOzs/DZgVnG5H55N1sv1M8qZU3A8RIKbs3mrACDNeIOeilDymVb2HdmP8uwshOCF4uJ8uM9rCqJw==}
 
-  /zod@3.22.2:
-    resolution: {integrity: sha512-wvWkphh5WQsJbVk1tbx1l1Ly4yg+XecD+Mq280uBGt9wa5BKSWf4Mhp6GmrkPixhMxmabYY7RbzlwVP32pbGCg==}
+  /zod@3.22.4:
+    resolution: {integrity: sha512-iC+8Io04lddc+mVqQ9AZ7OQ2MrUKGN+oIQyq1vemgt46jwCwLfhq7/pwnBnNXXXZb8VTVLKwp9EDkx+ryxIWmg==}
 
   /zwitch@2.0.4:
     resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==}

programming_language: HTML