@arabold/docs-mcp-server 1.11.0 → 1.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +93 -13
- package/db/migrations/000-initial-schema.sql +57 -0
- package/db/migrations/001-add-indexed-at-column.sql +6 -0
- package/dist/DocumentManagementService-_qCZ1Hi2.js +3409 -0
- package/dist/DocumentManagementService-_qCZ1Hi2.js.map +1 -0
- package/dist/EmbeddingFactory-BJMbJvje.js +174 -0
- package/dist/EmbeddingFactory-BJMbJvje.js.map +1 -0
- package/dist/FindVersionTool-CH1c3Tyu.js +170 -0
- package/dist/FindVersionTool-CH1c3Tyu.js.map +1 -0
- package/dist/RemoveTool-DmB1YJTA.js +65 -0
- package/dist/RemoveTool-DmB1YJTA.js.map +1 -0
- package/dist/assets/main.css +1 -0
- package/dist/assets/main.js +8097 -0
- package/dist/assets/main.js.map +1 -0
- package/dist/cli.js +48 -142
- package/dist/cli.js.map +1 -1
- package/dist/server.js +179 -88
- package/dist/server.js.map +1 -1
- package/dist/web.js +937 -0
- package/dist/web.js.map +1 -0
- package/package.json +34 -10
- package/public/assets/main.css +1 -0
- package/public/assets/main.js +8097 -0
- package/public/assets/main.js.map +1 -0
- package/dist/EmbeddingFactory-6UEXNF44.js +0 -1177
- package/dist/EmbeddingFactory-6UEXNF44.js.map +0 -1
- package/dist/chunk-VF2RUEVV.js +0 -12094
- package/dist/chunk-VF2RUEVV.js.map +0 -1
- package/dist/chunk-YCXNASA6.js +0 -124
- package/dist/chunk-YCXNASA6.js.map +0 -1
- package/dist/cli.d.ts +0 -1
- package/dist/server.d.ts +0 -1
package/dist/web.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"web.js","sources":["../src/web/components/Layout.tsx","../src/web/routes/index.tsx","../src/web/components/VersionBadge.tsx","../src/web/components/JobItem.tsx","../src/web/components/JobList.tsx","../src/web/routes/jobs/list.tsx","../src/web/components/ScrapeFormContent.tsx","../src/web/components/ScrapeForm.tsx","../src/web/components/Alert.tsx","../src/web/routes/jobs/new.tsx","../src/web/components/LoadingSpinner.tsx","../src/web/components/VersionDetailsRow.tsx","../src/web/components/LibraryDetailCard.tsx","../src/web/components/LibrarySearchCard.tsx","../src/web/components/SearchResultItem.tsx","../src/web/components/SearchResultList.tsx","../src/web/components/SearchResultSkeletonItem.tsx","../src/web/routes/libraries/detail.tsx","../src/web/components/LibraryItem.tsx","../src/web/components/LibraryList.tsx","../src/web/routes/libraries/list.tsx","../src/web/web.ts","../src/web.ts"],"sourcesContent":["import type { PropsWithChildren } from \"@kitajs/html\";\n\n/**\n * Props for the Layout component.\n */\ninterface LayoutProps extends PropsWithChildren {\n title: string;\n}\n\n/**\n * Base HTML layout component for all pages.\n * Includes common head elements, header, and scripts.\n * @param props - Component props including title and children.\n */\nconst Layout = ({ title, children }: LayoutProps) => (\n <html lang=\"en\">\n <head>\n <meta charset=\"UTF-8\" />\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n <title safe>{title}</title>\n {/* Bundled CSS (includes Tailwind and Flowbite) */}\n <link rel=\"stylesheet\" href=\"/assets/main.css\" />\n {/* Add style for htmx-indicator behavior (needed globally) */}\n <style>\n {`\n .htmx-indicator {\n display: none;\n }\n .htmx-request .htmx-indicator {\n display: block;\n }\n .htmx-request.htmx-indicator {\n display: block;\n }\n /* Default: Hide skeleton, show results container */\n #searchResultsContainer .search-skeleton { display: none; }\n #searchResultsContainer .search-results { display: block; } /* Or as needed */\n\n /* Request in progress: Show skeleton, hide results */\n #searchResultsContainer.htmx-request .search-skeleton { display: block; } /* Or flex etc. */\n #searchResultsContainer.htmx-request .search-results { display: none; }\n\n /* Keep button spinner logic */\n form .htmx-indicator .spinner { display: flex; }\n form .htmx-indicator .search-text { display: none; }\n form .spinner { display: none; }\n `}\n </style>\n </head>\n <body class=\"bg-gray-50 dark:bg-gray-900\">\n <div class=\"container max-w-2xl mx-auto px-4 py-4\">\n <header class=\"mb-4\">\n <h1 class=\"text-3xl font-bold text-gray-900 dark:text-white\">\n <a href=\"/\">MCP Docs</a>\n </h1>\n </header>\n\n <main>{children}</main>\n </div>\n\n {/* Bundled JS (includes Flowbite, HTMX, AlpineJS, and initialization) */}\n <script type=\"module\" src=\"/assets/main.js\"></script>\n </body>\n </html>\n);\n\nexport default Layout;\n","import type { FastifyInstance } from \"fastify\";\nimport Layout from \"../components/Layout\"; // Import the Layout component\n\n/**\n * Registers the root route that serves the main HTML page.\n * @param server - The Fastify instance.\n */\nexport function registerIndexRoute(server: FastifyInstance) {\n server.get(\"/\", async (_, reply) => {\n reply.type(\"text/html\");\n // Use the Layout component and define the main content within it\n return (\n \"<!DOCTYPE html>\" +\n (\n <Layout title=\"MCP Docs\">\n {/* Job Queue Section */}\n <section class=\"mb-4 p-4 bg-white rounded-lg shadow dark:bg-gray-800 border border-gray-300 dark:border-gray-600\">\n <h2 class=\"text-xl font-semibold mb-2 text-gray-900 dark:text-white\">\n Job Queue\n </h2>\n {/* Container for the job list, loaded via HTMX */}\n <div id=\"jobQueue\" hx-get=\"/api/jobs\" hx-trigger=\"load, every 1s\">\n {/* Initial loading state */}\n <div class=\"animate-pulse\">\n <div class=\"h-[0.8em] bg-gray-200 rounded-full dark:bg-gray-700 w-48 mb-4\" />\n <div class=\"h-[0.8em] bg-gray-200 rounded-full dark:bg-gray-700 w-full mb-2.5\" />\n <div class=\"h-[0.8em] bg-gray-200 rounded-full dark:bg-gray-700 w-full mb-2.5\" />\n </div>\n </div>\n </section>\n {/* Add New Job Section */}\n <section class=\"mb-8\">\n {/* Container for the add job form, loaded via HTMX */}\n <div id=\"addJobForm\" hx-get=\"/api/jobs/new\" hx-trigger=\"load\">\n {/* Initial loading state (optional, could just be empty) */}\n <div class=\"p-6 bg-white rounded-lg shadow dark:bg-gray-800 animate-pulse\">\n <div class=\"h-6 bg-gray-200 rounded-full dark:bg-gray-700 w-1/3 mb-4\" />\n <div class=\"h-[0.8em] bg-gray-200 rounded-full dark:bg-gray-700 w-full mb-2.5\" />\n <div class=\"h-[0.8em] bg-gray-200 rounded-full dark:bg-gray-700 w-full mb-2.5\" />\n </div>\n </div>\n </section>\n {/* Indexed Documentation Section */}\n <div>\n <h2 class=\"text-xl font-semibold mb-2 text-gray-900 dark:text-white\">\n Indexed Documentation\n </h2>\n <div\n id=\"indexedDocs\"\n hx-get=\"/api/libraries\"\n hx-trigger=\"load, every 10s\"\n >\n <div class=\"animate-pulse\">\n <div class=\"h-[0.8em] bg-gray-200 rounded-full dark:bg-gray-700 w-48 mb-4\" />\n <div class=\"h-[0.8em] bg-gray-200 rounded-full dark:bg-gray-700 w-full mb-2.5\" />\n <div class=\"h-[0.8em] bg-gray-200 rounded-full dark:bg-gray-700 w-full mb-2.5\" />\n </div>\n </div>\n </div>\n </Layout>\n )\n );\n });\n}\n","interface VersionBadgeProps {\n version: string;\n}\n\nconst VersionBadge = ({ version }: VersionBadgeProps) => {\n if (!version) {\n return null; // Don't render if no version is provided\n }\n\n return (\n <span class=\"bg-purple-100 text-purple-800 text-xs font-medium me-2 px-1.5 py-0.5 rounded dark:bg-purple-900 dark:text-purple-300\">\n <span safe>{version}</span>\n </span>\n );\n};\n\nexport default VersionBadge;\n","import type { JobInfo } from \"../../tools/GetJobInfoTool\";\nimport { PipelineJobStatus } from \"../../pipeline/types\";\nimport VersionBadge from \"./VersionBadge\"; // Adjusted import path\n\n/**\n * Props for the JobItem component.\n */\ninterface JobItemProps {\n job: JobInfo;\n}\n\n/**\n * Renders a single job item with its details and status.\n * @param props - Component props including the job information.\n */\nconst JobItem = ({ job }: JobItemProps) => (\n // Use Flowbite Card structure with reduced padding and added border\n <div class=\"block p-2 bg-gray-50 dark:bg-gray-700 rounded-lg border border-gray-200 dark:border-gray-600\">\n <div class=\"flex items-center justify-between\">\n <div>\n <p class=\"text-sm font-medium text-gray-900 dark:text-white\">\n <span safe>{job.library}</span>{\" \"}\n {/* Display version as badge if exists */}\n <VersionBadge version={job.version} />\n </p>\n <p class=\"text-sm text-gray-500 dark:text-gray-400\">\n Indexed: <span safe>{new Date(job.createdAt).toLocaleString()}</span>\n </p>\n </div>\n <div class=\"flex flex-col items-end gap-1\">\n {/* Use Flowbite Badge for status with dynamic color */}\n <span\n class={`px-1.5 py-0.5 text-xs font-medium me-2 rounded ${\n job.status === PipelineJobStatus.COMPLETED\n ? \"bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-300\"\n : job.error\n ? \"bg-red-100 text-red-800 dark:bg-red-900 dark:text-red-300\"\n : \"bg-blue-100 text-blue-800 dark:bg-blue-900 dark:text-blue-300\"\n }`}\n >\n {job.status}\n </span>\n {job.error && (\n // Keep the error badge for clarity if an error occurred\n <span class=\"bg-red-100 text-red-800 text-xs font-medium me-2 px-1.5 py-0.5 rounded dark:bg-red-900 dark:text-red-300\">\n Error\n </span>\n )}\n </div>\n </div>\n </div>\n);\n\nexport default JobItem;\n","import type { JobInfo } from \"../../tools/GetJobInfoTool\";\nimport JobItem from \"./JobItem\"; // Adjusted import path\n\n/**\n * Props for the JobList component.\n */\ninterface JobListProps {\n jobs: JobInfo[];\n}\n\n/**\n * Renders a list of JobItem components or a message if the list is empty.\n * @param props - Component props including the array of jobs.\n */\nconst JobList = ({ jobs }: JobListProps) => (\n <div class=\"space-y-2\">\n {jobs.length === 0 ? (\n <p class=\"text-center text-gray-500 dark:text-gray-400\">\n No pending jobs.\n </p>\n ) : (\n jobs.map((job) => <JobItem job={job} />)\n )}\n </div>\n);\n\nexport default JobList;\n","import type { FastifyInstance } from \"fastify\";\nimport type { ListJobsTool } from \"../../../tools/ListJobsTool\"; // Adjusted import path\nimport JobList from \"../../components/JobList\"; // Import the extracted component\n\n/**\n * Registers the API route for listing jobs.\n * @param server - The Fastify instance.\n * @param listJobsTool - The tool instance for listing jobs.\n */\nexport function registerJobListRoutes(\n server: FastifyInstance,\n listJobsTool: ListJobsTool\n) {\n // GET /api/jobs - List current jobs (only the list)\n server.get(\"/api/jobs\", async () => {\n const result = await listJobsTool.execute({});\n return <JobList jobs={result.jobs} />;\n });\n}\n","import { ScrapeMode } from \"../../scraper/types\"; // Adjusted import path\n\n/**\n * Renders the form fields for queuing a new scrape job.\n * Includes basic fields (URL, Library, Version) and advanced options.\n */\nconst ScrapeFormContent = () => (\n <div class=\"mt-4 p-4 bg-white dark:bg-gray-800 rounded-lg shadow border border-gray-300 dark:border-gray-600\">\n <h3 class=\"text-xl font-semibold text-gray-900 dark:text-white mb-2\">\n Queue New Scrape Job\n </h3>\n <form\n hx-post=\"/api/jobs/scrape\"\n hx-target=\"#job-response\"\n hx-swap=\"innerHTML\"\n class=\"space-y-2\"\n >\n <div>\n <label\n for=\"url\"\n class=\"block text-sm font-medium text-gray-700 dark:text-gray-300\"\n >\n URL\n </label>\n <input\n type=\"url\"\n name=\"url\"\n id=\"url\"\n required\n class=\"mt-0.5 block w-full px-2 py-1 border border-gray-300 dark:border-gray-600 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm bg-white dark:bg-gray-700 text-gray-900 dark:text-white\"\n />\n </div>\n <div>\n <label\n for=\"library\"\n class=\"block text-sm font-medium text-gray-700 dark:text-gray-300\"\n >\n Library Name\n </label>\n <input\n type=\"text\"\n name=\"library\"\n id=\"library\"\n required\n class=\"mt-0.5 block w-full px-2 py-1 border border-gray-300 dark:border-gray-600 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm bg-white dark:bg-gray-700 text-gray-900 dark:text-white\"\n />\n </div>\n <div>\n <label\n for=\"version\"\n class=\"block text-sm font-medium text-gray-700 dark:text-gray-300\"\n >\n Version (optional)\n </label>\n <input\n type=\"text\"\n name=\"version\"\n id=\"version\"\n class=\"mt-0.5 block w-full max-w-sm px-2 py-1 border border-gray-300 dark:border-gray-600 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm bg-white dark:bg-gray-700 text-gray-900 dark:text-white\"\n />\n </div>\n\n {/* Consider using Flowbite Accordion here */}\n <details class=\"bg-gray-50 dark:bg-gray-900 p-2 rounded-md\">\n <summary class=\"cursor-pointer text-sm font-medium text-gray-600 dark:text-gray-400\">\n Advanced Options\n </summary>\n <div class=\"mt-2 space-y-2\">\n <div>\n <label\n for=\"maxPages\"\n class=\"block text-sm font-medium text-gray-700 dark:text-gray-300\"\n >\n Max Pages\n </label>\n <input\n type=\"number\"\n name=\"maxPages\"\n id=\"maxPages\"\n min=\"1\"\n placeholder=\"1000\"\n class=\"mt-0.5 block w-full max-w-sm px-2 py-1 border border-gray-300 dark:border-gray-600 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm bg-white dark:bg-gray-700 text-gray-900 dark:text-white\"\n />\n </div>\n <div>\n <label\n for=\"maxDepth\"\n class=\"block text-sm font-medium text-gray-700 dark:text-gray-300\"\n >\n Max Depth\n </label>\n <input\n type=\"number\"\n name=\"maxDepth\"\n id=\"maxDepth\"\n min=\"0\"\n placeholder=\"3\"\n class=\"mt-0.5 block w-full max-w-sm px-2 py-1 border border-gray-300 dark:border-gray-600 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm bg-white dark:bg-gray-700 text-gray-900 dark:text-white\"\n />\n </div>\n <div>\n <label\n for=\"scope\"\n class=\"block text-sm font-medium text-gray-700 dark:text-gray-300\"\n >\n Scope\n </label>\n <select\n name=\"scope\"\n id=\"scope\"\n class=\"mt-0.5 block w-full max-w-sm pl-2 pr-10 py-1 text-base border border-gray-300 dark:border-gray-600 focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm rounded-md bg-white dark:bg-gray-700 text-gray-900 dark:text-white\"\n >\n <option value=\"subpages\" selected>\n Subpages (Default)\n </option>\n <option value=\"hostname\">Hostname</option>\n <option value=\"domain\">Domain</option>\n </select>\n </div>\n <div>\n <label\n for=\"scrapeMode\"\n class=\"block text-sm font-medium text-gray-700 dark:text-gray-300\"\n >\n Scrape Mode\n </label>\n <select\n name=\"scrapeMode\"\n id=\"scrapeMode\"\n class=\"mt-0.5 block w-full max-w-sm pl-2 pr-10 py-1 text-base border border-gray-300 dark:border-gray-600 focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm rounded-md bg-white dark:bg-gray-700 text-gray-900 dark:text-white\"\n >\n <option value={ScrapeMode.Auto} selected>\n Auto (Default)\n </option>\n <option value={ScrapeMode.Fetch}>Fetch</option>\n <option value={ScrapeMode.Playwright}>Playwright</option>\n </select>\n </div>\n <div class=\"flex items-center\">\n <input\n id=\"followRedirects\"\n name=\"followRedirects\"\n type=\"checkbox\"\n checked\n class=\"h-4 w-4 text-indigo-600 focus:ring-indigo-500 border-gray-300 dark:border-gray-600 rounded bg-white dark:bg-gray-700\"\n />\n <label\n for=\"followRedirects\"\n class=\"ml-1 block text-sm text-gray-900 dark:text-gray-300\"\n >\n Follow Redirects\n </label>\n </div>\n <div class=\"flex items-center\">\n <input\n id=\"ignoreErrors\"\n name=\"ignoreErrors\"\n type=\"checkbox\"\n checked\n class=\"h-4 w-4 text-indigo-600 focus:ring-indigo-500 border-gray-300 dark:border-gray-600 rounded bg-white dark:bg-gray-700\"\n />\n <label\n for=\"ignoreErrors\"\n class=\"ml-1 block text-sm text-gray-900 dark:text-gray-300\"\n >\n Ignore Errors During Scraping\n </label>\n </div>\n </div>\n </details>\n\n <div>\n <button\n type=\"submit\"\n class=\"w-full flex justify-center py-1.5 px-3 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-indigo-600 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500\"\n >\n Queue Job\n </button>\n </div>\n </form>\n {/* Target div for HTMX response */}\n <div id=\"job-response\" class=\"mt-2 text-sm\"></div>\n </div>\n);\n\nexport default ScrapeFormContent;\n","import ScrapeFormContent from \"./ScrapeFormContent\"; // Adjusted import path\n\n/**\n * Wrapper component for the ScrapeFormContent.\n * Provides a container div, often used as a target for HTMX OOB swaps.\n */\nconst ScrapeForm = () => (\n <div id=\"scrape-form-container\">\n <ScrapeFormContent />\n </div>\n);\n\nexport default ScrapeForm;\n","import type { PropsWithChildren } from \"@kitajs/html\";\n\n/**\n * Defines the possible types for the Alert component.\n */\ntype AlertType = \"success\" | \"error\" | \"warning\" | \"info\";\n\n/**\n * Props for the Alert component.\n */\ninterface AlertProps extends PropsWithChildren {\n type: AlertType;\n title?: string;\n message: string | JSX.Element; // Allow JSX for messages\n}\n\n/**\n * Reusable Alert component using Flowbite styling.\n * Displays messages with appropriate colors and icons based on the type.\n * @param props - Component props including type, title (optional), and message.\n */\nconst Alert = ({ type, title, message }: AlertProps) => {\n let iconSvg: JSX.Element;\n let colorClasses: string;\n let defaultTitle: string;\n\n switch (type) {\n case \"success\":\n defaultTitle = \"Success:\";\n colorClasses =\n \"text-green-800 border-green-300 bg-green-50 dark:bg-gray-800 dark:text-green-400 dark:border-green-800\";\n iconSvg = (\n <svg\n class=\"flex-shrink-0 inline w-4 h-4 me-3\"\n aria-hidden=\"true\"\n xmlns=\"http://www.w3.org/2000/svg\"\n fill=\"currentColor\"\n viewBox=\"0 0 20 20\"\n >\n <path d=\"M10 .5a9.5 9.5 0 1 0 9.5 9.5A9.51 9.51 0 0 0 10 .5Zm9.5 9.5A9.5 9.5 0 0 1 10 19a9.46 9.46 0 0 1-1.671-.14c-.165-.05-.3-.19-.42-.335l-.165-.165c-.19-.2-.3-.425-.3-.655A4.2 4.2 0 0 1 4.5 10a4.25 4.25 0 0 1 7.462-2.882l1.217 1.217a3.175 3.175 0 0 0 4.5.01l.106-.106a.934.934 0 0 0 .1-.36ZM10 11a1 1 0 1 0 0 2 1 1 0 0 0 0-2Z\" />\n </svg>\n );\n break;\n case \"error\":\n defaultTitle = \"Error:\";\n colorClasses =\n \"text-red-800 border-red-300 bg-red-50 dark:bg-gray-800 dark:text-red-400 dark:border-red-800\";\n iconSvg = (\n <svg\n class=\"flex-shrink-0 inline w-4 h-4 me-3\"\n aria-hidden=\"true\"\n xmlns=\"http://www.w3.org/2000/svg\"\n fill=\"currentColor\"\n viewBox=\"0 0 20 20\"\n >\n <path d=\"M10 .5a9.5 9.5 0 1 0 9.5 9.5A9.51 9.51 0 0 0 10 .5ZM9.5 4a1.5 1.5 0 1 1 0 3 1.5 1.5 0 0 1 0-3ZM12 15H8a1 1 0 0 1 0-2h1v-3h-1a1 1 0 0 1 0-2h2a1 1 0 0 1 1 1v4h1a1 1 0 0 1 0 2Z\" />\n </svg>\n );\n break;\n case \"warning\":\n defaultTitle = \"Warning:\";\n colorClasses =\n \"text-yellow-800 border-yellow-300 bg-yellow-50 dark:bg-gray-800 dark:text-yellow-300 dark:border-yellow-800\";\n iconSvg = (\n <svg\n class=\"flex-shrink-0 inline w-4 h-4 me-3\"\n aria-hidden=\"true\"\n xmlns=\"http://www.w3.org/2000/svg\"\n fill=\"currentColor\"\n viewBox=\"0 0 20 20\"\n >\n <path d=\"M10 .5a9.5 9.5 0 1 0 9.5 9.5A9.51 9.51 0 0 0 10 .5ZM9.5 4a1.5 1.5 0 1 1 0 3 1.5 1.5 0 0 1 0-3ZM12 15H8a1 1 0 0 1 0-2h1v-3h-1a1 1 0 0 1 0-2h2a1 1 0 0 1 1 1v4h1a1 1 0 0 1 0 2Z\" />\n </svg>\n );\n break;\n case \"info\":\n default: // Default to info style\n defaultTitle = \"Info:\";\n colorClasses =\n \"text-blue-800 border-blue-300 bg-blue-50 dark:bg-gray-800 dark:text-blue-400 dark:border-blue-800\";\n iconSvg = (\n <svg\n class=\"flex-shrink-0 inline w-4 h-4 me-3\"\n aria-hidden=\"true\"\n xmlns=\"http://www.w3.org/2000/svg\"\n fill=\"currentColor\"\n viewBox=\"0 0 20 20\"\n >\n <path d=\"M10 .5a9.5 9.5 0 1 0 9.5 9.5A9.51 9.51 0 0 0 10 .5ZM9.5 4a1.5 1.5 0 1 1 0 3 1.5 1.5 0 0 1 0-3ZM12 15H8a1 1 0 0 1 0-2h1v-3H8a1 1 0 0 1 0-2h2a1 1 0 0 1 1 1v4h1a1 1 0 0 1 0 2Z\" />\n </svg>\n );\n break;\n }\n\n const displayTitle = title ?? defaultTitle;\n\n return (\n <div\n class={`flex items-center p-4 mb-4 text-sm border rounded-lg ${colorClasses}`}\n role=\"alert\"\n >\n {iconSvg}\n <span class=\"sr-only\">Info</span>\n <div>\n {displayTitle ? (\n <span class=\"font-medium\" safe>\n {displayTitle}\n </span>\n ) : null}{\" \"}\n {message}\n </div>\n </div>\n );\n};\n\nexport default Alert;\n","import type { FastifyInstance, FastifyRequest } from \"fastify\";\nimport type { ScrapeTool } from \"../../../tools/ScrapeTool\"; // Adjusted import path\nimport { ScrapeMode } from \"../../../scraper/types\"; // Adjusted import path\nimport { logger } from \"../../../utils/logger\"; // Adjusted import path\nimport ScrapeForm from \"../../components/ScrapeForm\"; // Import extracted component\nimport Alert from \"../../components/Alert\"; // Import Alert component\nimport ScrapeFormContent from \"../../components/ScrapeFormContent\"; // Import for OOB swap\n\n/**\n * Registers the API routes for creating new jobs.\n * @param server - The Fastify instance.\n * @param scrapeTool - The tool instance for scraping documents.\n */\nexport function registerNewJobRoutes(\n server: FastifyInstance,\n scrapeTool: ScrapeTool\n) {\n // GET /api/jobs/new - Return the form component wrapped in its container\n server.get(\"/api/jobs/new\", async () => {\n // Return the wrapper component which includes the container div\n return <ScrapeForm />;\n });\n\n // POST /api/jobs/scrape - Queue a new scrape job\n server.post(\n \"/api/jobs/scrape\",\n async (\n request: FastifyRequest<{\n Body: {\n url: string;\n library: string;\n version?: string;\n maxPages?: string;\n maxDepth?: string;\n scope?: \"subpages\" | \"hostname\" | \"domain\";\n scrapeMode?: ScrapeMode;\n followRedirects?: \"on\" | undefined; // Checkbox value is 'on' if checked\n ignoreErrors?: \"on\" | undefined;\n };\n }>,\n reply\n ) => {\n const body = request.body;\n reply.type(\"text/html\"); // Set content type for all responses from this handler\n try {\n // Basic validation\n if (!body.url || !body.library) {\n reply.status(400);\n // Use Alert component for validation error\n return (\n <Alert\n type=\"error\"\n title=\"Validation Error:\"\n message=\"URL and Library Name are required.\"\n />\n );\n }\n\n // Prepare options for ScrapeTool\n const scrapeOptions = {\n url: body.url,\n library: body.library,\n version: body.version || null, // Handle empty string as null\n waitForCompletion: false, // Don't wait in UI\n options: {\n maxPages: body.maxPages\n ? Number.parseInt(body.maxPages, 10)\n : undefined,\n maxDepth: body.maxDepth\n ? Number.parseInt(body.maxDepth, 10)\n : undefined,\n scope: body.scope,\n scrapeMode: body.scrapeMode,\n // Checkboxes send 'on' when checked, otherwise undefined\n followRedirects: body.followRedirects === \"on\",\n ignoreErrors: body.ignoreErrors === \"on\",\n },\n };\n\n // Execute the scrape tool\n const result = await scrapeTool.execute(scrapeOptions);\n\n if (\"jobId\" in result) {\n // Success: Use Alert component and OOB swap\n return (\n <>\n {/* Main target response */}\n <Alert\n type=\"success\"\n message={\n <>\n Job queued successfully! ID:{\" \"}\n <span safe>{result.jobId}</span>\n </>\n }\n />\n {/* OOB target response - contains only the inner form content */}\n <div id=\"scrape-form-container\" hx-swap-oob=\"innerHTML\">\n <ScrapeFormContent />\n </div>\n </>\n );\n }\n\n // This case shouldn't happen with waitForCompletion: false, but handle defensively\n // Use Alert component for unexpected success\n return (\n <Alert type=\"warning\" message=\"Job finished unexpectedly quickly.\" />\n );\n } catch (error) {\n const errorMessage =\n error instanceof Error ? error.message : \"Unknown error\";\n logger.error(`Scrape job submission failed: ${error}`);\n reply.status(500); // Keep status code for errors\n // Use Alert component for server error\n return (\n <Alert\n type=\"error\"\n message={<>Failed to queue job: {errorMessage}</>}\n />\n );\n }\n }\n );\n}\n","/**\n * Renders an SVG loading spinner icon.\n * Used for indicating loading states in buttons or other elements.\n */\nconst LoadingSpinner = () => (\n <svg\n class=\"animate-spin h-4 w-4 text-white\" // Adjusted size to h-4 w-4 to match usage\n xmlns=\"http://www.w3.org/2000/svg\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n >\n <circle\n class=\"opacity-25\"\n cx=\"12\"\n cy=\"12\"\n r=\"10\"\n stroke=\"currentColor\"\n stroke-width=\"4\"\n ></circle>\n <path\n class=\"opacity-75\"\n fill=\"currentColor\"\n d=\"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z\"\n ></path>\n </svg>\n);\n\nexport default LoadingSpinner;\n","import type { LibraryVersionDetails } from \"../../store/types\";\nimport VersionBadge from \"./VersionBadge\"; // Adjusted import path\nimport LoadingSpinner from \"./LoadingSpinner\"; // Import spinner\n\n/**\n * Props for the VersionDetailsRow component.\n */\ninterface VersionDetailsRowProps {\n version: LibraryVersionDetails;\n libraryName: string;\n showDelete?: boolean; // Optional prop to control delete button visibility\n}\n\n/**\n * Renders details for a single library version in a row format.\n * Includes version, stats, and an optional delete button.\n * @param props - Component props including version, libraryName, and showDelete flag.\n */\nconst VersionDetailsRow = ({\n version,\n libraryName,\n showDelete = true, // Default to true\n}: VersionDetailsRowProps) => {\n // Format the indexed date nicely, handle null case\n const indexedDate = version.indexedAt\n ? new Date(version.indexedAt).toLocaleDateString()\n : \"N/A\";\n // Display 'Unversioned' if version string is empty\n const versionLabel = version.version || \"Unversioned\";\n const versionParam = version.version || \"unversioned\"; // Use consistent param for URL\n\n // Generate unique IDs for the row, ensuring it's a valid CSS selector\n // Replace periods and other potentially invalid characters with hyphens\n const sanitizedVersionParam = versionParam.replace(/[^a-zA-Z0-9-_]/g, \"-\");\n const rowId = `row-${libraryName}-${sanitizedVersionParam}`;\n\n // Define state-specific button classes for Alpine toggling\n const defaultStateClasses =\n \"text-red-700 border border-red-700 hover:bg-red-700 hover:text-white focus:ring-4 focus:outline-none focus:ring-red-300 dark:border-red-500 dark:text-red-500 dark:hover:text-white dark:focus:ring-red-800 dark:hover:bg-red-500\";\n const confirmingStateClasses =\n \"bg-red-600 text-white border-red-600 focus:ring-4 focus:outline-none focus:ring-red-300 dark:bg-red-700 dark:border-red-700 dark:focus:ring-red-800\";\n\n return (\n // Use flexbox for layout, add border between rows\n <div\n id={rowId}\n class=\"flex justify-between items-center py-1 border-b border-gray-200 dark:border-gray-600 last:border-b-0\"\n >\n {/* Version Label */}\n <span\n class=\"text-sm text-gray-900 dark:text-white w-1/4 truncate\"\n title={versionLabel}\n >\n {version.version ? (\n <VersionBadge version={version.version} />\n ) : (\n <span>Unversioned</span>\n )}\n </span>\n\n {/* Stats Group */}\n <div class=\"flex space-x-2 text-sm text-gray-600 dark:text-gray-400 w-3/4 justify-end items-center\">\n <span title=\"Number of unique pages indexed\">\n Pages:{\" \"}\n <span class=\"font-semibold\" safe>\n {version.uniqueUrlCount.toLocaleString()}\n </span>\n </span>\n <span title=\"Number of indexed snippets\">\n Snippets:{\" \"}\n <span class=\"font-semibold\" safe>\n {version.documentCount.toLocaleString()}\n </span>\n </span>\n <span title=\"Date last indexed\">\n Last Update:{\" \"}\n <span class=\"font-semibold\" safe>\n {indexedDate}\n </span>\n </span>\n </div>\n\n {/* Conditionally render the delete button */}\n {showDelete && (\n <button\n type=\"button\"\n class=\"ml-2 font-medium rounded-lg text-sm p-1 text-center inline-flex items-center transition-colors duration-150 ease-in-out\"\n title=\"Remove this version\"\n x-data=\"{ confirming: false, isDeleting: false, timeoutId: null }\" // Minimal state in x-data\n x-bind:class={`confirming ? \"${confirmingStateClasses}\" : \"${defaultStateClasses}\"`} // Toggle between state classes\n x-bind:disabled=\"isDeleting\"\n x-on:click=\"\n if (confirming) {\n clearTimeout(timeoutId);\n timeoutId = null;\n isDeleting = true; // Set deleting state directly\n // Dispatch a standard browser event instead of calling htmx directly\n $el.dispatchEvent(new CustomEvent('confirmed-delete', { bubbles: true }));\n } else {\n confirming = true;\n timeoutId = setTimeout(() => { confirming = false; timeoutId = null; }, 3000);\n }\n \"\n hx-delete={`/api/libraries/${libraryName}/versions/${versionParam}`}\n hx-target={`#${rowId}`}\n hx-swap=\"outerHTML\"\n hx-trigger=\"confirmed-delete\" // Listen for the standard browser event\n >\n {/* Default State: Trash Icon */}\n <span x-show=\"!confirming && !isDeleting\">\n <svg\n class=\"w-4 h-4\"\n aria-hidden=\"true\"\n xmlns=\"http://www.w3.org/2000/svg\"\n fill=\"none\"\n viewBox=\"0 0 18 20\"\n >\n <path\n stroke=\"currentColor\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n stroke-width=\"2\"\n d=\"M1 5h16M7 8v8m4-8v8M7 1h4a1 1 0 0 1 1 1v3H6V2a1 1 0 0 1 1-1ZM3 5h12v13a1 1 0 0 1-1 1H4a1 1 0 0 1-1-1V5Z\"\n />\n </svg>\n <span class=\"sr-only\">Remove version</span>\n </span>\n\n {/* Confirming State: Text */}\n <span x-show=\"confirming && !isDeleting\">Confirm?</span>\n\n {/* Deleting State: Spinner Icon */}\n <span x-show=\"isDeleting\">\n <LoadingSpinner />\n <span class=\"sr-only\">Loading...</span>\n </span>\n </button>\n )}\n </div>\n );\n};\n\nexport default VersionDetailsRow;\n","import semver from \"semver\";\nimport type { LibraryInfo } from \"../../tools/ListLibrariesTool\";\nimport VersionDetailsRow from \"./VersionDetailsRow\"; // Adjusted import path\n\n/**\n * Props for the LibraryDetailCard component.\n */\ninterface LibraryDetailCardProps {\n library: LibraryInfo;\n}\n\n/**\n * Renders a card displaying library details and its versions.\n * Uses VersionDetailsRow without the delete button.\n * @param props - Component props including the library information.\n */\nconst LibraryDetailCard = ({ library }: LibraryDetailCardProps) => (\n // Use Flowbite Card structure with updated padding and border, and white background\n <div class=\"block p-4 bg-white dark:bg-gray-800 rounded-lg shadow-sm border border-gray-300 dark:border-gray-600 mb-4\">\n <h3 class=\"text-lg font-medium text-gray-900 dark:text-white mb-1\">\n <span safe>{library.name}</span>\n </h3>\n {/* Container for version rows */}\n <div class=\"mt-1\">\n {library.versions.length > 0 ? (\n library.versions\n // Sort versions: unversioned first, then newest semver first.\n .sort((a, b) => {\n // Explicitly place unversioned first\n if (!a.version) return -1;\n if (!b.version) return 1;\n // Then sort by semver, newest first\n return semver.compare(\n semver.coerce(b.version)?.version ?? \"0.0.0\",\n semver.coerce(a.version)?.version ?? \"0.0.0\"\n );\n })\n .map((version) => (\n <VersionDetailsRow\n libraryName={library.name}\n version={version}\n showDelete={false} // Explicitly hide delete button\n />\n ))\n ) : (\n // Display message if no versions are indexed\n <p class=\"text-sm text-gray-500 dark:text-gray-400 italic\">\n No versions indexed.\n </p>\n )}\n </div>\n </div>\n);\n\nexport default LibraryDetailCard;\n","import semver from \"semver\";\nimport type { LibraryInfo } from \"../../tools/ListLibrariesTool\";\nimport LoadingSpinner from \"./LoadingSpinner\"; // Import spinner\n\n/**\n * Props for the LibrarySearchCard component.\n */\ninterface LibrarySearchCardProps {\n library: LibraryInfo;\n}\n\n/**\n * Renders the search form card for a specific library.\n * Includes a version dropdown and query input.\n * @param props - Component props including the library information.\n */\nconst LibrarySearchCard = ({ library }: LibrarySearchCardProps) => {\n // Sort versions for the dropdown: unversioned first, then newest semver first.\n const sortedVersions = library.versions.sort((a, b) => {\n if (!a.version) return -1;\n if (!b.version) return 1;\n return semver.compare(\n semver.coerce(b.version)?.version ?? \"0.0.0\",\n semver.coerce(a.version)?.version ?? \"0.0.0\"\n );\n });\n\n return (\n <div class=\"block p-4 bg-white dark:bg-gray-800 rounded-lg shadow-sm border border-gray-300 dark:border-gray-600 mb-4\">\n <h2 class=\"text-xl font-semibold mb-2 text-gray-900 dark:text-white\" safe>\n Search {library.name} Documentation\n </h2>\n <form\n hx-get={`/api/libraries/${encodeURIComponent(library.name)}/search`}\n hx-target=\"#searchResultsContainer .search-results\"\n hx-swap=\"innerHTML\"\n hx-indicator=\"#searchResultsContainer\"\n class=\"flex space-x-2\"\n >\n <select\n name=\"version\"\n class=\"w-40 bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500\"\n >\n <option value=\"\">Latest</option> {/* Default to latest */}\n {sortedVersions.map((version) => (\n <option value={version.version || \"unversioned\"} safe>\n {version.version || \"Unversioned\"}\n </option>\n ))}\n </select>\n <input\n type=\"text\"\n name=\"query\"\n placeholder=\"Search query...\"\n required\n class=\"flex-grow bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500\"\n />\n <button\n type=\"submit\"\n class=\"text-white bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:outline-none focus:ring-blue-300 font-medium rounded-lg text-sm px-5 py-2.5 text-center dark:bg-blue-600 dark:hover:bg-blue-700 dark:focus:ring-blue-800 relative\"\n >\n <span class=\"search-text\">Search</span>\n {/* Spinner for HTMX loading - shown via htmx-indicator class on parent */}\n <span class=\"spinner absolute inset-0 flex items-center justify-center\">\n <LoadingSpinner />\n </span>\n </button>\n </form>\n {/* Add style for htmx-indicator behavior on button */}\n {/* Styles moved to Layout.tsx */}\n </div>\n );\n};\n\nexport default LibrarySearchCard;\n","import { unified } from \"unified\"; // Import unified\nimport remarkParse from \"remark-parse\"; // Import unified plugins\nimport remarkGfm from \"remark-gfm\";\nimport remarkHtml from \"remark-html\";\nimport DOMPurify from \"dompurify\"; // Import DOMPurify\nimport { createJSDOM } from \"../../utils/dom\"; // Import JSDOM helper\nimport type { StoreSearchResult } from \"../../store/types\";\n\n/**\n * Props for the SearchResultItem component.\n */\ninterface SearchResultItemProps {\n result: StoreSearchResult;\n}\n\n/**\n * Renders a single search result item.\n * Converts markdown content to HTML using unified.\n * @param props - Component props including the search result data.\n */\nconst SearchResultItem = async ({ result }: SearchResultItemProps) => {\n // Use unified pipeline to convert markdown to HTML\n const processor = unified().use(remarkParse).use(remarkGfm).use(remarkHtml);\n const file = await processor.process(result.content);\n const rawHtml = String(file);\n\n // Create JSDOM instance and initialize DOMPurify\n const jsdom = createJSDOM(\"\");\n const purifier = DOMPurify(jsdom.window);\n\n // Sanitize the HTML content\n const safeHtml = purifier.sanitize(rawHtml);\n\n return (\n <div class=\"block px-4 py-2 bg-white dark:bg-gray-800 rounded-lg shadow-sm border border-gray-300 dark:border-gray-600 mb-2\">\n <div class=\"text-sm text-gray-600 dark:text-gray-400 mb-1\">\n <a\n href={result.url}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n class=\"underline underline-offset-4\"\n safe\n >\n {result.url}\n </a>\n </div>\n {/* Render the sanitized HTML content */}\n <div class=\"format dark:format-invert max-w-none\">{safeHtml}</div>\n </div>\n );\n};\n\nexport default SearchResultItem;\n","import type { StoreSearchResult } from \"../../store/types\";\nimport SearchResultItem from \"./SearchResultItem\"; // Adjusted import path\n\n/**\n * Props for the SearchResultList component.\n */\ninterface SearchResultListProps {\n results: StoreSearchResult[];\n}\n\n/**\n * Renders the list of search results using SearchResultItem.\n * Displays a message if no results are found.\n * @param props - Component props including the array of search results.\n */\nconst SearchResultList = ({ results }: SearchResultListProps) => {\n if (results.length === 0) {\n return (\n <p class=\"text-gray-500 dark:text-gray-400 italic\">No results found.</p>\n );\n }\n return (\n <div class=\"space-y-2\">\n {results.map((result) => (\n <SearchResultItem result={result} />\n ))}\n </div>\n );\n};\n\nexport default SearchResultList;\n","/**\n * Renders a skeleton placeholder for a search result item.\n * Used to indicate loading state while search results are being fetched.\n */\nconst SearchResultSkeletonItem = () => (\n <div class=\"block px-4 py-2 bg-white dark:bg-gray-800 rounded-lg shadow-sm mb-2 animate-pulse\">\n <div class=\"h-[0.8em] bg-gray-200 dark:bg-gray-700 rounded w-3/4 mb-2\"></div>\n <div class=\"h-[0.8em] bg-gray-200 dark:bg-gray-700 rounded w-full mb-2\"></div>\n <div class=\"h-[0.8em] bg-gray-200 dark:bg-gray-700 rounded w-5/6\"></div>\n </div>\n);\n\nexport default SearchResultSkeletonItem;\n","import type { FastifyInstance, FastifyReply, FastifyRequest } from \"fastify\";\nimport type { ListLibrariesTool } from \"../../../tools/ListLibrariesTool\";\nimport { SearchTool } from \"../../../tools/SearchTool\";\nimport Layout from \"../../components/Layout\";\nimport LibraryDetailCard from \"../../components/LibraryDetailCard\";\nimport LibrarySearchCard from \"../../components/LibrarySearchCard\";\nimport SearchResultList from \"../../components/SearchResultList\";\nimport SearchResultSkeletonItem from \"../../components/SearchResultSkeletonItem\";\n\n/**\n * Registers the route for displaying library details.\n * @param server - The Fastify instance.\n * @param listLibrariesTool - The tool instance for listing libraries.\n * @param searchTool - The tool instance for searching documentation.\n */\nexport function registerLibraryDetailRoutes(\n server: FastifyInstance,\n listLibrariesTool: ListLibrariesTool,\n searchTool: SearchTool\n) {\n // Route for the library detail page\n server.get(\n \"/libraries/:libraryName\",\n async (\n request: FastifyRequest<{ Params: { libraryName: string } }>,\n reply: FastifyReply\n ) => {\n const { libraryName } = request.params;\n try {\n // Fetch all libraries and find the requested one\n const result = await listLibrariesTool.execute();\n const libraryInfo = result.libraries.find(\n (lib) => lib.name === libraryName\n );\n\n if (!libraryInfo) {\n reply.status(404).send(\"Library not found\");\n return;\n }\n\n reply.type(\"text/html; charset=utf-8\");\n // Use the Layout component\n return (\n \"<!DOCTYPE html>\" +\n (\n <Layout title={`MCP Docs - ${libraryInfo.name}`}>\n {/* Library Detail Card */}\n <LibraryDetailCard library={libraryInfo} />\n\n {/* Library Search Card */}\n <LibrarySearchCard library={libraryInfo} />\n\n {/* Search Results Container */}\n <div id=\"searchResultsContainer\">\n {/* Skeleton loader - Initially present */}\n <div class=\"search-skeleton space-y-2\">\n <SearchResultSkeletonItem />\n <SearchResultSkeletonItem />\n <SearchResultSkeletonItem />\n </div>\n {/* Search results will be loaded here via HTMX */}\n <div class=\"search-results\">\n {/* Initially empty, HTMX will swap content here */}\n </div>\n </div>\n </Layout>\n )\n );\n } catch (error) {\n server.log.error(\n error,\n `Failed to load library details for ${libraryName}`\n );\n reply.status(500).send(\"Internal Server Error\");\n }\n }\n );\n\n // API route for searching a specific library\n server.get(\n \"/api/libraries/:libraryName/search\",\n async (\n request: FastifyRequest<{\n Params: { libraryName: string };\n Querystring: { query: string; version?: string };\n }>,\n reply: FastifyReply\n ) => {\n const { libraryName } = request.params;\n const { query, version } = request.query;\n\n if (!query) {\n reply.status(400).send(\"Search query is required.\");\n return;\n }\n\n // Map \"unversioned\" string to undefined for the tool\n const versionParam = version === \"unversioned\" ? undefined : version;\n\n try {\n const searchResult = await searchTool.execute({\n library: libraryName,\n query,\n version: versionParam,\n limit: 10, // Limit search results\n });\n\n // Return only the results list or error message\n reply.type(\"text/html; charset=utf-8\");\n return <SearchResultList results={searchResult.results} />;\n } catch (error) {\n server.log.error(error, `Failed to search library ${libraryName}`);\n // Return error message on catch\n reply.type(\"text/html; charset=utf-8\");\n return (\n <p class=\"text-red-500 dark:text-red-400 italic\">\n An unexpected error occurred during the search.\n </p>\n );\n }\n }\n );\n}\n","import semver from \"semver\";\nimport type { LibraryInfo } from \"../../tools/ListLibrariesTool\";\nimport VersionDetailsRow from \"./VersionDetailsRow\"; // Adjusted import path\n\n/**\n * Props for the LibraryItem component.\n */\ninterface LibraryItemProps {\n library: LibraryInfo;\n}\n\n/**\n * Renders a card for a single library, listing its versions with details.\n * Uses VersionDetailsRow to display each version.\n * @param props - Component props including the library information.\n */\nconst LibraryItem = ({ library }: LibraryItemProps) => (\n // Use Flowbite Card structure with updated padding and border, and white background\n <div class=\"block px-4 py-2 bg-white dark:bg-gray-800 rounded-lg shadow-sm border border-gray-300 dark:border-gray-600\">\n <h3 class=\"text-lg font-medium text-gray-900 dark:text-white mb-1\">\n <a\n href={`/libraries/${encodeURIComponent(library.name)}`}\n class=\"hover:underline\"\n >\n <span safe>{library.name}</span>\n </a>\n </h3>\n {/* Container for version rows */}\n <div class=\"mt-1\">\n {library.versions.length > 0 ? (\n library.versions\n // Sort versions: unversioned first, then newest semver first.\n .sort((a, b) => {\n // Explicitly place unversioned first\n if (!a.version) return -1;\n if (!b.version) return 1;\n // Then sort by semver, newest first\n return semver.compare(\n semver.coerce(b.version)?.version ?? \"0.0.0\",\n semver.coerce(a.version)?.version ?? \"0.0.0\"\n );\n })\n .map((version) => (\n <VersionDetailsRow libraryName={library.name} version={version} />\n )) // Pass libraryName, showDelete defaults to true\n ) : (\n // Display message if no versions are indexed\n <p class=\"text-sm text-gray-500 dark:text-gray-400 italic\">\n No versions indexed.\n </p>\n )}\n </div>\n </div>\n);\n\nexport default LibraryItem;\n","import type { LibraryInfo } from \"../../tools/ListLibrariesTool\";\nimport LibraryItem from \"./LibraryItem\"; // Adjusted import path\n\n/**\n * Props for the LibraryList component.\n */\ninterface LibraryListProps {\n libraries: LibraryInfo[];\n}\n\n/**\n * Renders a list of LibraryItem components.\n * @param props - Component props including the array of libraries.\n */\nconst LibraryList = ({ libraries }: LibraryListProps) => {\n return (\n <>\n <div class=\"space-y-2\">\n {libraries.map((library) => (\n <LibraryItem library={library} />\n ))}\n </div>\n </>\n );\n};\n\nexport default LibraryList;\n","import type { FastifyInstance } from \"fastify\";\nimport type { ListLibrariesTool } from \"../../../tools/ListLibrariesTool\";\nimport { RemoveTool } from \"../../../tools\";\nimport LibraryList from \"../../components/LibraryList\";\n\n/**\n * Registers the API routes for library management.\n * @param server - The Fastify instance.\n * @param listLibrariesTool - The tool instance for listing libraries.\n * @param removeTool - The tool instance for removing library versions.\n */\nexport function registerLibrariesRoutes(\n server: FastifyInstance,\n listLibrariesTool: ListLibrariesTool,\n removeTool: RemoveTool // Accept RemoveTool\n) {\n server.get(\"/api/libraries\", async (_request, reply) => {\n // Add reply\n try {\n const result = await listLibrariesTool.execute();\n // Set content type to HTML for JSX rendering\n reply.type(\"text/html; charset=utf-8\");\n // Render the component directly\n return <LibraryList libraries={result.libraries} />;\n } catch (error) {\n server.log.error(error, \"Failed to list libraries\");\n reply.status(500).send(\"Internal Server Error\"); // Handle errors\n }\n });\n\n // Add DELETE route for removing versions\n server.delete<{ Params: { libraryName: string; versionParam: string } }>(\n \"/api/libraries/:libraryName/versions/:versionParam\",\n async (request, reply) => {\n const { libraryName, versionParam } = request.params;\n const version = versionParam === \"unversioned\" ? undefined : versionParam;\n try {\n await removeTool.execute({ library: libraryName, version });\n reply.status(204).send(); // No Content on success\n } catch (error: any) {\n server.log.error(\n error,\n `Failed to remove ${libraryName}@${versionParam}`\n );\n // Check for specific errors if needed, e.g., NotFoundError\n reply\n .status(500)\n .send({ message: error.message || \"Failed to remove version.\" });\n }\n }\n );\n}\n","import path from \"node:path\";\nimport formBody from \"@fastify/formbody\";\nimport fastifyStatic from \"@fastify/static\";\nimport Fastify, { type FastifyInstance } from \"fastify\";\nimport { PipelineManager } from \"../pipeline/PipelineManager\";\nimport { DocumentManagementService } from \"../store/DocumentManagementService\";\nimport { SearchTool } from \"../tools\";\nimport { ListJobsTool } from \"../tools/ListJobsTool\";\nimport { ListLibrariesTool } from \"../tools/ListLibrariesTool\";\nimport { RemoveTool } from \"../tools/RemoveTool\";\nimport { ScrapeTool } from \"../tools/ScrapeTool\";\nimport { DEFAULT_WEB_PORT } from \"../utils/config\";\nimport { logger } from \"../utils/logger\";\nimport { getProjectRoot } from \"../utils/paths\";\nimport { registerIndexRoute } from \"./routes/index\";\nimport { registerJobListRoutes } from \"./routes/jobs/list\";\nimport { registerNewJobRoutes } from \"./routes/jobs/new\";\nimport { registerLibraryDetailRoutes } from \"./routes/libraries/detail\";\nimport { registerLibrariesRoutes } from \"./routes/libraries/list\";\n\n/**\n * Initializes the Fastify web server instance.\n *\n * @returns The initialized Fastify server instance.\n */\nexport async function startWebServer(port: number): Promise<FastifyInstance> {\n const server = Fastify({\n logger: false, // Use our own logger instead\n });\n\n // Register plugins\n await server.register(formBody); // Register formbody to parse form data\n\n // Instantiate services and tools\n const docService = new DocumentManagementService();\n await docService.initialize();\n const pipelineManager = new PipelineManager(docService);\n await pipelineManager.start(); // Start the manager to process jobs enqueued via web\n const listLibrariesTool = new ListLibrariesTool(docService);\n const listJobsTool = new ListJobsTool(pipelineManager);\n const scrapeTool = new ScrapeTool(docService, pipelineManager);\n const removeTool = new RemoveTool(docService);\n const searchTool = new SearchTool(docService);\n\n // Register static file serving\n await server.register(fastifyStatic, {\n // Use project root to construct absolute path to public directory\n root: path.join(getProjectRoot(), \"public\"),\n prefix: \"/\",\n index: false, // Disable automatic index.html serving\n });\n\n // Register routes\n registerIndexRoute(server); // Register the root route first\n registerJobListRoutes(server, listJobsTool);\n registerNewJobRoutes(server, scrapeTool);\n registerLibrariesRoutes(server, listLibrariesTool, removeTool);\n registerLibraryDetailRoutes(server, listLibrariesTool, searchTool);\n\n // Graceful shutdown\n server.addHook(\"onClose\", async () => {\n logger.info(\"Shutting down document service...\");\n await docService.shutdown();\n logger.info(\"Document service shut down.\");\n });\n\n try {\n const address = await server.listen({ port, host: \"0.0.0.0\" });\n logger.info(`🚀 Web UI available at ${address}`);\n return server; // Return the server instance\n } catch (error) {\n logger.error(`❌ Failed to start web UI: ${error}`);\n // Ensure server is closed if listen fails but initialization succeeded partially\n await server.close();\n throw error;\n }\n}\n\n/**\n * Stops the provided Fastify web server instance.\n *\n * @param server - The Fastify server instance to stop.\n */\nexport async function stopWebServer(server: FastifyInstance): Promise<void> {\n try {\n await server.close();\n logger.info(\"🛑 Web UI stopped.\");\n } catch (error) {\n logger.error(`❌ Failed to stop web server gracefully: ${error}`);\n // Rethrow or handle as needed, but ensure the process doesn't hang\n throw error;\n }\n}\n","#!/usr/bin/env node\nimport \"dotenv/config\";\nimport { program } from \"commander\";\nimport type { FastifyInstance } from \"fastify\";\nimport { DEFAULT_WEB_PORT } from \"./utils/config\";\nimport { logger } from \"./utils/logger\";\nimport { startWebServer, stopWebServer } from \"./web/web\";\n\nprogram\n .option(\n \"--port <number>\",\n \"Port to listen on for the web interface\",\n `${DEFAULT_WEB_PORT}`,\n )\n .parse(process.argv);\n\nconst options = program.opts();\n\nlet currentServer: FastifyInstance | null = null;\n\nasync function main() {\n try {\n // Prioritize environment variable, then CLI arg, then default\n const port = process.env.WEB_PORT\n ? Number.parseInt(process.env.WEB_PORT, 10)\n : Number.parseInt(options.port, 10);\n\n currentServer = await startWebServer(port);\n } catch (error) {\n logger.error(`❌ Fatal Error during startup: ${error}`);\n process.exit(1);\n }\n}\n\n// Handle HMR using Vite's API\nif (import.meta.hot) {\n import.meta.hot.on(\"vite:beforeFullReload\", async () => {\n if (currentServer) {\n logger.info(\"🔥 Hot reload detected. Shutting down existing web server...\");\n try {\n await stopWebServer(currentServer);\n } catch (error) {\n logger.error(`❌ Error stopping server during HMR: ${error}`);\n // Decide if we should exit or try to continue\n } finally {\n currentServer = null; // Ensure reference is cleared\n }\n }\n });\n}\n\n// Start the application\nmain();\n"],"names":["semver"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@arabold/docs-mcp-server",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.12.0",
|
|
4
4
|
"description": "MCP server for fetching and searching documentation",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
7
7
|
"docs-server": "dist/server.js",
|
|
8
|
-
"docs-cli": "dist/cli.js"
|
|
8
|
+
"docs-cli": "dist/cli.js",
|
|
9
|
+
"docs-web": "dist/web.js"
|
|
9
10
|
},
|
|
10
11
|
"license": "MIT",
|
|
11
12
|
"repository": {
|
|
@@ -14,18 +15,25 @@
|
|
|
14
15
|
},
|
|
15
16
|
"files": [
|
|
16
17
|
"dist",
|
|
18
|
+
"public",
|
|
19
|
+
"db",
|
|
17
20
|
"README.md",
|
|
18
21
|
"LICENSE",
|
|
19
22
|
"package.json"
|
|
20
23
|
],
|
|
21
24
|
"scripts": {
|
|
22
25
|
"prepare": "husky || true",
|
|
23
|
-
"build": "
|
|
24
|
-
"cli": "node --enable-source-maps dist/cli.js",
|
|
26
|
+
"build": "vite build --config vite.config.web.ts && vite build",
|
|
25
27
|
"start": "node --enable-source-maps dist/server.js",
|
|
26
|
-
"dev:cli": "
|
|
27
|
-
"server": "node --
|
|
28
|
-
"dev:server": "
|
|
28
|
+
"dev:cli": "vite build && node --enable-source-maps dist/cli.js",
|
|
29
|
+
"dev:server": "vite-node --watch src/server.ts",
|
|
30
|
+
"dev:server:stdio": "vite-node --watch src/server.ts -- --protocol stdio",
|
|
31
|
+
"dev:server:http": "vite-node --watch src/server.ts -- --protocol http",
|
|
32
|
+
"dev:web": "npm-run-all --parallel watch:web web",
|
|
33
|
+
"watch:web": "vite build --config vite.config.web.ts --watch",
|
|
34
|
+
"cli": "node --enable-source-maps dist/cli.js",
|
|
35
|
+
"server": "vite-node --watch src/server.ts",
|
|
36
|
+
"web": "vite-node --watch src/web.ts",
|
|
29
37
|
"test": "vitest run",
|
|
30
38
|
"test:watch": "vitest",
|
|
31
39
|
"test:coverage": "vitest run --coverage",
|
|
@@ -34,24 +42,33 @@
|
|
|
34
42
|
"postinstall": "npx playwright install --no-shell --with-deps chromium"
|
|
35
43
|
},
|
|
36
44
|
"dependencies": {
|
|
45
|
+
"@fastify/formbody": "^8.0.2",
|
|
46
|
+
"@fastify/static": "^8.1.1",
|
|
37
47
|
"@joplin/turndown-plugin-gfm": "^1.0.61",
|
|
48
|
+
"@kitajs/html": "^4.2.7",
|
|
49
|
+
"@kitajs/ts-html-plugin": "^4.1.1",
|
|
38
50
|
"@langchain/aws": "^0.1.8",
|
|
39
51
|
"@langchain/community": "^0.3.34",
|
|
40
52
|
"@langchain/google-genai": "^0.2.3",
|
|
41
53
|
"@langchain/google-vertexai": "^0.2.4",
|
|
42
54
|
"@langchain/openai": "^0.5.0",
|
|
43
55
|
"@modelcontextprotocol/sdk": "^1.10.2",
|
|
56
|
+
"alpinejs": "^3.14.9",
|
|
44
57
|
"axios": "^1.8.3",
|
|
45
58
|
"axios-retry": "^4.5.0",
|
|
46
59
|
"better-sqlite3": "^11.9.1",
|
|
47
60
|
"cheerio": "^1.0.0",
|
|
48
61
|
"commander": "^13.1.0",
|
|
62
|
+
"dompurify": "^3.2.5",
|
|
49
63
|
"dotenv": "^16.4.7",
|
|
50
64
|
"env-paths": "^3.0.0",
|
|
65
|
+
"fastify": "^5.3.0",
|
|
66
|
+
"flowbite": "^3.1.2",
|
|
51
67
|
"fuse.js": "^7.1.0",
|
|
68
|
+
"header-generator": "^2.1.66",
|
|
69
|
+
"htmx.org": "^1.9.12",
|
|
52
70
|
"jsdom": "^26.0.0",
|
|
53
71
|
"langchain": "0.3.19",
|
|
54
|
-
"pg": "^8.14.0",
|
|
55
72
|
"playwright": "^1.52.0",
|
|
56
73
|
"psl": "^1.15.0",
|
|
57
74
|
"remark": "^15.0.1",
|
|
@@ -70,23 +87,30 @@
|
|
|
70
87
|
"@semantic-release/git": "^10.0.1",
|
|
71
88
|
"@semantic-release/github": "^11.0.1",
|
|
72
89
|
"@semantic-release/npm": "^12.0.1",
|
|
90
|
+
"@tailwindcss/postcss": "^4.1.4",
|
|
91
|
+
"@tailwindcss/vite": "^4.1.4",
|
|
92
|
+
"@types/alpinejs": "^3.13.11",
|
|
73
93
|
"@types/better-sqlite3": "^7.6.12",
|
|
74
94
|
"@types/jsdom": "~21.1.7",
|
|
75
95
|
"@types/lint-staged": "~13.3.0",
|
|
76
96
|
"@types/node": "^20.17.23",
|
|
77
97
|
"@types/node-fetch": "^2.6.12",
|
|
78
|
-
"@types/pg": "~8.11.11",
|
|
79
98
|
"@types/psl": "^1.1.3",
|
|
80
99
|
"@types/semver": "^7.5.8",
|
|
81
100
|
"@types/turndown": "^5.0.5",
|
|
101
|
+
"autoprefixer": "^10.4.21",
|
|
102
|
+
"flowbite-typography": "^1.0.5",
|
|
82
103
|
"husky": "^9.1.7",
|
|
83
104
|
"lint-staged": "^15.5.0",
|
|
84
105
|
"memfs": "^4.17.0",
|
|
85
106
|
"npm-run-all": "^4.1.5",
|
|
107
|
+
"postcss": "^8.5.3",
|
|
86
108
|
"semantic-release": "^24.2.3",
|
|
87
|
-
"
|
|
109
|
+
"tailwindcss": "^4.1.4",
|
|
88
110
|
"typescript": "^5.8.2",
|
|
89
111
|
"vite": "^6.2.1",
|
|
112
|
+
"vite-node": "^3.1.2",
|
|
113
|
+
"vite-plugin-dts": "^4.5.3",
|
|
90
114
|
"vitest": "^3.0.8"
|
|
91
115
|
},
|
|
92
116
|
"engines": {
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
/*! tailwindcss v4.1.4 | MIT License | https://tailwindcss.com */@layer properties{@supports ((-webkit-hyphens:none) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-translate-x:0;--tw-translate-y:0;--tw-translate-z:0;--tw-rotate-x:initial;--tw-rotate-y:initial;--tw-rotate-z:initial;--tw-skew-x:initial;--tw-skew-y:initial;--tw-space-y-reverse:0;--tw-space-x-reverse:0;--tw-border-style:solid;--tw-leading:initial;--tw-font-weight:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-outline-style:solid;--tw-blur:initial;--tw-brightness:initial;--tw-contrast:initial;--tw-grayscale:initial;--tw-hue-rotate:initial;--tw-invert:initial;--tw-opacity:initial;--tw-saturate:initial;--tw-sepia:initial;--tw-drop-shadow:initial;--tw-drop-shadow-color:initial;--tw-drop-shadow-alpha:100%;--tw-drop-shadow-size:initial;--tw-duration:initial;--tw-ease:initial}}}@layer theme{:root,:host{--font-sans:ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";--font-mono:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;--color-red-50:#fef2f2;--color-red-100:#fee2e2;--color-red-200:#fecaca;--color-red-300:#fca5a5;--color-red-400:#f87171;--color-red-500:#ef4444;--color-red-600:#dc2626;--color-red-700:#b91c1c;--color-red-800:#991b1b;--color-red-900:#7f1d1d;--color-orange-50:#fffaf0;--color-orange-100:#feebc8;--color-orange-200:#fbd38d;--color-orange-300:#f6ad55;--color-orange-400:#ed8936;--color-orange-500:#dd6b20;--color-orange-600:#c05621;--color-orange-700:#9c4221;--color-orange-800:#7b341e;--color-orange-900:#652b19;--color-yellow-50:#fffbeb;--color-yellow-100:#fef3c7;--color-yellow-200:#fde68a;--color-yellow-300:#fcd34d;--color-yellow-400:#fbbf24;--color-yellow-500:#f59e0b;--color-yellow-600:#d97706;--color-yellow-700:#b45309;--color-yellow-800:#92400e;--color-yellow-900:#78350f;--color-lime-200:oklch(93.8% .127 124.321);--color-lime-300:oklch(89.7% .196 126.665);--color-lime-400:oklch(84.1% .238 128.85);--color-lime-500:oklch(76.8% .233 130.85);--color-lime-800:oklch(45.3% .124 130.933);--color-green-50:#ecfdf5;--color-green-100:#d1fae5;--color-green-200:#a7f3d0;--color-green-300:#6ee7b7;--color-green-400:#34d399;--color-green-500:#10b981;--color-green-600:#059669;--color-green-700:#047857;--color-green-800:#065f46;--color-green-900:#064e3b;--color-emerald-600:oklch(59.6% .145 163.225);--color-teal-50:#f0fdfa;--color-teal-100:#ccfbf1;--color-teal-200:#99f6e4;--color-teal-300:#5eead4;--color-teal-400:#2dd4bf;--color-teal-500:#14b8a6;--color-teal-600:#0d9488;--color-teal-700:#0f766e;--color-teal-800:#115e59;--color-cyan-200:#a5f3fc;--color-cyan-300:#67e8f9;--color-cyan-400:#22d3ee;--color-cyan-500:#06b6d4;--color-cyan-600:#0891b2;--color-cyan-800:#155e75;--color-sky-400:oklch(74.6% .16 232.661);--color-sky-500:oklch(68.5% .169 237.323);--color-blue-50:#eff6ff;--color-blue-100:#dbeafe;--color-blue-200:#bfdbfe;--color-blue-300:#93c5fd;--color-blue-400:#60a5fa;--color-blue-500:#3b82f6;--color-blue-600:#2563eb;--color-blue-700:#1d4ed8;--color-blue-800:#1e40af;--color-blue-900:#1e3a8a;--color-indigo-50:#eef2ff;--color-indigo-100:#e0e7ff;--color-indigo-200:#c7d2fe;--color-indigo-300:#a5b4fc;--color-indigo-400:#818cf8;--color-indigo-500:#6366f1;--color-indigo-600:#4f46e5;--color-indigo-700:#4338ca;--color-indigo-800:#3730a3;--color-indigo-900:#312e81;--color-purple-50:#f5f3ff;--color-purple-100:#ede9fe;--color-purple-200:#ddd6fe;--color-purple-300:#c4b5fd;--color-purple-400:#a78bfa;--color-purple-500:#8b5cf6;--color-purple-600:#7c3aed;--color-purple-700:#6d28d9;--color-purple-800:#5b21b6;--color-purple-900:#4c1d95;--color-pink-50:#fdf2f8;--color-pink-100:#fce7f3;--color-pink-200:#fbcfe8;--color-pink-300:#f9a8d4;--color-pink-400:#f472b6;--color-pink-500:#ec4899;--color-pink-600:#db2777;--color-pink-700:#be185d;--color-pink-800:#9d174d;--color-pink-900:#831843;--color-gray-50:#f9fafb;--color-gray-100:#f3f4f6;--color-gray-200:#e5e7eb;--color-gray-300:#d1d5db;--color-gray-400:#9ca3af;--color-gray-500:#6b7280;--color-gray-600:#4b5563;--color-gray-700:#374151;--color-gray-800:#1f2937;--color-gray-900:#111827;--color-white:#fff;--spacing:.25rem;--breakpoint-md:48rem;--breakpoint-lg:64rem;--breakpoint-xl:80rem;--container-2xs:18rem;--container-xs:20rem;--container-sm:24rem;--container-md:28rem;--container-lg:32rem;--container-xl:36rem;--container-2xl:42rem;--container-4xl:56rem;--container-7xl:80rem;--text-xs:.75rem;--text-xs--line-height:calc(1/.75);--text-sm:.875rem;--text-sm--line-height:calc(1.25/.875);--text-base:1rem;--text-base--line-height: 1.5 ;--text-lg:1.125rem;--text-lg--line-height:calc(1.75/1.125);--text-xl:1.25rem;--text-xl--line-height:calc(1.75/1.25);--text-2xl:1.5rem;--text-2xl--line-height:calc(2/1.5);--text-3xl:1.875rem;--text-3xl--line-height: 1.2 ;--text-4xl:2.25rem;--text-4xl--line-height:calc(2.5/2.25);--text-5xl:3rem;--text-5xl--line-height:1;--text-6xl:3.75rem;--text-6xl--line-height:1;--text-7xl:4.5rem;--text-7xl--line-height:1;--text-8xl:6rem;--text-8xl--line-height:1;--text-9xl:8rem;--text-9xl--line-height:1;--font-weight-thin:100;--font-weight-extralight:200;--font-weight-normal:400;--font-weight-medium:500;--font-weight-semibold:600;--font-weight-bold:700;--font-weight-extrabold:800;--font-weight-black:900;--tracking-tighter:-.05em;--tracking-tight:-.025em;--tracking-normal:0em;--tracking-wide:.025em;--tracking-wider:.05em;--tracking-widest:.1em;--leading-tight:1.25;--leading-normal:1.5;--leading-relaxed:1.625;--leading-loose:2;--radius-xs:.125rem;--radius-sm:.25rem;--radius-md:.375rem;--radius-lg:.5rem;--radius-xl:.75rem;--ease-in:cubic-bezier(.4,0,1,1);--ease-out:cubic-bezier(0,0,.2,1);--ease-in-out:cubic-bezier(.4,0,.2,1);--animate-spin:spin 1s linear infinite;--animate-pulse:pulse 2s cubic-bezier(.4,0,.6,1)infinite;--blur-xs:4px;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4,0,.2,1);--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono)}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;-moz-tab-size:4;-o-tab-size:4;tab-size:4;line-height:1.5;font-family:var(--default-font-family,ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::-moz-placeholder{opacity:1}::placeholder{opacity:1}@supports (not (-webkit-appearance:-apple-pay-button)) or (contain-intrinsic-size:1px){::-moz-placeholder{color:currentColor}::placeholder{color:currentColor}@supports (color:color-mix(in lab,red,red)){::-moz-placeholder{color:color-mix(in oklab,currentcolor 50%,transparent)}::placeholder{color:color-mix(in oklab,currentcolor 50%,transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){-webkit-appearance:button;-moz-appearance:button;appearance:button}::file-selector-button{-webkit-appearance:button;-moz-appearance:button;appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}.tooltip-arrow,.tooltip-arrow:before{background:inherit;width:8px;height:8px;position:absolute}.tooltip-arrow{visibility:hidden}.tooltip-arrow:before{content:"";visibility:visible;transform:rotate(45deg)}[data-tooltip-style^=light]+.tooltip>.tooltip-arrow:before{border-style:solid;border-color:var(--color-gray-200)}[data-tooltip-style^=light]+.tooltip[data-popper-placement^=top]>.tooltip-arrow:before{border-bottom-width:1px;border-right-width:1px}[data-tooltip-style^=light]+.tooltip[data-popper-placement^=right]>.tooltip-arrow:before{border-bottom-width:1px;border-left-width:1px}[data-tooltip-style^=light]+.tooltip[data-popper-placement^=bottom]>.tooltip-arrow:before{border-top-width:1px;border-left-width:1px}[data-tooltip-style^=light]+.tooltip[data-popper-placement^=left]>.tooltip-arrow:before{border-top-width:1px;border-right-width:1px}.tooltip[data-popper-placement^=top]>.tooltip-arrow{bottom:-4px}.tooltip[data-popper-placement^=bottom]>.tooltip-arrow{top:-4px}.tooltip[data-popper-placement^=left]>.tooltip-arrow{right:-4px}.tooltip[data-popper-placement^=right]>.tooltip-arrow{left:-4px}.tooltip.invisible>.tooltip-arrow:before{visibility:hidden}[data-popper-arrow],[data-popper-arrow]:before{background:inherit;width:8px;height:8px;position:absolute}[data-popper-arrow]{visibility:hidden}[data-popper-arrow]:before{content:"";visibility:visible;transform:rotate(45deg)}[data-popper-arrow]:after{content:"";visibility:visible;background:inherit;width:9px;height:9px;position:absolute;transform:rotate(45deg)}[role=tooltip]>[data-popper-arrow]:before{border-style:solid;border-color:var(--color-gray-200)}.dark [role=tooltip]>[data-popper-arrow]:before{border-style:solid;border-color:var(--color-gray-600)}[role=tooltip]>[data-popper-arrow]:after{border-style:solid;border-color:var(--color-gray-200)}.dark [role=tooltip]>[data-popper-arrow]:after{border-style:solid;border-color:var(--color-gray-600)}[data-popover][role=tooltip][data-popper-placement^=top]>[data-popper-arrow]:before,[data-popover][role=tooltip][data-popper-placement^=top]>[data-popper-arrow]:after{border-bottom-width:1px;border-right-width:1px}[data-popover][role=tooltip][data-popper-placement^=right]>[data-popper-arrow]:before,[data-popover][role=tooltip][data-popper-placement^=right]>[data-popper-arrow]:after{border-bottom-width:1px;border-left-width:1px}[data-popover][role=tooltip][data-popper-placement^=bottom]>[data-popper-arrow]:before,[data-popover][role=tooltip][data-popper-placement^=bottom]>[data-popper-arrow]:after{border-top-width:1px;border-left-width:1px}[data-popover][role=tooltip][data-popper-placement^=left]>[data-popper-arrow]:before,[data-popover][role=tooltip][data-popper-placement^=left]>[data-popper-arrow]:after{border-top-width:1px;border-right-width:1px}[data-popover][role=tooltip][data-popper-placement^=top]>[data-popper-arrow]{bottom:-5px}[data-popover][role=tooltip][data-popper-placement^=bottom]>[data-popper-arrow]{top:-5px}[data-popover][role=tooltip][data-popper-placement^=left]>[data-popper-arrow]{right:-5px}[data-popover][role=tooltip][data-popper-placement^=right]>[data-popper-arrow]{left:-5px}[role=tooltip].invisible>[data-popper-arrow]:before,[role=tooltip].invisible>[data-popper-arrow]:after{visibility:hidden}[type=text],[type=email],[type=url],[type=password],[type=number],[type=date],[type=datetime-local],[type=month],[type=search],[type=tel],[type=time],[type=week],[multiple],textarea,select{-webkit-appearance:none;-moz-appearance:none;appearance:none;border-color:var(--color-gray-500);--tw-shadow:0 0 #0000;background-color:#fff;border-width:1px;border-radius:0;padding:.5rem .75rem;font-size:1rem;line-height:1.5rem}:is([type=text],[type=email],[type=url],[type=password],[type=number],[type=date],[type=datetime-local],[type=month],[type=search],[type=tel],[type=time],[type=week],[multiple],textarea,select):focus{outline-offset:2px;--tw-ring-inset:var(--tw-empty, );--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:var(--color-blue-600);--tw-ring-offset-shadow:var(--tw-ring-inset)0 0 0 var(--tw-ring-offset-width)var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset)0 0 0 calc(1px + var(--tw-ring-offset-width))var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);border-color:var(--color-blue-600);outline:2px solid #0000}input::-moz-placeholder,textarea::-moz-placeholder{color:var(--color-gray-500);opacity:1}input::placeholder,textarea::placeholder{color:var(--color-gray-500);opacity:1}::-webkit-datetime-edit-fields-wrapper{padding:0}input[type=time]::-webkit-calendar-picker-indicator{background:0 0}select:not([size]){-webkit-print-color-adjust:exact;print-color-adjust:exact;background-image:url("data:image/svg+xml,%3csvg aria-hidden='true' xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 10 6'%3e %3cpath stroke='%236B7280' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m1 1 4 4 4-4'/%3e %3c/svg%3e");background-position:right .75rem center;background-repeat:no-repeat;background-size:.75em .75em;padding-right:2.5rem}[dir=rtl] select:not([size]){background-position:.75rem;padding-left:0;padding-right:.75rem}[multiple]{background-image:initial;background-position:initial;background-repeat:unset;background-size:initial;-webkit-print-color-adjust:unset;print-color-adjust:unset;padding-right:.75rem}[type=checkbox],[type=radio]{-webkit-appearance:none;-moz-appearance:none;appearance:none;-webkit-print-color-adjust:exact;print-color-adjust:exact;vertical-align:middle;-webkit-user-select:none;-moz-user-select:none;user-select:none;width:1rem;height:1rem;color:var(--color-blue-600);border-color:--color-gray-500;--tw-shadow:0 0 #0000;background-color:#fff;background-origin:border-box;border-width:1px;flex-shrink:0;padding:0;display:inline-block}[type=checkbox]{border-radius:0}[type=radio]{border-radius:100%}[type=checkbox]:focus,[type=radio]:focus{outline-offset:2px;--tw-ring-inset:var(--tw-empty, );--tw-ring-offset-width:2px;--tw-ring-offset-color:#fff;--tw-ring-color:var(--color-blue-600);--tw-ring-offset-shadow:var(--tw-ring-inset)0 0 0 var(--tw-ring-offset-width)var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset)0 0 0 calc(2px + var(--tw-ring-offset-width))var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);outline:2px solid #0000}[type=checkbox]:checked,[type=radio]:checked,.dark [type=checkbox]:checked,.dark [type=radio]:checked{background-position:50%;background-repeat:no-repeat;background-size:.55em .55em;background-color:currentColor!important;border-color:#0000!important}[type=checkbox]:checked{-webkit-print-color-adjust:exact;print-color-adjust:exact;background-image:url("data:image/svg+xml,%3csvg aria-hidden='true' xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 16 12'%3e %3cpath stroke='white' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' d='M1 5.917 5.724 10.5 15 1.5'/%3e %3c/svg%3e");background-repeat:no-repeat;background-size:.55em .55em}[type=radio]:checked,.dark [type=radio]:checked{background-image:url("data:image/svg+xml,%3csvg viewBox='0 0 16 16' fill='white' xmlns='http://www.w3.org/2000/svg'%3e%3ccircle cx='8' cy='8' r='3'/%3e%3c/svg%3e");background-size:1em 1em}[type=checkbox]:indeterminate{-webkit-print-color-adjust:exact;print-color-adjust:exact;background-image:url("data:image/svg+xml,%3csvg aria-hidden='true' xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 16 12'%3e %3cpath stroke='white' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' d='M0.5 6h14'/%3e %3c/svg%3e");background-position:50%;background-repeat:no-repeat;background-size:.55em .55em;background-color:currentColor!important;border-color:#0000!important}[type=checkbox]:indeterminate:hover,[type=checkbox]:indeterminate:focus{background-color:currentColor!important;border-color:#0000!important}[type=file]{background:unset;border-color:inherit;font-size:unset;line-height:inherit;border-width:0;border-radius:0;padding:0}[type=file]:focus{outline:1px auto inherit}input[type=file]::file-selector-button{color:#fff;background:var(--color-gray-800);cursor:pointer;border:0;margin-inline:-1rem 1rem;padding:.625rem 1rem .625rem 2rem;font-size:.875rem;font-weight:500}input[type=file]::file-selector-button:hover{background:var(--color-gray-700)}[dir=rtl] input[type=file]::file-selector-button{padding-left:1rem;padding-right:2rem}.dark input[type=file]::file-selector-button{color:#fff;background:var(--color-gray-600)}.dark input[type=file]::file-selector-button:hover{background:var(--color-gray-500)}input[type=range]::-webkit-slider-thumb{background:var(--color-blue-600);-webkit-appearance:none;appearance:none;cursor:pointer;border:0;border-radius:9999px;width:1.25rem;height:1.25rem}input[type=range]:disabled::-webkit-slider-thumb{background:var(--color-gray-400)}.dark input[type=range]:disabled::-webkit-slider-thumb{background:var(--color-gray-500)}input[type=range]:focus::-webkit-slider-thumb{outline-offset:2px;--tw-ring-offset-shadow:var(--tw-ring-inset)0 0 0 var(--tw-ring-offset-width)var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset)0 0 0 calc(4px + var(--tw-ring-offset-width))var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000);--tw-ring-opacity:1;--tw-ring-color:rgb(164 202 254/var(--tw-ring-opacity));outline:2px solid #0000}input[type=range]::-moz-range-thumb{background:var(--color-blue-600);-moz-appearance:none;appearance:none;cursor:pointer;border:0;border-radius:9999px;width:1.25rem;height:1.25rem}input[type=range]:disabled::-moz-range-thumb{background:var(--color-gray-400)}.dark input[type=range]:disabled::-moz-range-thumb{background:var(--color-gray-500)}input[type=range]::-moz-range-progress{background:var(--color-blue-500)}input[type=range]::-ms-fill-lower{background:var(--color-blue-500)}input[type=range].range-sm::-webkit-slider-thumb{width:1rem;height:1rem}input[type=range].range-lg::-webkit-slider-thumb{width:1.5rem;height:1.5rem}input[type=range].range-sm::-moz-range-thumb{width:1rem;height:1rem}input[type=range].range-lg::-moz-range-thumb{width:1.5rem;height:1.5rem}.toggle-bg:after{content:"";border-color:var(--color-gray-300);width:1.25rem;height:1.25rem;box-shadow:var(--tw-ring-inset) 0 0 0 calc(0px + var(--tw-ring-offset-width)) var(--tw-ring-color);background:#fff;border-width:1px;border-radius:9999px;transition-property:background-color,border-color,color,fill,stroke,opacity,box-shadow,transform,filter,-webkit-backdrop-filter,backdrop-filter;transition-duration:.15s;position:absolute;top:.125rem;left:.125rem}input:checked+.toggle-bg:after{border-color:#fff;transform:translate(100%)}input:checked+.toggle-bg{background:var(--color-blue-600);border-color:var(--color-blue-600)}}@layer components{a{text-underline-offset:8px}button{cursor:pointer}}@layer utilities{.collapse{visibility:collapse}.invisible{visibility:hidden}.visible{visibility:visible}.datatable-wrapper{width:100%}.datatable-wrapper .datatable-bottom{flex-direction:column;justify-content:space-between;align-items:start;gap:1rem;margin-top:1rem;display:flex}@media (min-width:640px){.datatable-wrapper .datatable-bottom{flex-direction:row;align-items:center}}.datatable-wrapper .datatable-bottom .datatable-pagination .datatable-pagination-list-item:first-of-type,.datatable-wrapper .datatable-bottom .datatable-pagination .datatable-pagination-list-item:last-of-type{position:relative}.datatable-wrapper .datatable-bottom .datatable-pagination .datatable-pagination-list-item-link{color:var(--color-gray-500);border-top:1px solid var(--color-gray-300);border-bottom:1px solid var(--color-gray-300);border-right:1px solid var(--color-gray-300);align-items:center;height:2rem;padding-left:.75rem;padding-right:.75rem;font-size:.875rem;font-weight:500;display:flex}.datatable-wrapper .datatable-bottom .datatable-pagination .datatable-pagination-list-item:first-of-type .datatable-pagination-list-item-link,.datatable-wrapper .datatable-bottom .datatable-pagination .datatable-pagination-list-item:last-of-type .datatable-pagination-list-item-link,.dark .datatable-wrapper .datatable-bottom .datatable-pagination .datatable-pagination-list-item:first-of-type .datatable-pagination-list-item-link,.dark .datatable-wrapper .datatable-bottom .datatable-pagination .datatable-pagination-list-item:last-of-type .datatable-pagination-list-item-link{color:#0000}.datatable-wrapper .datatable-bottom .datatable-pagination .datatable-pagination-list-item:first-of-type .datatable-pagination-list-item-link:after{content:url("data:image/svg+xml,%3csvg aria-hidden='true' xmlns='http://www.w3.org/2000/svg' width='20' height='20' fill='none' viewBox='0 0 24 24'%3e %3cpath stroke='%236B7280' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m14 8-4 4 4 4'/%3e %3c/svg%3e");width:1.3rem;height:1.3rem;position:absolute;top:50%;left:50%;transform:translate(-50%,-50%)}.datatable-wrapper .datatable-bottom .datatable-pagination .datatable-pagination-list-item:first-of-type .datatable-pagination-list-item-link:hover:after{content:url("data:image/svg+xml,%3csvg aria-hidden='true' xmlns='http://www.w3.org/2000/svg' width='20' height='20' fill='none' viewBox='0 0 24 24'%3e %3cpath stroke='%23111827' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m14 8-4 4 4 4'/%3e %3c/svg%3e")}.datatable-wrapper .datatable-bottom .datatable-pagination .datatable-pagination-list-item:last-of-type .datatable-pagination-list-item-link:after{content:url("data:image/svg+xml,%3csvg aria-hidden='true' xmlns='http://www.w3.org/2000/svg' width='20' height='20' fill='none' viewBox='0 0 24 24'%3e %3cpath stroke='%236B7280' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m10 16 4-4-4-4'/%3e %3c/svg%3e");width:1.3rem;height:1.3rem;position:absolute;top:50%;right:50%;transform:translate(50%,-50%)}.datatable-wrapper .datatable-bottom .datatable-pagination .datatable-pagination-list-item:last-of-type .datatable-pagination-list-item-link:hover:after{content:url("data:image/svg+xml,%3csvg aria-hidden='true' xmlns='http://www.w3.org/2000/svg' width='20' height='20' fill='none' viewBox='0 0 24 24'%3e %3cpath stroke='%23111827' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m10 16 4-4-4-4'/%3e %3c/svg%3e")}.datatable-wrapper .datatable-bottom .datatable-pagination .datatable-pagination-list-item:first-of-type .datatable-pagination-list-item-link{border-left:1px solid var(--color-gray-300);border-top-left-radius:.5rem;border-bottom-left-radius:.5rem}.datatable-wrapper .datatable-bottom .datatable-pagination .datatable-pagination-list-item:last-of-type .datatable-pagination-list-item-link{border-left:0;border-top-right-radius:.5rem;border-bottom-right-radius:.5rem}.datatable-wrapper .datatable-bottom .datatable-pagination .datatable-pagination-list-item-link:hover{background-color:var(--color-gray-50);color:var(--color-gray-700)}.sr-only{clip:rect(0,0,0,0);white-space:nowrap;border-width:0;width:1px;height:1px;margin:-1px;padding:0;position:absolute;overflow:hidden}.absolute{position:absolute}.fixed{position:fixed}.relative{position:relative}.static{position:static}.sticky{position:sticky}.inset-0{inset:calc(var(--spacing)*0)}.top-0{top:calc(var(--spacing)*0)}.right-0{right:calc(var(--spacing)*0)}.bottom-0{bottom:calc(var(--spacing)*0)}.bottom-\[60px\]{bottom:60px}.left-0{left:calc(var(--spacing)*0)}.isolate{isolation:isolate}.z-10{z-index:10}.z-20{z-index:20}.z-30{z-index:30}.z-40{z-index:40}.z-50{z-index:50}.container{width:100%}@media (min-width:40rem){.container{max-width:40rem}}@media (min-width:48rem){.container{max-width:48rem}}@media (min-width:64rem){.container{max-width:64rem}}@media (min-width:80rem){.container{max-width:80rem}}@media (min-width:96rem){.container{max-width:96rem}}.format{color:var(--tw-format-body);--tw-format-body:oklch(55.1% .027 264.364);--tw-format-headings:oklch(21% .034 264.665);--tw-format-lead:oklch(55.1% .027 264.364);--tw-format-links:oklch(44.6% .03 256.802);--tw-format-bold:oklch(21% .034 264.665);--tw-format-counters:oklch(55.1% .027 264.364);--tw-format-bullets:oklch(55.1% .027 264.364);--tw-format-hr:oklch(92.8% .006 264.531);--tw-format-quotes:oklch(21% .034 264.665);--tw-format-quote-borders:oklch(92.8% .006 264.531);--tw-format-captions:oklch(55.1% .027 264.364);--tw-format-code:oklch(21% .034 264.665);--tw-format-code-bg:oklch(96.7% .003 264.542);--tw-format-pre-code:oklch(44.6% .03 256.802);--tw-format-pre-bg:oklch(96.7% .003 264.542);--tw-format-th-borders:oklch(92.8% .006 264.531);--tw-format-th-bg:oklch(98.5% .002 247.839);--tw-format-td-borders:oklch(92.8% .006 264.531);--tw-format-invert-body:oklch(70.7% .022 261.325);--tw-format-invert-headings:#fff;--tw-format-invert-lead:oklch(70.7% .022 261.325);--tw-format-invert-links:#fff;--tw-format-invert-bold:#fff;--tw-format-invert-counters:oklch(70.7% .022 261.325);--tw-format-invert-bullets:oklch(44.6% .03 256.802);--tw-format-invert-hr:oklch(37.3% .034 259.733);--tw-format-invert-quotes:oklch(96.7% .003 264.542);--tw-format-invert-quote-borders:oklch(37.3% .034 259.733);--tw-format-invert-captions:oklch(70.7% .022 261.325);--tw-format-invert-code:#fff;--tw-format-invert-code-bg:oklch(27.8% .033 256.848);--tw-format-invert-pre-code:oklch(87.2% .01 258.338);--tw-format-invert-pre-bg:oklch(37.3% .034 259.733);--tw-format-invert-th-borders:oklch(44.6% .03 256.802);--tw-format-invert-td-borders:oklch(37.3% .034 259.733);--tw-format-invert-th-bg:oklch(37.3% .034 259.733);max-width:65ch;font-size:1rem;line-height:1.75}.format :where([class~=lead]):not(:where([class~=not-format] *)){color:var(--tw-format-lead);margin-top:1.2em;margin-bottom:1.2em;font-size:1.25em;line-height:1.6}.format :where(a):not(:where([class~=not-format] *)){color:var(--tw-format-links);font-weight:500;text-decoration:underline}.format :where(a):not(:where([class~=not-format] *)):hover{text-decoration:none}.format :where(strong):not(:where([class~=not-format] *)){color:var(--tw-format-bold);font-weight:700}.format :where(a strong):not(:where([class~=not-format] *)),.format :where(blockquote strong):not(:where([class~=not-format] *)),.format :where(thead th strong):not(:where([class~=not-format] *)){color:inherit}.format :where(ol):not(:where([class~=not-format] *)){margin-top:1.25em;margin-bottom:1.25em;padding-left:1.625em;list-style-type:decimal}.format :where(ol[type=A]):not(:where([class~=not-format] *)){list-style-type:upper-alpha}.format :where(ol[type=a]):not(:where([class~=not-format] *)){list-style-type:lower-alpha}.format :where(ol[type=A s]):not(:where([class~=not-format] *)){list-style-type:upper-alpha}.format :where(ol[type=a s]):not(:where([class~=not-format] *)){list-style-type:lower-alpha}.format :where(ol[type=I]):not(:where([class~=not-format] *)){list-style-type:upper-roman}.format :where(ol[type=i]):not(:where([class~=not-format] *)){list-style-type:lower-roman}.format :where(ol[type=I s]):not(:where([class~=not-format] *)){list-style-type:upper-roman}.format :where(ol[type=i s]):not(:where([class~=not-format] *)){list-style-type:lower-roman}.format :where(ol[type="1"]):not(:where([class~=not-format] *)){list-style-type:decimal}.format :where(ul):not(:where([class~=not-format] *)){margin-top:1.25em;margin-bottom:1.25em;padding-left:1.625em;list-style-type:disc}.format :where(ol>li):not(:where([class~=not-format] *))::marker{color:var(--tw-format-counters);font-weight:400}.format :where(ul>li):not(:where([class~=not-format] *))::marker{color:var(--tw-format-bullets)}.format :where(hr):not(:where([class~=not-format] *)){border-color:var(--tw-format-hr);border-top-width:1px;margin-top:3em;margin-bottom:3em}.format :where(blockquote):not(:where([class~=not-format] *)){color:var(--tw-format-quotes);quotes:"“""”""‘""’";margin-bottom:1.6em;font-size:1.11111em;font-style:italic;font-weight:700}.format :where(blockquote):not(:where([class~=not-format] *)):before{content:"";color:var(--tw-format-quotes);background-image:url("data:image/svg+xml,%0A%3Csvg width='32' height='24' viewBox='0 0 32 24' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M18.6893 24V14.1453C18.6893 6.54 23.664 1.38533 30.6667 -7.15256e-07L31.9933 2.868C28.7507 4.09066 26.6667 7.71867 26.6667 10.6667H32V24H18.6893ZM-9.53674e-07 24V14.1453C-9.53674e-07 6.54 4.99733 1.384 12 -7.15256e-07L13.328 2.868C10.084 4.09066 8 7.71867 8 10.6667L13.3107 10.6667V24H-9.53674e-07Z' fill='%239CA3AF'/%3E%3C/svg%3E%0A");background-repeat:no-repeat;width:1.77778em;height:1.33333em;margin-top:1.6em;display:block}.format :where(blockquote p:first-of-type):not(:where([class~=not-format] *)):before{content:open-quote}.format :where(blockquote p:last-of-type):not(:where([class~=not-format] *)):after{content:close-quote}.format :where(h1):not(:where([class~=not-format] *)){color:var(--tw-format-headings);margin-top:0;margin-bottom:.888889em;font-size:2.25em;font-weight:800;line-height:1.11111}.format :where(h1 strong):not(:where([class~=not-format] *)){color:inherit;font-weight:900}.format :where(h2):not(:where([class~=not-format] *)){color:var(--tw-format-headings);margin-top:0;margin-bottom:1em;font-size:1.5em;font-weight:700;line-height:1.33333}.format :where(h2 strong):not(:where([class~=not-format] *)){color:inherit;font-weight:800}.format :where(h3):not(:where([class~=not-format] *)){color:var(--tw-format-headings);margin-top:0;margin-bottom:.6em;font-size:1.25em;font-weight:700;line-height:1.6}.format :where(h3 strong):not(:where([class~=not-format] *)){color:inherit;font-weight:800}.format :where(h4):not(:where([class~=not-format] *)){color:var(--tw-format-headings);margin-top:0;margin-bottom:.5em;font-weight:600;line-height:1.5}.format :where(h4 strong):not(:where([class~=not-format] *)){color:inherit;font-weight:700}.format :where(img):not(:where([class~=not-format] *)){margin-top:2em;margin-bottom:2em}.format :where(figure>*):not(:where([class~=not-format] *)){margin-top:0;margin-bottom:0}.format :where(figcaption):not(:where([class~=not-format] *)){color:var(--tw-format-captions);margin-top:.857143em;font-size:.875em;line-height:1.42857}.format :where(code):not(:where([class~=not-format] *)){color:var(--tw-format-code);background-color:var(--tw-format-code-bg);border-radius:.222222em;padding:.333333em .555556em;font-size:.875em;font-weight:600}.format :where(a code):not(:where([class~=not-format] *)),.format :where(h1 code):not(:where([class~=not-format] *)){color:inherit}.format :where(h2 code):not(:where([class~=not-format] *)){color:inherit;font-size:.875em}.format :where(h3 code):not(:where([class~=not-format] *)){color:inherit;font-size:.9em}.format :where(h4 code):not(:where([class~=not-format] *)),.format :where(blockquote code):not(:where([class~=not-format] *)),.format :where(thead th code):not(:where([class~=not-format] *)){color:inherit}.format :where(pre):not(:where([class~=not-format] *)){color:var(--tw-format-pre-code);background-color:var(--tw-format-pre-bg);border-radius:.375rem;margin-top:1.71429em;margin-bottom:1.71429em;padding:.857143em 1.14286em;font-size:.875em;font-weight:400;line-height:1.71429;overflow-x:auto}.format :where(pre code):not(:where([class~=not-format] *)){font-weight:inherit;color:inherit;font-size:inherit;font-family:inherit;line-height:inherit;background-color:#0000;border-width:0;border-radius:0;padding:0}.format :where(pre code):not(:where([class~=not-format] *)):before,.format :where(pre code):not(:where([class~=not-format] *)):after{content:none}.format :where(table):not(:where([class~=not-format] *)){table-layout:auto;text-align:left;width:100%;margin-top:2em;margin-bottom:2em;font-size:.875em;line-height:1.71429}.format :where(thead):not(:where([class~=not-format] *)){background-color:var(--tw-format-th-bg);border-radius:.277778em}.format :where(thead th):not(:where([class~=not-format] *)){background-color:var(--tw-format-th-bg);color:var(--tw-format-headings);vertical-align:bottom;padding:.555556em .571429em .571429em;font-weight:600}.format :where(tbody th):not(:where([class~=not-format] *)){background-color:var(--tw-format-th-bg);color:var(--tw-format-headings);vertical-align:bottom;padding:.555556em;font-weight:600}.format :where(tbody tr th p,tbody tr td p):not(:where([class~=not-format] *)){margin:0!important}.format :where(tbody tr th,tbody tr td):not(:where([class~=not-format] *)){padding:.666667em!important}.format :where(tbody tr):not(:where([class~=not-format] *)){border-bottom-width:1px;border-bottom-color:var(--tw-format-td-borders)}.format :where(tbody tr:last-child):not(:where([class~=not-format] *)){border-bottom-width:0}.format :where(tbody td):not(:where([class~=not-format] *)){vertical-align:baseline}.format :where(tfoot):not(:where([class~=not-format] *)){border-top-width:1px;border-top-color:var(--tw-format-th-borders)}.format :where(tfoot td):not(:where([class~=not-format] *)){vertical-align:top}.format :where(p):not(:where([class~=not-format] *)){margin-top:1.25em;margin-bottom:1.25em}.format :where(blockquote>p:first-child):not(:where([class~=not-format] *)){margin-top:0}.format :where(video):not(:where([class~=not-format] *)),.format :where(figure):not(:where([class~=not-format] *)){margin-top:2em;margin-bottom:2em}.format :where(li):not(:where([class~=not-format] *)){margin-top:.5em;margin-bottom:.5em}.format :where(ol>li):not(:where([class~=not-format] *)),.format :where(ul>li):not(:where([class~=not-format] *)){padding-left:.375em}.format :where(.format>ul>li p):not(:where([class~=not-format] *)){margin-top:.75em;margin-bottom:.75em}.format :where(.format>ul>li>:first-child):not(:where([class~=not-format] *)){margin-top:1.25em}.format :where(.format>ul>li>:last-child):not(:where([class~=not-format] *)){margin-bottom:1.25em}.format :where(.format>ol>li>:first-child):not(:where([class~=not-format] *)){margin-top:1.25em}.format :where(.format>ol>li>:last-child):not(:where([class~=not-format] *)){margin-bottom:1.25em}.format :where(ul ul,ul ol,ol ul,ol ol):not(:where([class~=not-format] *)){margin-top:.75em;margin-bottom:.75em}.format :where(hr+*):not(:where([class~=not-format] *)),.format :where(h2+*):not(:where([class~=not-format] *)),.format :where(h3+*):not(:where([class~=not-format] *)),.format :where(h4+*):not(:where([class~=not-format] *)){margin-top:0}.format :where(thead th:last-child):not(:where([class~=not-format] *)){padding-right:0}.format :where(tbody td,tfoot td):not(:where([class~=not-format] *)){padding:.571429em}.format :where(tbody td:last-child,tfoot td:last-child):not(:where([class~=not-format] *)){padding-right:0}.format :where(.format>:first-child):not(:where([class~=not-format] *)){margin-top:0}.format :where(.format>:last-child):not(:where([class~=not-format] *)){margin-bottom:0}.mx-auto{margin-inline:auto}.me-2{margin-inline-end:calc(var(--spacing)*2)}.me-3{margin-inline-end:calc(var(--spacing)*3)}.mt-0\.5{margin-top:calc(var(--spacing)*.5)}.mt-1{margin-top:calc(var(--spacing)*1)}.mt-2{margin-top:calc(var(--spacing)*2)}.mt-4{margin-top:calc(var(--spacing)*4)}.apexcharts-canvas .apexcharts-legend-series{align-items:center!important;margin-bottom:.25rem!important;margin-left:.5rem!important;margin-right:.5rem!important;display:flex!important}.apexcharts-canvas .apexcharts-tooltip{color:var(--color-gray-700)!important;background-color:#fff!important;border:0!important;border-radius:.25rem!important;box-shadow:0 4px 6px -1px #0000001a,0 2px 4px -2px #0000001a!important}.datatable-wrapper .datatable-top{flex-direction:column-reverse;justify-content:space-between;align-items:start;gap:1rem;margin-bottom:1rem;display:flex}@media (min-width:640px){.datatable-wrapper .datatable-top{flex-direction:row-reverse;align-items:center}}[dir=rtl] .apexcharts-tooltip .apexcharts-tooltip-marker{margin-right:0!important;margin-left:e!important}.datatable-wrapper .datatable-top .datatable-dropdown{color:var(--color-gray-500);font-size:.875rem}.datatable-wrapper .datatable-top .datatable-dropdown .datatable-selector{background-color:var(--color-gray-50);color:var(--color-gray-900);border:1px solid var(--color-gray-300);border-radius:.5rem;min-width:4rem;margin-right:.25rem;font-size:.875rem}.apexcharts-canvas .apexcharts-tooltip .apexcharts-tooltip-title{background-color:var(--color-gray-100)!important;border-bottom-color:var(--color-gray-200)!important;color:var(--color-gray-500)!important;margin-bottom:.75rem!important;padding:.5rem .75rem!important;font-size:.875rem!important;font-weight:400!important}.mb-1{margin-bottom:calc(var(--spacing)*1)}.mb-2{margin-bottom:calc(var(--spacing)*2)}.mb-2\.5{margin-bottom:calc(var(--spacing)*2.5)}.mb-4{margin-bottom:calc(var(--spacing)*4)}.mb-8{margin-bottom:calc(var(--spacing)*8)}.apexcharts-canvas .apexcharts-xaxistooltip{color:var(--color-gray-500)!important;background-color:#fff!important;border-color:#0000!important;border-radius:.25rem!important;padding:.5rem .75rem!important;box-shadow:0 4px 6px -1px #0000001a,0 2px 4px -2px #0000001a!important}.apexcharts-canvas .apexcharts-xaxistooltip:after,.apexcharts-canvas .apexcharts-xaxistooltip:before{border-bottom-color:#fff!important}.apexcharts-canvas .apexcharts-xaxistooltip:after{border-width:8px!important;margin-left:-8px!important}.apexcharts-canvas .apexcharts-xaxistooltip:before{border-width:10px!important;margin-left:-10px!important}.ml-1{margin-left:calc(var(--spacing)*1)}.ml-2{margin-left:calc(var(--spacing)*2)}.ml-auto{margin-left:auto}.datatable-wrapper .datatable-bottom .datatable-pagination .datatable-pagination-list{align-items:center;height:2rem;font-size:.875rem;display:flex}.block{display:block}.contents{display:contents}.flex{display:flex}.grid{display:grid}.hidden{display:none}.inline{display:inline}.inline-block{display:inline-block}.inline-flex{display:inline-flex}.table{display:table}.h-4{height:calc(var(--spacing)*4)}.h-5{height:calc(var(--spacing)*5)}.h-6{height:calc(var(--spacing)*6)}.h-\[0\.8em\]{height:.8em}.h-\[calc\(100\%-1rem\)\]{height:calc(100% - 1rem)}.max-h-full{max-height:100%}.datatable-wrapper .datatable-table{width:100%;color:var(--color-gray-500);text-align:left;font-size:.875rem}.datatable-wrapper .datatable-table thead{color:var(--color-gray-500);background-color:var(--color-gray-50);font-size:.75rem}.datatable-wrapper .datatable-table thead th{white-space:nowrap;padding:.75rem 1.5rem;width:auto!important}.datatable-wrapper .datatable-table tbody th,.datatable-wrapper .datatable-table tbody td{padding:.75rem 1.5rem;width:auto!important}.datatable-wrapper .datatable-table thead th .datatable-sorter,.datatable-wrapper .datatable-table thead th{text-transform:uppercase}.datatable-wrapper .datatable-table tbody tr{border-bottom:1px solid var(--color-gray-200)}.w-1\/2{width:50%}.w-1\/3{width:33.3333%}.w-1\/4{width:25%}.w-3\/4{width:75%}.w-4{width:calc(var(--spacing)*4)}.w-5{width:calc(var(--spacing)*5)}.w-5\/6{width:83.3333%}.w-40{width:calc(var(--spacing)*40)}.w-48{width:calc(var(--spacing)*48)}.w-64{width:calc(var(--spacing)*64)}.w-full{width:100%}.max-w-2xl{max-width:var(--container-2xl)}.max-w-none{max-width:none}.max-w-sm{max-width:var(--container-sm)}.datatable-wrapper .datatable-search .datatable-input,.datatable-wrapper .datatable-input{color:var(--color-gray-900);border:1px solid var(--color-gray-300);background-color:var(--color-gray-50);border-radius:.5rem;min-width:16rem;font-size:.875rem}.datatable-wrapper thead th .datatable-input{color:var(--color-gray-900);background-color:#fff;min-width:0;padding-top:.35rem;padding-bottom:.35rem;font-weight:400}.datatable-wrapper .datatable-search .datatable-input{color:var(--color-gray-900);border:1px solid var(--color-gray-300);background-color:var(--color-gray-50);border-radius:.5rem;min-width:16rem;font-size:.875rem}.dark .datatable-wrapper .datatable-search .datatable-input{color:#fff;background-color:var(--color-gray-800);border:1px solid var(--color-gray-700)}.datatable-wrapper .datatable-search .datatable-input:focus{border-color:var(--color-blue-600)}.flex-1{flex:1}.flex-shrink{flex-shrink:1}.flex-shrink-0{flex-shrink:0}.flex-grow{flex-grow:1}.-translate-x-full{--tw-translate-x:-100%;translate:var(--tw-translate-x)var(--tw-translate-y)}.translate-x-0{--tw-translate-x:calc(var(--spacing)*0);translate:var(--tw-translate-x)var(--tw-translate-y)}.translate-x-full{--tw-translate-x:100%;translate:var(--tw-translate-x)var(--tw-translate-y)}.-translate-y-full{--tw-translate-y:-100%;translate:var(--tw-translate-x)var(--tw-translate-y)}.translate-y-full{--tw-translate-y:100%;translate:var(--tw-translate-x)var(--tw-translate-y)}.rotate-180{rotate:180deg}.transform{transform:var(--tw-rotate-x,)var(--tw-rotate-y,)var(--tw-rotate-z,)var(--tw-skew-x,)var(--tw-skew-y,)}.transform-none{transform:none}.animate-pulse{animation:var(--animate-pulse)}.animate-spin{animation:var(--animate-spin)}.cursor-default{cursor:default}.cursor-not-allowed{cursor:not-allowed}.cursor-pointer{cursor:pointer}.resize{resize:both}.grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}.grid-cols-7{grid-template-columns:repeat(7,minmax(0,1fr))}.flex-col{flex-direction:column}.items-center{align-items:center}.items-end{align-items:flex-end}.items-start{align-items:flex-start}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.justify-end{justify-content:flex-end}.justify-start{justify-content:flex-start}.gap-1{gap:calc(var(--spacing)*1)}:where(.space-y-2>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*2)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*2)*calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-6>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*6)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*6)*calc(1 - var(--tw-space-y-reverse)))}:where(.space-x-2>:not(:last-child)){--tw-space-x-reverse:0;margin-inline-start:calc(calc(var(--spacing)*2)*var(--tw-space-x-reverse));margin-inline-end:calc(calc(var(--spacing)*2)*calc(1 - var(--tw-space-x-reverse)))}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.overflow-hidden{overflow:hidden}.datatable-wrapper .datatable-container{overflow-x:auto}.overflow-x-hidden{overflow-x:hidden}.overflow-y-auto{overflow-y:auto}.rounded{border-radius:.25rem}.rounded-full{border-radius:3.40282e38px}.rounded-lg{border-radius:var(--radius-lg)}.rounded-md{border-radius:var(--radius-md)}.rounded-t{border-top-left-radius:.25rem;border-top-right-radius:.25rem}.rounded-l-lg{border-top-left-radius:var(--radius-lg);border-bottom-left-radius:var(--radius-lg)}.rounded-r-lg{border-top-right-radius:var(--radius-lg);border-bottom-right-radius:var(--radius-lg)}.rounded-b{border-bottom-right-radius:.25rem;border-bottom-left-radius:.25rem}.border{border-style:var(--tw-border-style);border-width:1px}.border-0{border-style:var(--tw-border-style);border-width:0}.border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.border-b{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.dark .apexcharts-canvas .apexcharts-tooltip{background-color:var(--color-gray-700)!important;color:var(--color-gray-400)!important;border-color:#0000!important;box-shadow:0 4px 6px -1px #0000001a,0 2px 4px -2px #0000001a!important}.dark .apexcharts-canvas .apexcharts-tooltip .apexcharts-tooltip-title{background-color:var(--color-gray-600)!important;border-color:var(--color-gray-500)!important;color:var(--color-gray-500)!important}.dark .apexcharts-canvas .apexcharts-xaxistooltip{color:var(--color-gray-400)!important;background-color:var(--color-gray-700)!important}.dark .apexcharts-canvas .apexcharts-xaxistooltip:after,.dark .apexcharts-canvas .apexcharts-xaxistooltip:before{border-bottom-color:var(--color-gray-700)!important}.dark .apexcharts-gridline,.dark .apexcharts-xcrosshairs,.dark .apexcharts-ycrosshairs{stroke:var(--color-gray-700)!important}.dark .datatable-wrapper .datatable-search .datatable-input,.dark .datatable-wrapper .datatable-input{color:#fff;background-color:var(--color-gray-800);border:1px solid var(--color-gray-700)}.dark .datatable-wrapper thead th .datatable-input{background-color:var(--color-gray-700);border-color:var(--color-gray-600);color:#fff}.dark .datatable-wrapper .datatable-top .datatable-dropdown{color:var(--color-gray-400)}.dark .datatable-wrapper .datatable-top .datatable-dropdown .datatable-selector{background-color:var(--color-gray-800);border:1px solid var(--color-gray-700);color:#fff}.dark .datatable-wrapper .datatable-table{color:var(--color-gray-400)}.dark .datatable-wrapper .datatable-table thead{color:var(--color-gray-400);background-color:var(--color-gray-800)}.dark .datatable-wrapper .datatable-table tbody tr{border-bottom:1px solid var(--color-gray-700)}.dark .datatable-wrapper .datatable-bottom .datatable-pagination .datatable-pagination-list-item-link{color:var(--color-gray-400);border-color:var(--color-gray-700)}.dark .datatable-wrapper .datatable-bottom .datatable-pagination .datatable-pagination-list-item:first-of-type .datatable-pagination-list-item-link,.dark .datatable-wrapper .datatable-bottom .datatable-pagination .datatable-pagination-list-item:last-of-type .datatable-pagination-list-item-link{color:#0000}.dark .datatable-wrapper .datatable-bottom .datatable-pagination .datatable-pagination-list-item:first-of-type .datatable-pagination-list-item-link:after{content:url("data:image/svg+xml,%3csvg aria-hidden='true' xmlns='http://www.w3.org/2000/svg' width='20' height='20' fill='none' viewBox='0 0 24 24'%3e %3cpath stroke='%239CA3AF' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m14 8-4 4 4 4'/%3e %3c/svg%3e")}.dark .datatable-wrapper .datatable-bottom .datatable-pagination .datatable-pagination-list-item:first-of-type .datatable-pagination-list-item-link:hover:after{content:url("data:image/svg+xml,%3csvg aria-hidden='true' xmlns='http://www.w3.org/2000/svg' width='20' height='20' fill='none' viewBox='0 0 24 24'%3e %3cpath stroke='white' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m14 8-4 4 4 4'/%3e %3c/svg%3e")}.dark .datatable-wrapper .datatable-bottom .datatable-pagination .datatable-pagination-list-item:last-of-type .datatable-pagination-list-item-link:after{content:url("data:image/svg+xml,%3csvg aria-hidden='true' xmlns='http://www.w3.org/2000/svg' width='20' height='20' fill='none' viewBox='0 0 24 24'%3e %3cpath stroke='%239CA3AF' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m10 16 4-4-4-4'/%3e %3c/svg%3e")}.dark .datatable-wrapper .datatable-bottom .datatable-pagination .datatable-pagination-list-item:last-of-type .datatable-pagination-list-item-link:hover:after{content:url("data:image/svg+xml,%3csvg aria-hidden='true' xmlns='http://www.w3.org/2000/svg' width='20' height='20' fill='none' viewBox='0 0 24 24'%3e %3cpath stroke='white' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m10 16 4-4-4-4'/%3e %3c/svg%3e")}.dark .datatable-wrapper .datatable-bottom .datatable-pagination .datatable-pagination-list-item:first-of-type .datatable-pagination-list-item-link{border-left:1px solid var(--color-gray-700)}.dark .datatable-wrapper .datatable-bottom .datatable-pagination .datatable-pagination-list-item-link:hover{background-color:var(--color-gray-700);color:#fff}.border-blue-300{border-color:var(--color-blue-300)}.border-blue-600{border-color:var(--color-blue-600)}.border-blue-700{border-color:var(--color-blue-700)}.border-gray-100{border-color:var(--color-gray-100)}.border-gray-200{border-color:var(--color-gray-200)}.border-gray-300{border-color:var(--color-gray-300)}.border-green-300{border-color:var(--color-green-300)}.border-red-300{border-color:var(--color-red-300)}.border-red-600{border-color:var(--color-red-600)}.border-red-700{border-color:var(--color-red-700)}.border-transparent{border-color:#0000}.border-yellow-300{border-color:var(--color-yellow-300)}.apexcharts-canvas .apexcharts-tooltip-series-group.apexcharts-active .apexcharts-tooltip-y-group{padding:0!important}.apexcharts-canvas .apexcharts-tooltip-series-group.apexcharts-active{color:var(--color-gray-500)!important;background-color:#fff!important;padding-bottom:.75rem!important;padding-left:.75rem!important;padding-right:.75rem!important}.dark .apexcharts-canvas .apexcharts-tooltip-series-group.apexcharts-active{background-color:var(--color-gray-700)!important;color:var(--color-gray-400)!important}.apexcharts-canvas .apexcharts-tooltip-series-group.apexcharts-active:first-of-type{padding-top:.75rem!important}.datatable-wrapper .datatable-table tbody tr.selected{background-color:var(--color-gray-100)}.dark .datatable-wrapper .datatable-table tbody tr.selected{background-color:var(--color-gray-700)}.selectedCell{background-color:var(--color-gray-50)}.bg-blue-50{background-color:var(--color-blue-50)}.bg-blue-100{background-color:var(--color-blue-100)}.bg-blue-700{background-color:var(--color-blue-700)}.bg-gray-50{background-color:var(--color-gray-50)}.bg-gray-100{background-color:var(--color-gray-100)}.bg-gray-200{background-color:var(--color-gray-200)}.bg-gray-900\/50{background-color:#11182780}@supports (color:color-mix(in lab,red,red)){.bg-gray-900\/50{background-color:color-mix(in oklab,var(--color-gray-900)50%,transparent)}}.bg-green-50{background-color:var(--color-green-50)}.bg-green-100{background-color:var(--color-green-100)}.bg-indigo-600{background-color:var(--color-indigo-600)}.bg-purple-100{background-color:var(--color-purple-100)}.bg-red-50{background-color:var(--color-red-50)}.bg-red-100{background-color:var(--color-red-100)}.bg-red-600{background-color:var(--color-red-600)}.bg-transparent{background-color:#0000}.bg-white{background-color:var(--color-white)}.bg-white\/50{background-color:#ffffff80}@supports (color:color-mix(in lab,red,red)){.bg-white\/50{background-color:color-mix(in oklab,var(--color-white)50%,transparent)}}.bg-yellow-50{background-color:var(--color-yellow-50)}.dark .selectedCell{background-color:var(--color-gray-700)}.apexcharts-canvas .apexcharts-datalabels-group .apexcharts-text.apexcharts-datalabel-label{fill:var(--color-gray-500)!important;font-size:1rem,[object Object]!important;font-weight:400!important}.dark .apexcharts-canvas .apexcharts-datalabels-group .apexcharts-text.apexcharts-datalabel-label{fill:var(--color-gray-400)!important}.apexcharts-datalabels-group .apexcharts-text.apexcharts-datalabel-value{fill:var(--color-gray-900)!important;font-size:1.875rem,[object Object]!important;font-weight:700!important}.dark .apexcharts-canvas .apexcharts-datalabels-group .apexcharts-text.apexcharts-datalabel-value{fill:#fff!important}.apexcharts-ycrosshairs{stroke:var(--color-gray-200)!important}.dark .apexcharts-ycrosshairs{stroke:var(--color-gray-700)!important}.apexcharts-canvas .apexcharts-legend,.apexcharts-canvas .apexcharts-tooltip-series-group.apexcharts-active .apexcharts-tooltip-y-group{padding:0!important}.p-1{padding:calc(var(--spacing)*1)}.p-1\.5{padding:calc(var(--spacing)*1.5)}.p-2{padding:calc(var(--spacing)*2)}.p-2\.5{padding:calc(var(--spacing)*2.5)}.p-4{padding:calc(var(--spacing)*4)}.p-6{padding:calc(var(--spacing)*6)}.px-1\.5{padding-inline:calc(var(--spacing)*1.5)}.px-2{padding-inline:calc(var(--spacing)*2)}.px-3{padding-inline:calc(var(--spacing)*3)}.px-4{padding-inline:calc(var(--spacing)*4)}.px-5{padding-inline:calc(var(--spacing)*5)}.py-0\.5{padding-block:calc(var(--spacing)*.5)}.py-1{padding-block:calc(var(--spacing)*1)}.py-1\.5{padding-block:calc(var(--spacing)*1.5)}.py-2{padding-block:calc(var(--spacing)*2)}.py-2\.5{padding-block:calc(var(--spacing)*2.5)}.py-3{padding-block:calc(var(--spacing)*3)}.py-4{padding-block:calc(var(--spacing)*4)}.pt-2{padding-top:calc(var(--spacing)*2)}.datatable-wrapper .datatable-container thead tr.search-filtering-row th{padding-top:0}.apexcharts-canvas .apexcharts-legend-text{color:var(--color-gray-500)!important;padding-left:1.25rem!important;font-size:.75rem!important;font-weight:500!important}[dir=rtl] .apexcharts-canvas .apexcharts-legend-text{padding-right:.5rem!important}.apexcharts-canvas .apexcharts-legend-text:not(.apexcharts-inactive-legend):hover{color:var(--color-gray-900)!important}.dark .apexcharts-canvas .apexcharts-legend-text{color:var(--color-gray-400)!important}.dark .apexcharts-canvas .apexcharts-legend-text:not(.apexcharts-inactive-legend):hover{color:#fff!important}.pr-10{padding-right:calc(var(--spacing)*10)}.pl-2{padding-left:calc(var(--spacing)*2)}.datatable-wrapper .datatable-table .datatable-empty,.text-center{text-align:center}.text-3xl{font-size:var(--text-3xl);line-height:var(--tw-leading,var(--text-3xl--line-height))}.text-base{font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height))}.text-lg{font-size:var(--text-lg);line-height:var(--tw-leading,var(--text-lg--line-height))}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-xl{font-size:var(--text-xl);line-height:var(--tw-leading,var(--text-xl--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.apexcharts-canvas .apexcharts-datalabels .apexcharts-text.apexcharts-pie-label{text-shadow:none!important;filter:none!important;font-size:.75rem,[object Object]!important;font-weight:600!important}.apexcharts-canvas .apexcharts-xaxistooltip-text{font-size:.875rem!important;font-weight:400!important}.apexcharts-canvas .apexcharts-tooltip .apexcharts-tooltip-text-y-label{color:var(--color-gray-500)!important;font-size:.875rem!important}.dark .apexcharts-canvas .apexcharts-tooltip .apexcharts-tooltip-text-y-label{color:var(--color-gray-400)!important}.apexcharts-canvas .apexcharts-tooltip .apexcharts-tooltip-text-y-value{color:var(--color-gray-900);font-size:.875rem!important}.dark .apexcharts-canvas .apexcharts-tooltip .apexcharts-tooltip-text-y-value{color:#fff!important}.datatable-wrapper .datatable-bottom .datatable-info{color:var(--color-gray-500);font-size:.875rem}.dark .datatable-wrapper .datatable-bottom .datatable-info{color:var(--color-gray-400)}.leading-6{--tw-leading:calc(var(--spacing)*6);line-height:calc(var(--spacing)*6)}.leading-9{--tw-leading:calc(var(--spacing)*9);line-height:calc(var(--spacing)*9)}.leading-relaxed{--tw-leading:var(--leading-relaxed);line-height:var(--leading-relaxed)}.font-bold{--tw-font-weight:var(--font-weight-bold);font-weight:var(--font-weight-bold)}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.datatable-wrapper .datatable-table thead th .datatable-sorter{text-transform:uppercase}.datatable-wrapper .datatable-table thead th .datatable-sorter:hover,.datatable-wrapper .datatable-table thead th.datatable-ascending .datatable-sorter,.datatable-wrapper .datatable-table thead th.datatable-descending .datatable-sorter{color:var(--color-gray-900)}.dark .datatable-wrapper .datatable-table thead th .datatable-sorter:hover,.dark .datatable-wrapper .datatable-table thead th.datatable-ascending .datatable-sorter,.dark .datatable-wrapper .datatable-table thead th.datatable-descending .datatable-sorter{color:#fff}.datatable-wrapper .datatable-table thead th.datatable-ascending .datatable-sorter{color:var(--color-gray-900)}.dark .datatable-wrapper .datatable-table thead th.datatable-ascending .datatable-sorter{color:#fff}.datatable-wrapper .datatable-table thead th.datatable-descending .datatable-sorter{color:var(--color-gray-900)}.dark .datatable-wrapper .datatable-table thead th.datatable-descending .datatable-sorter{color:#fff}.text-blue-600{color:var(--color-blue-600)}.text-blue-800{color:var(--color-blue-800)}.text-gray-400{color:var(--color-gray-400)}.text-gray-500{color:var(--color-gray-500)}.text-gray-600{color:var(--color-gray-600)}.text-gray-700{color:var(--color-gray-700)}.text-gray-800{color:var(--color-gray-800)}.text-gray-900{color:var(--color-gray-900)}.text-green-800{color:var(--color-green-800)}.text-indigo-600{color:var(--color-indigo-600)}.text-purple-800{color:var(--color-purple-800)}.text-red-500{color:var(--color-red-500)}.text-red-700{color:var(--color-red-700)}.text-red-800{color:var(--color-red-800)}.text-white{color:var(--color-white)}.text-yellow-800{color:var(--color-yellow-800)}.lowercase{text-transform:lowercase}.uppercase{text-transform:uppercase}.italic{font-style:italic}.underline{text-decoration-line:underline}.underline-offset-4{text-underline-offset:4px}.opacity-0{opacity:0}.opacity-25{opacity:.25}.opacity-75{opacity:.75}.opacity-100{opacity:1}.shadow{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a),0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-lg{--tw-shadow:0 10px 15px -3px var(--tw-shadow-color,#0000001a),0 4px 6px -4px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-sm{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a),0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.outline{outline-style:var(--tw-outline-style);outline-width:1px}.blur{--tw-blur:blur(8px);filter:var(--tw-blur,)var(--tw-brightness,)var(--tw-contrast,)var(--tw-grayscale,)var(--tw-hue-rotate,)var(--tw-invert,)var(--tw-saturate,)var(--tw-sepia,)var(--tw-drop-shadow,)}.filter{filter:var(--tw-blur,)var(--tw-brightness,)var(--tw-contrast,)var(--tw-grayscale,)var(--tw-hue-rotate,)var(--tw-invert,)var(--tw-saturate,)var(--tw-sepia,)var(--tw-drop-shadow,)}.transition{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-opacity{transition-property:opacity;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-transform{transition-property:transform,translate,scale,rotate;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.duration-150{--tw-duration:.15s;transition-duration:.15s}.ease-in-out{--tw-ease:var(--ease-in-out);transition-timing-function:var(--ease-in-out)}.ease-out{--tw-ease:var(--ease-out);transition-timing-function:var(--ease-out)}.last\:border-b-0:last-child{border-bottom-style:var(--tw-border-style);border-bottom-width:0}@media (hover:hover){.hover\:border-gray-300:hover{border-color:var(--color-gray-300)}.hover\:bg-blue-800:hover{background-color:var(--color-blue-800)}.hover\:bg-gray-100:hover{background-color:var(--color-gray-100)}.hover\:bg-gray-200:hover{background-color:var(--color-gray-200)}.hover\:bg-indigo-700:hover{background-color:var(--color-indigo-700)}.hover\:bg-red-700:hover{background-color:var(--color-red-700)}.hover\:bg-white:hover{background-color:var(--color-white)}.hover\:text-blue-600:hover{color:var(--color-blue-600)}.hover\:text-gray-600:hover{color:var(--color-gray-600)}.hover\:text-gray-900:hover{color:var(--color-gray-900)}.hover\:text-white:hover{color:var(--color-white)}.hover\:underline:hover{text-decoration-line:underline}}.focus\:z-10:focus{z-index:10}.focus\:border-blue-500:focus{border-color:var(--color-blue-500)}.focus\:border-indigo-500:focus{border-color:var(--color-indigo-500)}.focus\:ring-2:focus{--tw-ring-shadow:var(--tw-ring-inset,)0 0 0 calc(2px + var(--tw-ring-offset-width))var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.focus\:ring-4:focus{--tw-ring-shadow:var(--tw-ring-inset,)0 0 0 calc(4px + var(--tw-ring-offset-width))var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.focus\:ring-blue-300:focus{--tw-ring-color:var(--color-blue-300)}.focus\:ring-blue-500:focus{--tw-ring-color:var(--color-blue-500)}.focus\:ring-gray-200:focus{--tw-ring-color:var(--color-gray-200)}.focus\:ring-indigo-500:focus{--tw-ring-color:var(--color-indigo-500)}.focus\:ring-red-300:focus{--tw-ring-color:var(--color-red-300)}.focus\:ring-offset-2:focus{--tw-ring-offset-width:2px;--tw-ring-offset-shadow:var(--tw-ring-inset,)0 0 0 var(--tw-ring-offset-width)var(--tw-ring-offset-color)}.focus\:outline-none:focus{--tw-outline-style:none;outline-style:none}@media (min-width:40rem){.sm\:text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}}@media (min-width:48rem){.md\:inset-0{inset:calc(var(--spacing)*0)}}.rtl\:rotate-180:where(:dir(rtl),[dir=rtl],[dir=rtl] *){rotate:180deg}:where(.rtl\:space-x-reverse:where(:dir(rtl),[dir=rtl],[dir=rtl] *)>:not(:last-child)){--tw-space-x-reverse:1}@media (prefers-color-scheme:dark){.dark\:border-blue-500{border-color:var(--color-blue-500)}.dark\:border-blue-800{border-color:var(--color-blue-800)}.dark\:border-gray-500{border-color:var(--color-gray-500)}.dark\:border-gray-600{border-color:var(--color-gray-600)}.dark\:border-gray-700{border-color:var(--color-gray-700)}.dark\:border-green-800{border-color:var(--color-green-800)}.dark\:border-red-500{border-color:var(--color-red-500)}.dark\:border-red-700{border-color:var(--color-red-700)}.dark\:border-red-800{border-color:var(--color-red-800)}.dark\:border-transparent{border-color:#0000}.dark\:border-yellow-800{border-color:var(--color-yellow-800)}.dark\:bg-blue-600{background-color:var(--color-blue-600)}.dark\:bg-blue-900{background-color:var(--color-blue-900)}.dark\:bg-gray-600{background-color:var(--color-gray-600)}.dark\:bg-gray-700{background-color:var(--color-gray-700)}.dark\:bg-gray-800{background-color:var(--color-gray-800)}.dark\:bg-gray-800\/50{background-color:#1f293780}@supports (color:color-mix(in lab,red,red)){.dark\:bg-gray-800\/50{background-color:color-mix(in oklab,var(--color-gray-800)50%,transparent)}}.dark\:bg-gray-900{background-color:var(--color-gray-900)}.dark\:bg-gray-900\/80{background-color:#111827cc}@supports (color:color-mix(in lab,red,red)){.dark\:bg-gray-900\/80{background-color:color-mix(in oklab,var(--color-gray-900)80%,transparent)}}.dark\:bg-green-900{background-color:var(--color-green-900)}.dark\:bg-purple-900{background-color:var(--color-purple-900)}.dark\:bg-red-700{background-color:var(--color-red-700)}.dark\:bg-red-900{background-color:var(--color-red-900)}.dark\:text-blue-300{color:var(--color-blue-300)}.dark\:text-blue-400{color:var(--color-blue-400)}.dark\:text-blue-500{color:var(--color-blue-500)}.dark\:text-gray-300{color:var(--color-gray-300)}.dark\:text-gray-400{color:var(--color-gray-400)}.dark\:text-gray-500{color:var(--color-gray-500)}.dark\:text-green-300{color:var(--color-green-300)}.dark\:text-green-400{color:var(--color-green-400)}.dark\:text-purple-300{color:var(--color-purple-300)}.dark\:text-red-300{color:var(--color-red-300)}.dark\:text-red-400{color:var(--color-red-400)}.dark\:text-red-500{color:var(--color-red-500)}.dark\:text-white{color:var(--color-white)}.dark\:text-yellow-300{color:var(--color-yellow-300)}.dark\:placeholder-gray-400::-moz-placeholder{color:var(--color-gray-400)}.dark\:placeholder-gray-400::placeholder{color:var(--color-gray-400)}.dark\:format-invert{--tw-format-body:var(--tw-format-invert-body);--tw-format-headings:var(--tw-format-invert-headings);--tw-format-lead:var(--tw-format-invert-lead);--tw-format-links:var(--tw-format-invert-links);--tw-format-bold:var(--tw-format-invert-bold);--tw-format-counters:var(--tw-format-invert-counters);--tw-format-bullets:var(--tw-format-invert-bullets);--tw-format-hr:var(--tw-format-invert-hr);--tw-format-quotes:var(--tw-format-invert-quotes);--tw-format-quote-borders:var(--tw-format-invert-quote-borders);--tw-format-captions:var(--tw-format-invert-captions);--tw-format-code:var(--tw-format-invert-code);--tw-format-code-bg:var(--tw-format-invert-code-bg);--tw-format-pre-code:var(--tw-format-invert-pre-code);--tw-format-pre-bg:var(--tw-format-invert-pre-bg);--tw-format-th-borders:var(--tw-format-invert-th-borders);--tw-format-td-borders:var(--tw-format-invert-td-borders);--tw-format-th-bg:var(--tw-format-invert-th-bg)}@media (hover:hover){.dark\:hover\:bg-blue-700:hover{background-color:var(--color-blue-700)}.dark\:hover\:bg-gray-600:hover{background-color:var(--color-gray-600)}.dark\:hover\:bg-gray-800:hover{background-color:var(--color-gray-800)}.dark\:hover\:bg-red-500:hover{background-color:var(--color-red-500)}.dark\:hover\:text-blue-500:hover{color:var(--color-blue-500)}.dark\:hover\:text-gray-300:hover{color:var(--color-gray-300)}.dark\:hover\:text-white:hover{color:var(--color-white)}}.dark\:focus\:border-blue-500:focus{border-color:var(--color-blue-500)}.dark\:focus\:ring-blue-500:focus{--tw-ring-color:var(--color-blue-500)}.dark\:focus\:ring-blue-800:focus{--tw-ring-color:var(--color-blue-800)}.dark\:focus\:ring-gray-600:focus{--tw-ring-color:var(--color-gray-600)}.dark\:focus\:ring-red-800:focus{--tw-ring-color:var(--color-red-800)}}}@property --tw-translate-x{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-y{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-z{syntax:"*";inherits:false;initial-value:0}@property --tw-rotate-x{syntax:"*";inherits:false}@property --tw-rotate-y{syntax:"*";inherits:false}@property --tw-rotate-z{syntax:"*";inherits:false}@property --tw-skew-x{syntax:"*";inherits:false}@property --tw-skew-y{syntax:"*";inherits:false}@property --tw-space-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-space-x-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-leading{syntax:"*";inherits:false}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"<length>";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-outline-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-blur{syntax:"*";inherits:false}@property --tw-brightness{syntax:"*";inherits:false}@property --tw-contrast{syntax:"*";inherits:false}@property --tw-grayscale{syntax:"*";inherits:false}@property --tw-hue-rotate{syntax:"*";inherits:false}@property --tw-invert{syntax:"*";inherits:false}@property --tw-opacity{syntax:"*";inherits:false}@property --tw-saturate{syntax:"*";inherits:false}@property --tw-sepia{syntax:"*";inherits:false}@property --tw-drop-shadow{syntax:"*";inherits:false}@property --tw-drop-shadow-color{syntax:"*";inherits:false}@property --tw-drop-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-drop-shadow-size{syntax:"*";inherits:false}@property --tw-duration{syntax:"*";inherits:false}@property --tw-ease{syntax:"*";inherits:false}@keyframes spin{to{transform:rotate(360deg)}}@keyframes pulse{50%{opacity:.5}}
|