Spaces:
Sleeping
Sleeping
Commit
·
6c7da6d
1
Parent(s):
e46de24
Improve the code and UI for easy usage
Browse files- index.html +6 -3
- package-lock.json +1549 -85
- package.json +3 -1
- src/backend/profile_data.py +80 -0
- src/backend/voice_assistant.py +36 -105
- src/components/App.jsx +25 -4
- src/components/Footer.jsx +1 -1
- src/components/VoiceAssistant.jsx +361 -301
- src/main.jsx +28 -2
index.html
CHANGED
|
@@ -1,13 +1,16 @@
|
|
| 1 |
<!DOCTYPE html>
|
| 2 |
-
<html lang="en">
|
| 3 |
<head>
|
| 4 |
<meta charset="UTF-8" />
|
| 5 |
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
| 6 |
<title>AI Voice Secretary</title>
|
| 7 |
-
<script type="module" src="/src/main.jsx"></script>
|
| 8 |
<script src="https://cdn.tailwindcss.com"></script>
|
|
|
|
|
|
|
|
|
|
| 9 |
</head>
|
| 10 |
-
<body class="bg-gray-100 font-sans">
|
| 11 |
<div id="root"></div>
|
| 12 |
</body>
|
| 13 |
</html>
|
|
|
|
| 1 |
<!DOCTYPE html>
|
| 2 |
+
<html lang="en" class="dark">
|
| 3 |
<head>
|
| 4 |
<meta charset="UTF-8" />
|
| 5 |
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
| 6 |
<title>AI Voice Secretary</title>
|
| 7 |
+
<link rel="icon" type="image/svg+xml" href="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32'%3E%3Ccircle cx='16' cy='16' r='16' fill='%23006DFF'/%3E%3Ctext x='16' y='22' font-size='16' text-anchor='middle' fill='white' font-family='Arial'%3E%F0%9F%8E%A4%3C/text%3E%3C/svg%3E"/> <script type="module" src="/src/main.jsx"></script>
|
| 8 |
<script src="https://cdn.tailwindcss.com"></script>
|
| 9 |
+
<script>
|
| 10 |
+
tailwind.config = { darkMode: 'class' };
|
| 11 |
+
</script>
|
| 12 |
</head>
|
| 13 |
+
<body class="bg-gray-100 dark:bg-gray-900 font-sans">
|
| 14 |
<div id="root"></div>
|
| 15 |
</body>
|
| 16 |
</html>
|
package-lock.json
CHANGED
|
@@ -11,7 +11,9 @@
|
|
| 11 |
"date-fns": "^4.1.0",
|
| 12 |
"lucide-react": "^0.525.0",
|
| 13 |
"react": "^19.0.0",
|
| 14 |
-
"react-dom": "^19.0.0"
|
|
|
|
|
|
|
| 15 |
},
|
| 16 |
"devDependencies": {
|
| 17 |
"@eslint/js": "^9.22.0",
|
|
@@ -1367,13 +1369,39 @@
|
|
| 1367 |
"@babel/types": "^7.20.7"
|
| 1368 |
}
|
| 1369 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1370 |
"node_modules/@types/estree": {
|
| 1371 |
"version": "1.0.8",
|
| 1372 |
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz",
|
| 1373 |
"integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==",
|
| 1374 |
-
"dev": true,
|
| 1375 |
"license": "MIT"
|
| 1376 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1377 |
"node_modules/@types/json-schema": {
|
| 1378 |
"version": "7.0.15",
|
| 1379 |
"resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz",
|
|
@@ -1381,11 +1409,25 @@
|
|
| 1381 |
"dev": true,
|
| 1382 |
"license": "MIT"
|
| 1383 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1384 |
"node_modules/@types/react": {
|
| 1385 |
"version": "19.1.8",
|
| 1386 |
"resolved": "https://registry.npmjs.org/@types/react/-/react-19.1.8.tgz",
|
| 1387 |
"integrity": "sha512-AwAfQ2Wa5bCx9WP8nZL2uMZWod7J7/JSplxbTmBQ5ms6QpqNYm672H0Vu9ZVKVngQ+ii4R/byguVEUZQyeg44g==",
|
| 1388 |
-
"dev": true,
|
| 1389 |
"license": "MIT",
|
| 1390 |
"dependencies": {
|
| 1391 |
"csstype": "^3.0.2"
|
|
@@ -1401,6 +1443,18 @@
|
|
| 1401 |
"@types/react": "^19.0.0"
|
| 1402 |
}
|
| 1403 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1404 |
"node_modules/@vitejs/plugin-react": {
|
| 1405 |
"version": "4.6.0",
|
| 1406 |
"resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-4.6.0.tgz",
|
|
@@ -1523,6 +1577,16 @@
|
|
| 1523 |
"postcss": "^8.1.0"
|
| 1524 |
}
|
| 1525 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1526 |
"node_modules/balanced-match": {
|
| 1527 |
"version": "1.0.2",
|
| 1528 |
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
|
|
@@ -1605,6 +1669,16 @@
|
|
| 1605 |
],
|
| 1606 |
"license": "CC-BY-4.0"
|
| 1607 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1608 |
"node_modules/chalk": {
|
| 1609 |
"version": "4.1.2",
|
| 1610 |
"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
|
|
@@ -1622,6 +1696,46 @@
|
|
| 1622 |
"url": "https://github.com/chalk/chalk?sponsor=1"
|
| 1623 |
}
|
| 1624 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1625 |
"node_modules/color-convert": {
|
| 1626 |
"version": "2.0.1",
|
| 1627 |
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
|
|
@@ -1642,6 +1756,16 @@
|
|
| 1642 |
"dev": true,
|
| 1643 |
"license": "MIT"
|
| 1644 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1645 |
"node_modules/concat-map": {
|
| 1646 |
"version": "0.0.1",
|
| 1647 |
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
|
|
@@ -1675,7 +1799,6 @@
|
|
| 1675 |
"version": "3.1.3",
|
| 1676 |
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz",
|
| 1677 |
"integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==",
|
| 1678 |
-
"dev": true,
|
| 1679 |
"license": "MIT"
|
| 1680 |
},
|
| 1681 |
"node_modules/date-fns": {
|
|
@@ -1692,7 +1815,6 @@
|
|
| 1692 |
"version": "4.4.1",
|
| 1693 |
"resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz",
|
| 1694 |
"integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==",
|
| 1695 |
-
"dev": true,
|
| 1696 |
"license": "MIT",
|
| 1697 |
"dependencies": {
|
| 1698 |
"ms": "^2.1.3"
|
|
@@ -1706,6 +1828,19 @@
|
|
| 1706 |
}
|
| 1707 |
}
|
| 1708 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1709 |
"node_modules/deep-is": {
|
| 1710 |
"version": "0.1.4",
|
| 1711 |
"resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz",
|
|
@@ -1713,6 +1848,28 @@
|
|
| 1713 |
"dev": true,
|
| 1714 |
"license": "MIT"
|
| 1715 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1716 |
"node_modules/electron-to-chromium": {
|
| 1717 |
"version": "1.5.177",
|
| 1718 |
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.177.tgz",
|
|
@@ -1952,6 +2109,16 @@
|
|
| 1952 |
"node": ">=4.0"
|
| 1953 |
}
|
| 1954 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1955 |
"node_modules/esutils": {
|
| 1956 |
"version": "2.0.3",
|
| 1957 |
"resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
|
|
@@ -1962,6 +2129,12 @@
|
|
| 1962 |
"node": ">=0.10.0"
|
| 1963 |
}
|
| 1964 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1965 |
"node_modules/fast-deep-equal": {
|
| 1966 |
"version": "3.1.3",
|
| 1967 |
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
|
|
@@ -2124,6 +2297,56 @@
|
|
| 2124 |
"node": ">=8"
|
| 2125 |
}
|
| 2126 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2127 |
"node_modules/ignore": {
|
| 2128 |
"version": "5.3.2",
|
| 2129 |
"resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz",
|
|
@@ -2161,6 +2384,46 @@
|
|
| 2161 |
"node": ">=0.8.19"
|
| 2162 |
}
|
| 2163 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2164 |
"node_modules/is-extglob": {
|
| 2165 |
"version": "2.1.1",
|
| 2166 |
"resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
|
|
@@ -2184,6 +2447,28 @@
|
|
| 2184 |
"node": ">=0.10.0"
|
| 2185 |
}
|
| 2186 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2187 |
"node_modules/isexe": {
|
| 2188 |
"version": "2.0.0",
|
| 2189 |
"resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
|
|
@@ -2305,6 +2590,16 @@
|
|
| 2305 |
"dev": true,
|
| 2306 |
"license": "MIT"
|
| 2307 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2308 |
"node_modules/lru-cache": {
|
| 2309 |
"version": "5.1.1",
|
| 2310 |
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
|
|
@@ -2324,108 +2619,962 @@
|
|
| 2324 |
"react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0"
|
| 2325 |
}
|
| 2326 |
},
|
| 2327 |
-
"node_modules/
|
| 2328 |
-
"version": "3.
|
| 2329 |
-
"resolved": "https://registry.npmjs.org/
|
| 2330 |
-
"integrity": "sha512-
|
| 2331 |
-
"
|
| 2332 |
-
"
|
| 2333 |
-
|
| 2334 |
-
"
|
| 2335 |
-
},
|
| 2336 |
-
"engines": {
|
| 2337 |
-
"node": "*"
|
| 2338 |
}
|
| 2339 |
},
|
| 2340 |
-
"node_modules/
|
| 2341 |
-
"version": "
|
| 2342 |
-
"resolved": "https://registry.npmjs.org/
|
| 2343 |
-
"integrity": "sha512-
|
| 2344 |
-
"dev": true,
|
| 2345 |
-
"license": "MIT"
|
| 2346 |
-
},
|
| 2347 |
-
"node_modules/nanoid": {
|
| 2348 |
-
"version": "3.3.11",
|
| 2349 |
-
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz",
|
| 2350 |
-
"integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==",
|
| 2351 |
-
"dev": true,
|
| 2352 |
-
"funding": [
|
| 2353 |
-
{
|
| 2354 |
-
"type": "github",
|
| 2355 |
-
"url": "https://github.com/sponsors/ai"
|
| 2356 |
-
}
|
| 2357 |
-
],
|
| 2358 |
"license": "MIT",
|
| 2359 |
-
"
|
| 2360 |
-
"
|
|
|
|
|
|
|
|
|
|
| 2361 |
},
|
| 2362 |
-
"
|
| 2363 |
-
"
|
|
|
|
| 2364 |
}
|
| 2365 |
},
|
| 2366 |
-
"node_modules/
|
| 2367 |
-
"version": "
|
| 2368 |
-
"resolved": "https://registry.npmjs.org/
|
| 2369 |
-
"integrity": "sha512
|
| 2370 |
-
"dev": true,
|
| 2371 |
-
"license": "MIT"
|
| 2372 |
-
},
|
| 2373 |
-
"node_modules/node-releases": {
|
| 2374 |
-
"version": "2.0.19",
|
| 2375 |
-
"resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz",
|
| 2376 |
-
"integrity": "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==",
|
| 2377 |
-
"dev": true,
|
| 2378 |
-
"license": "MIT"
|
| 2379 |
-
},
|
| 2380 |
-
"node_modules/normalize-range": {
|
| 2381 |
-
"version": "0.1.2",
|
| 2382 |
-
"resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz",
|
| 2383 |
-
"integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==",
|
| 2384 |
-
"dev": true,
|
| 2385 |
"license": "MIT",
|
| 2386 |
"engines": {
|
| 2387 |
-
"node": ">=
|
|
|
|
|
|
|
|
|
|
| 2388 |
}
|
| 2389 |
},
|
| 2390 |
-
"node_modules/
|
| 2391 |
-
"version": "0.
|
| 2392 |
-
"resolved": "https://registry.npmjs.org/
|
| 2393 |
-
"integrity": "sha512-
|
| 2394 |
-
"dev": true,
|
| 2395 |
"license": "MIT",
|
| 2396 |
"dependencies": {
|
| 2397 |
-
"
|
| 2398 |
-
"
|
| 2399 |
-
"
|
| 2400 |
-
"
|
| 2401 |
-
"
|
| 2402 |
-
"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2403 |
},
|
| 2404 |
-
"
|
| 2405 |
-
"
|
|
|
|
| 2406 |
}
|
| 2407 |
},
|
| 2408 |
-
"node_modules/
|
| 2409 |
"version": "3.1.0",
|
| 2410 |
-
"resolved": "https://registry.npmjs.org/
|
| 2411 |
-
"integrity": "sha512-
|
| 2412 |
-
"dev": true,
|
| 2413 |
"license": "MIT",
|
| 2414 |
"dependencies": {
|
| 2415 |
-
"
|
| 2416 |
-
|
| 2417 |
-
|
| 2418 |
-
"
|
|
|
|
|
|
|
|
|
|
| 2419 |
},
|
| 2420 |
"funding": {
|
| 2421 |
-
"
|
|
|
|
| 2422 |
}
|
| 2423 |
},
|
| 2424 |
-
"node_modules/
|
| 2425 |
-
"version": "
|
| 2426 |
-
"resolved": "https://registry.npmjs.org/
|
| 2427 |
-
"integrity": "sha512-
|
| 2428 |
-
"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2429 |
"license": "MIT",
|
| 2430 |
"dependencies": {
|
| 2431 |
"p-limit": "^3.0.2"
|
|
@@ -2450,6 +3599,31 @@
|
|
| 2450 |
"node": ">=6"
|
| 2451 |
}
|
| 2452 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2453 |
"node_modules/path-exists": {
|
| 2454 |
"version": "4.0.0",
|
| 2455 |
"resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
|
|
@@ -2536,6 +3710,16 @@
|
|
| 2536 |
"node": ">= 0.8.0"
|
| 2537 |
}
|
| 2538 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2539 |
"node_modules/punycode": {
|
| 2540 |
"version": "2.3.1",
|
| 2541 |
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz",
|
|
@@ -2567,6 +3751,33 @@
|
|
| 2567 |
"react": "^19.1.0"
|
| 2568 |
}
|
| 2569 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2570 |
"node_modules/react-refresh": {
|
| 2571 |
"version": "0.17.0",
|
| 2572 |
"resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.17.0.tgz",
|
|
@@ -2577,6 +3788,72 @@
|
|
| 2577 |
"node": ">=0.10.0"
|
| 2578 |
}
|
| 2579 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2580 |
"node_modules/resolve-from": {
|
| 2581 |
"version": "4.0.0",
|
| 2582 |
"resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
|
|
@@ -2676,6 +3953,30 @@
|
|
| 2676 |
"node": ">=0.10.0"
|
| 2677 |
}
|
| 2678 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2679 |
"node_modules/strip-json-comments": {
|
| 2680 |
"version": "3.1.1",
|
| 2681 |
"resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz",
|
|
@@ -2689,6 +3990,24 @@
|
|
| 2689 |
"url": "https://github.com/sponsors/sindresorhus"
|
| 2690 |
}
|
| 2691 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2692 |
"node_modules/supports-color": {
|
| 2693 |
"version": "7.2.0",
|
| 2694 |
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
|
|
@@ -2726,6 +4045,26 @@
|
|
| 2726 |
"url": "https://github.com/sponsors/SuperchupuDev"
|
| 2727 |
}
|
| 2728 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2729 |
"node_modules/type-check": {
|
| 2730 |
"version": "0.4.0",
|
| 2731 |
"resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz",
|
|
@@ -2739,6 +4078,93 @@
|
|
| 2739 |
"node": ">= 0.8.0"
|
| 2740 |
}
|
| 2741 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2742 |
"node_modules/update-browserslist-db": {
|
| 2743 |
"version": "1.1.3",
|
| 2744 |
"resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.3.tgz",
|
|
@@ -2780,6 +4206,34 @@
|
|
| 2780 |
"punycode": "^2.1.0"
|
| 2781 |
}
|
| 2782 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2783 |
"node_modules/vite": {
|
| 2784 |
"version": "6.3.5",
|
| 2785 |
"resolved": "https://registry.npmjs.org/vite/-/vite-6.3.5.tgz",
|
|
@@ -2900,6 +4354,16 @@
|
|
| 2900 |
"funding": {
|
| 2901 |
"url": "https://github.com/sponsors/sindresorhus"
|
| 2902 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2903 |
}
|
| 2904 |
}
|
| 2905 |
}
|
|
|
|
| 11 |
"date-fns": "^4.1.0",
|
| 12 |
"lucide-react": "^0.525.0",
|
| 13 |
"react": "^19.0.0",
|
| 14 |
+
"react-dom": "^19.0.0",
|
| 15 |
+
"react-markdown": "^10.1.0",
|
| 16 |
+
"remark-gfm": "^4.0.1"
|
| 17 |
},
|
| 18 |
"devDependencies": {
|
| 19 |
"@eslint/js": "^9.22.0",
|
|
|
|
| 1369 |
"@babel/types": "^7.20.7"
|
| 1370 |
}
|
| 1371 |
},
|
| 1372 |
+
"node_modules/@types/debug": {
|
| 1373 |
+
"version": "4.1.12",
|
| 1374 |
+
"resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz",
|
| 1375 |
+
"integrity": "sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==",
|
| 1376 |
+
"license": "MIT",
|
| 1377 |
+
"dependencies": {
|
| 1378 |
+
"@types/ms": "*"
|
| 1379 |
+
}
|
| 1380 |
+
},
|
| 1381 |
"node_modules/@types/estree": {
|
| 1382 |
"version": "1.0.8",
|
| 1383 |
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz",
|
| 1384 |
"integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==",
|
|
|
|
| 1385 |
"license": "MIT"
|
| 1386 |
},
|
| 1387 |
+
"node_modules/@types/estree-jsx": {
|
| 1388 |
+
"version": "1.0.5",
|
| 1389 |
+
"resolved": "https://registry.npmjs.org/@types/estree-jsx/-/estree-jsx-1.0.5.tgz",
|
| 1390 |
+
"integrity": "sha512-52CcUVNFyfb1A2ALocQw/Dd1BQFNmSdkuC3BkZ6iqhdMfQz7JWOFRuJFloOzjk+6WijU56m9oKXFAXc7o3Towg==",
|
| 1391 |
+
"license": "MIT",
|
| 1392 |
+
"dependencies": {
|
| 1393 |
+
"@types/estree": "*"
|
| 1394 |
+
}
|
| 1395 |
+
},
|
| 1396 |
+
"node_modules/@types/hast": {
|
| 1397 |
+
"version": "3.0.4",
|
| 1398 |
+
"resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.4.tgz",
|
| 1399 |
+
"integrity": "sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==",
|
| 1400 |
+
"license": "MIT",
|
| 1401 |
+
"dependencies": {
|
| 1402 |
+
"@types/unist": "*"
|
| 1403 |
+
}
|
| 1404 |
+
},
|
| 1405 |
"node_modules/@types/json-schema": {
|
| 1406 |
"version": "7.0.15",
|
| 1407 |
"resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz",
|
|
|
|
| 1409 |
"dev": true,
|
| 1410 |
"license": "MIT"
|
| 1411 |
},
|
| 1412 |
+
"node_modules/@types/mdast": {
|
| 1413 |
+
"version": "4.0.4",
|
| 1414 |
+
"resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.4.tgz",
|
| 1415 |
+
"integrity": "sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==",
|
| 1416 |
+
"license": "MIT",
|
| 1417 |
+
"dependencies": {
|
| 1418 |
+
"@types/unist": "*"
|
| 1419 |
+
}
|
| 1420 |
+
},
|
| 1421 |
+
"node_modules/@types/ms": {
|
| 1422 |
+
"version": "2.1.0",
|
| 1423 |
+
"resolved": "https://registry.npmjs.org/@types/ms/-/ms-2.1.0.tgz",
|
| 1424 |
+
"integrity": "sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==",
|
| 1425 |
+
"license": "MIT"
|
| 1426 |
+
},
|
| 1427 |
"node_modules/@types/react": {
|
| 1428 |
"version": "19.1.8",
|
| 1429 |
"resolved": "https://registry.npmjs.org/@types/react/-/react-19.1.8.tgz",
|
| 1430 |
"integrity": "sha512-AwAfQ2Wa5bCx9WP8nZL2uMZWod7J7/JSplxbTmBQ5ms6QpqNYm672H0Vu9ZVKVngQ+ii4R/byguVEUZQyeg44g==",
|
|
|
|
| 1431 |
"license": "MIT",
|
| 1432 |
"dependencies": {
|
| 1433 |
"csstype": "^3.0.2"
|
|
|
|
| 1443 |
"@types/react": "^19.0.0"
|
| 1444 |
}
|
| 1445 |
},
|
| 1446 |
+
"node_modules/@types/unist": {
|
| 1447 |
+
"version": "3.0.3",
|
| 1448 |
+
"resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz",
|
| 1449 |
+
"integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==",
|
| 1450 |
+
"license": "MIT"
|
| 1451 |
+
},
|
| 1452 |
+
"node_modules/@ungap/structured-clone": {
|
| 1453 |
+
"version": "1.3.0",
|
| 1454 |
+
"resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.3.0.tgz",
|
| 1455 |
+
"integrity": "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==",
|
| 1456 |
+
"license": "ISC"
|
| 1457 |
+
},
|
| 1458 |
"node_modules/@vitejs/plugin-react": {
|
| 1459 |
"version": "4.6.0",
|
| 1460 |
"resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-4.6.0.tgz",
|
|
|
|
| 1577 |
"postcss": "^8.1.0"
|
| 1578 |
}
|
| 1579 |
},
|
| 1580 |
+
"node_modules/bail": {
|
| 1581 |
+
"version": "2.0.2",
|
| 1582 |
+
"resolved": "https://registry.npmjs.org/bail/-/bail-2.0.2.tgz",
|
| 1583 |
+
"integrity": "sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==",
|
| 1584 |
+
"license": "MIT",
|
| 1585 |
+
"funding": {
|
| 1586 |
+
"type": "github",
|
| 1587 |
+
"url": "https://github.com/sponsors/wooorm"
|
| 1588 |
+
}
|
| 1589 |
+
},
|
| 1590 |
"node_modules/balanced-match": {
|
| 1591 |
"version": "1.0.2",
|
| 1592 |
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
|
|
|
|
| 1669 |
],
|
| 1670 |
"license": "CC-BY-4.0"
|
| 1671 |
},
|
| 1672 |
+
"node_modules/ccount": {
|
| 1673 |
+
"version": "2.0.1",
|
| 1674 |
+
"resolved": "https://registry.npmjs.org/ccount/-/ccount-2.0.1.tgz",
|
| 1675 |
+
"integrity": "sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==",
|
| 1676 |
+
"license": "MIT",
|
| 1677 |
+
"funding": {
|
| 1678 |
+
"type": "github",
|
| 1679 |
+
"url": "https://github.com/sponsors/wooorm"
|
| 1680 |
+
}
|
| 1681 |
+
},
|
| 1682 |
"node_modules/chalk": {
|
| 1683 |
"version": "4.1.2",
|
| 1684 |
"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
|
|
|
|
| 1696 |
"url": "https://github.com/chalk/chalk?sponsor=1"
|
| 1697 |
}
|
| 1698 |
},
|
| 1699 |
+
"node_modules/character-entities": {
|
| 1700 |
+
"version": "2.0.2",
|
| 1701 |
+
"resolved": "https://registry.npmjs.org/character-entities/-/character-entities-2.0.2.tgz",
|
| 1702 |
+
"integrity": "sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==",
|
| 1703 |
+
"license": "MIT",
|
| 1704 |
+
"funding": {
|
| 1705 |
+
"type": "github",
|
| 1706 |
+
"url": "https://github.com/sponsors/wooorm"
|
| 1707 |
+
}
|
| 1708 |
+
},
|
| 1709 |
+
"node_modules/character-entities-html4": {
|
| 1710 |
+
"version": "2.1.0",
|
| 1711 |
+
"resolved": "https://registry.npmjs.org/character-entities-html4/-/character-entities-html4-2.1.0.tgz",
|
| 1712 |
+
"integrity": "sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==",
|
| 1713 |
+
"license": "MIT",
|
| 1714 |
+
"funding": {
|
| 1715 |
+
"type": "github",
|
| 1716 |
+
"url": "https://github.com/sponsors/wooorm"
|
| 1717 |
+
}
|
| 1718 |
+
},
|
| 1719 |
+
"node_modules/character-entities-legacy": {
|
| 1720 |
+
"version": "3.0.0",
|
| 1721 |
+
"resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-3.0.0.tgz",
|
| 1722 |
+
"integrity": "sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==",
|
| 1723 |
+
"license": "MIT",
|
| 1724 |
+
"funding": {
|
| 1725 |
+
"type": "github",
|
| 1726 |
+
"url": "https://github.com/sponsors/wooorm"
|
| 1727 |
+
}
|
| 1728 |
+
},
|
| 1729 |
+
"node_modules/character-reference-invalid": {
|
| 1730 |
+
"version": "2.0.1",
|
| 1731 |
+
"resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-2.0.1.tgz",
|
| 1732 |
+
"integrity": "sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw==",
|
| 1733 |
+
"license": "MIT",
|
| 1734 |
+
"funding": {
|
| 1735 |
+
"type": "github",
|
| 1736 |
+
"url": "https://github.com/sponsors/wooorm"
|
| 1737 |
+
}
|
| 1738 |
+
},
|
| 1739 |
"node_modules/color-convert": {
|
| 1740 |
"version": "2.0.1",
|
| 1741 |
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
|
|
|
|
| 1756 |
"dev": true,
|
| 1757 |
"license": "MIT"
|
| 1758 |
},
|
| 1759 |
+
"node_modules/comma-separated-tokens": {
|
| 1760 |
+
"version": "2.0.3",
|
| 1761 |
+
"resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-2.0.3.tgz",
|
| 1762 |
+
"integrity": "sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==",
|
| 1763 |
+
"license": "MIT",
|
| 1764 |
+
"funding": {
|
| 1765 |
+
"type": "github",
|
| 1766 |
+
"url": "https://github.com/sponsors/wooorm"
|
| 1767 |
+
}
|
| 1768 |
+
},
|
| 1769 |
"node_modules/concat-map": {
|
| 1770 |
"version": "0.0.1",
|
| 1771 |
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
|
|
|
|
| 1799 |
"version": "3.1.3",
|
| 1800 |
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz",
|
| 1801 |
"integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==",
|
|
|
|
| 1802 |
"license": "MIT"
|
| 1803 |
},
|
| 1804 |
"node_modules/date-fns": {
|
|
|
|
| 1815 |
"version": "4.4.1",
|
| 1816 |
"resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz",
|
| 1817 |
"integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==",
|
|
|
|
| 1818 |
"license": "MIT",
|
| 1819 |
"dependencies": {
|
| 1820 |
"ms": "^2.1.3"
|
|
|
|
| 1828 |
}
|
| 1829 |
}
|
| 1830 |
},
|
| 1831 |
+
"node_modules/decode-named-character-reference": {
|
| 1832 |
+
"version": "1.2.0",
|
| 1833 |
+
"resolved": "https://registry.npmjs.org/decode-named-character-reference/-/decode-named-character-reference-1.2.0.tgz",
|
| 1834 |
+
"integrity": "sha512-c6fcElNV6ShtZXmsgNgFFV5tVX2PaV4g+MOAkb8eXHvn6sryJBrZa9r0zV6+dtTyoCKxtDy5tyQ5ZwQuidtd+Q==",
|
| 1835 |
+
"license": "MIT",
|
| 1836 |
+
"dependencies": {
|
| 1837 |
+
"character-entities": "^2.0.0"
|
| 1838 |
+
},
|
| 1839 |
+
"funding": {
|
| 1840 |
+
"type": "github",
|
| 1841 |
+
"url": "https://github.com/sponsors/wooorm"
|
| 1842 |
+
}
|
| 1843 |
+
},
|
| 1844 |
"node_modules/deep-is": {
|
| 1845 |
"version": "0.1.4",
|
| 1846 |
"resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz",
|
|
|
|
| 1848 |
"dev": true,
|
| 1849 |
"license": "MIT"
|
| 1850 |
},
|
| 1851 |
+
"node_modules/dequal": {
|
| 1852 |
+
"version": "2.0.3",
|
| 1853 |
+
"resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz",
|
| 1854 |
+
"integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==",
|
| 1855 |
+
"license": "MIT",
|
| 1856 |
+
"engines": {
|
| 1857 |
+
"node": ">=6"
|
| 1858 |
+
}
|
| 1859 |
+
},
|
| 1860 |
+
"node_modules/devlop": {
|
| 1861 |
+
"version": "1.1.0",
|
| 1862 |
+
"resolved": "https://registry.npmjs.org/devlop/-/devlop-1.1.0.tgz",
|
| 1863 |
+
"integrity": "sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==",
|
| 1864 |
+
"license": "MIT",
|
| 1865 |
+
"dependencies": {
|
| 1866 |
+
"dequal": "^2.0.0"
|
| 1867 |
+
},
|
| 1868 |
+
"funding": {
|
| 1869 |
+
"type": "github",
|
| 1870 |
+
"url": "https://github.com/sponsors/wooorm"
|
| 1871 |
+
}
|
| 1872 |
+
},
|
| 1873 |
"node_modules/electron-to-chromium": {
|
| 1874 |
"version": "1.5.177",
|
| 1875 |
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.177.tgz",
|
|
|
|
| 2109 |
"node": ">=4.0"
|
| 2110 |
}
|
| 2111 |
},
|
| 2112 |
+
"node_modules/estree-util-is-identifier-name": {
|
| 2113 |
+
"version": "3.0.0",
|
| 2114 |
+
"resolved": "https://registry.npmjs.org/estree-util-is-identifier-name/-/estree-util-is-identifier-name-3.0.0.tgz",
|
| 2115 |
+
"integrity": "sha512-hFtqIDZTIUZ9BXLb8y4pYGyk6+wekIivNVTcmvk8NoOh+VeRn5y6cEHzbURrWbfp1fIqdVipilzj+lfaadNZmg==",
|
| 2116 |
+
"license": "MIT",
|
| 2117 |
+
"funding": {
|
| 2118 |
+
"type": "opencollective",
|
| 2119 |
+
"url": "https://opencollective.com/unified"
|
| 2120 |
+
}
|
| 2121 |
+
},
|
| 2122 |
"node_modules/esutils": {
|
| 2123 |
"version": "2.0.3",
|
| 2124 |
"resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
|
|
|
|
| 2129 |
"node": ">=0.10.0"
|
| 2130 |
}
|
| 2131 |
},
|
| 2132 |
+
"node_modules/extend": {
|
| 2133 |
+
"version": "3.0.2",
|
| 2134 |
+
"resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
|
| 2135 |
+
"integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==",
|
| 2136 |
+
"license": "MIT"
|
| 2137 |
+
},
|
| 2138 |
"node_modules/fast-deep-equal": {
|
| 2139 |
"version": "3.1.3",
|
| 2140 |
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
|
|
|
|
| 2297 |
"node": ">=8"
|
| 2298 |
}
|
| 2299 |
},
|
| 2300 |
+
"node_modules/hast-util-to-jsx-runtime": {
|
| 2301 |
+
"version": "2.3.6",
|
| 2302 |
+
"resolved": "https://registry.npmjs.org/hast-util-to-jsx-runtime/-/hast-util-to-jsx-runtime-2.3.6.tgz",
|
| 2303 |
+
"integrity": "sha512-zl6s8LwNyo1P9uw+XJGvZtdFF1GdAkOg8ujOw+4Pyb76874fLps4ueHXDhXWdk6YHQ6OgUtinliG7RsYvCbbBg==",
|
| 2304 |
+
"license": "MIT",
|
| 2305 |
+
"dependencies": {
|
| 2306 |
+
"@types/estree": "^1.0.0",
|
| 2307 |
+
"@types/hast": "^3.0.0",
|
| 2308 |
+
"@types/unist": "^3.0.0",
|
| 2309 |
+
"comma-separated-tokens": "^2.0.0",
|
| 2310 |
+
"devlop": "^1.0.0",
|
| 2311 |
+
"estree-util-is-identifier-name": "^3.0.0",
|
| 2312 |
+
"hast-util-whitespace": "^3.0.0",
|
| 2313 |
+
"mdast-util-mdx-expression": "^2.0.0",
|
| 2314 |
+
"mdast-util-mdx-jsx": "^3.0.0",
|
| 2315 |
+
"mdast-util-mdxjs-esm": "^2.0.0",
|
| 2316 |
+
"property-information": "^7.0.0",
|
| 2317 |
+
"space-separated-tokens": "^2.0.0",
|
| 2318 |
+
"style-to-js": "^1.0.0",
|
| 2319 |
+
"unist-util-position": "^5.0.0",
|
| 2320 |
+
"vfile-message": "^4.0.0"
|
| 2321 |
+
},
|
| 2322 |
+
"funding": {
|
| 2323 |
+
"type": "opencollective",
|
| 2324 |
+
"url": "https://opencollective.com/unified"
|
| 2325 |
+
}
|
| 2326 |
+
},
|
| 2327 |
+
"node_modules/hast-util-whitespace": {
|
| 2328 |
+
"version": "3.0.0",
|
| 2329 |
+
"resolved": "https://registry.npmjs.org/hast-util-whitespace/-/hast-util-whitespace-3.0.0.tgz",
|
| 2330 |
+
"integrity": "sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==",
|
| 2331 |
+
"license": "MIT",
|
| 2332 |
+
"dependencies": {
|
| 2333 |
+
"@types/hast": "^3.0.0"
|
| 2334 |
+
},
|
| 2335 |
+
"funding": {
|
| 2336 |
+
"type": "opencollective",
|
| 2337 |
+
"url": "https://opencollective.com/unified"
|
| 2338 |
+
}
|
| 2339 |
+
},
|
| 2340 |
+
"node_modules/html-url-attributes": {
|
| 2341 |
+
"version": "3.0.1",
|
| 2342 |
+
"resolved": "https://registry.npmjs.org/html-url-attributes/-/html-url-attributes-3.0.1.tgz",
|
| 2343 |
+
"integrity": "sha512-ol6UPyBWqsrO6EJySPz2O7ZSr856WDrEzM5zMqp+FJJLGMW35cLYmmZnl0vztAZxRUoNZJFTCohfjuIJ8I4QBQ==",
|
| 2344 |
+
"license": "MIT",
|
| 2345 |
+
"funding": {
|
| 2346 |
+
"type": "opencollective",
|
| 2347 |
+
"url": "https://opencollective.com/unified"
|
| 2348 |
+
}
|
| 2349 |
+
},
|
| 2350 |
"node_modules/ignore": {
|
| 2351 |
"version": "5.3.2",
|
| 2352 |
"resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz",
|
|
|
|
| 2384 |
"node": ">=0.8.19"
|
| 2385 |
}
|
| 2386 |
},
|
| 2387 |
+
"node_modules/inline-style-parser": {
|
| 2388 |
+
"version": "0.2.4",
|
| 2389 |
+
"resolved": "https://registry.npmjs.org/inline-style-parser/-/inline-style-parser-0.2.4.tgz",
|
| 2390 |
+
"integrity": "sha512-0aO8FkhNZlj/ZIbNi7Lxxr12obT7cL1moPfE4tg1LkX7LlLfC6DeX4l2ZEud1ukP9jNQyNnfzQVqwbwmAATY4Q==",
|
| 2391 |
+
"license": "MIT"
|
| 2392 |
+
},
|
| 2393 |
+
"node_modules/is-alphabetical": {
|
| 2394 |
+
"version": "2.0.1",
|
| 2395 |
+
"resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-2.0.1.tgz",
|
| 2396 |
+
"integrity": "sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ==",
|
| 2397 |
+
"license": "MIT",
|
| 2398 |
+
"funding": {
|
| 2399 |
+
"type": "github",
|
| 2400 |
+
"url": "https://github.com/sponsors/wooorm"
|
| 2401 |
+
}
|
| 2402 |
+
},
|
| 2403 |
+
"node_modules/is-alphanumerical": {
|
| 2404 |
+
"version": "2.0.1",
|
| 2405 |
+
"resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-2.0.1.tgz",
|
| 2406 |
+
"integrity": "sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw==",
|
| 2407 |
+
"license": "MIT",
|
| 2408 |
+
"dependencies": {
|
| 2409 |
+
"is-alphabetical": "^2.0.0",
|
| 2410 |
+
"is-decimal": "^2.0.0"
|
| 2411 |
+
},
|
| 2412 |
+
"funding": {
|
| 2413 |
+
"type": "github",
|
| 2414 |
+
"url": "https://github.com/sponsors/wooorm"
|
| 2415 |
+
}
|
| 2416 |
+
},
|
| 2417 |
+
"node_modules/is-decimal": {
|
| 2418 |
+
"version": "2.0.1",
|
| 2419 |
+
"resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-2.0.1.tgz",
|
| 2420 |
+
"integrity": "sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A==",
|
| 2421 |
+
"license": "MIT",
|
| 2422 |
+
"funding": {
|
| 2423 |
+
"type": "github",
|
| 2424 |
+
"url": "https://github.com/sponsors/wooorm"
|
| 2425 |
+
}
|
| 2426 |
+
},
|
| 2427 |
"node_modules/is-extglob": {
|
| 2428 |
"version": "2.1.1",
|
| 2429 |
"resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
|
|
|
|
| 2447 |
"node": ">=0.10.0"
|
| 2448 |
}
|
| 2449 |
},
|
| 2450 |
+
"node_modules/is-hexadecimal": {
|
| 2451 |
+
"version": "2.0.1",
|
| 2452 |
+
"resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-2.0.1.tgz",
|
| 2453 |
+
"integrity": "sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg==",
|
| 2454 |
+
"license": "MIT",
|
| 2455 |
+
"funding": {
|
| 2456 |
+
"type": "github",
|
| 2457 |
+
"url": "https://github.com/sponsors/wooorm"
|
| 2458 |
+
}
|
| 2459 |
+
},
|
| 2460 |
+
"node_modules/is-plain-obj": {
|
| 2461 |
+
"version": "4.1.0",
|
| 2462 |
+
"resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz",
|
| 2463 |
+
"integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==",
|
| 2464 |
+
"license": "MIT",
|
| 2465 |
+
"engines": {
|
| 2466 |
+
"node": ">=12"
|
| 2467 |
+
},
|
| 2468 |
+
"funding": {
|
| 2469 |
+
"url": "https://github.com/sponsors/sindresorhus"
|
| 2470 |
+
}
|
| 2471 |
+
},
|
| 2472 |
"node_modules/isexe": {
|
| 2473 |
"version": "2.0.0",
|
| 2474 |
"resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
|
|
|
|
| 2590 |
"dev": true,
|
| 2591 |
"license": "MIT"
|
| 2592 |
},
|
| 2593 |
+
"node_modules/longest-streak": {
|
| 2594 |
+
"version": "3.1.0",
|
| 2595 |
+
"resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-3.1.0.tgz",
|
| 2596 |
+
"integrity": "sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==",
|
| 2597 |
+
"license": "MIT",
|
| 2598 |
+
"funding": {
|
| 2599 |
+
"type": "github",
|
| 2600 |
+
"url": "https://github.com/sponsors/wooorm"
|
| 2601 |
+
}
|
| 2602 |
+
},
|
| 2603 |
"node_modules/lru-cache": {
|
| 2604 |
"version": "5.1.1",
|
| 2605 |
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
|
|
|
|
| 2619 |
"react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0"
|
| 2620 |
}
|
| 2621 |
},
|
| 2622 |
+
"node_modules/markdown-table": {
|
| 2623 |
+
"version": "3.0.4",
|
| 2624 |
+
"resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-3.0.4.tgz",
|
| 2625 |
+
"integrity": "sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw==",
|
| 2626 |
+
"license": "MIT",
|
| 2627 |
+
"funding": {
|
| 2628 |
+
"type": "github",
|
| 2629 |
+
"url": "https://github.com/sponsors/wooorm"
|
|
|
|
|
|
|
|
|
|
| 2630 |
}
|
| 2631 |
},
|
| 2632 |
+
"node_modules/mdast-util-find-and-replace": {
|
| 2633 |
+
"version": "3.0.2",
|
| 2634 |
+
"resolved": "https://registry.npmjs.org/mdast-util-find-and-replace/-/mdast-util-find-and-replace-3.0.2.tgz",
|
| 2635 |
+
"integrity": "sha512-Tmd1Vg/m3Xz43afeNxDIhWRtFZgM2VLyaf4vSTYwudTyeuTneoL3qtWMA5jeLyz/O1vDJmmV4QuScFCA2tBPwg==",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2636 |
"license": "MIT",
|
| 2637 |
+
"dependencies": {
|
| 2638 |
+
"@types/mdast": "^4.0.0",
|
| 2639 |
+
"escape-string-regexp": "^5.0.0",
|
| 2640 |
+
"unist-util-is": "^6.0.0",
|
| 2641 |
+
"unist-util-visit-parents": "^6.0.0"
|
| 2642 |
},
|
| 2643 |
+
"funding": {
|
| 2644 |
+
"type": "opencollective",
|
| 2645 |
+
"url": "https://opencollective.com/unified"
|
| 2646 |
}
|
| 2647 |
},
|
| 2648 |
+
"node_modules/mdast-util-find-and-replace/node_modules/escape-string-regexp": {
|
| 2649 |
+
"version": "5.0.0",
|
| 2650 |
+
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz",
|
| 2651 |
+
"integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2652 |
"license": "MIT",
|
| 2653 |
"engines": {
|
| 2654 |
+
"node": ">=12"
|
| 2655 |
+
},
|
| 2656 |
+
"funding": {
|
| 2657 |
+
"url": "https://github.com/sponsors/sindresorhus"
|
| 2658 |
}
|
| 2659 |
},
|
| 2660 |
+
"node_modules/mdast-util-from-markdown": {
|
| 2661 |
+
"version": "2.0.2",
|
| 2662 |
+
"resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-2.0.2.tgz",
|
| 2663 |
+
"integrity": "sha512-uZhTV/8NBuw0WHkPTrCqDOl0zVe1BIng5ZtHoDk49ME1qqcjYmmLmOf0gELgcRMxN4w2iuIeVso5/6QymSrgmA==",
|
|
|
|
| 2664 |
"license": "MIT",
|
| 2665 |
"dependencies": {
|
| 2666 |
+
"@types/mdast": "^4.0.0",
|
| 2667 |
+
"@types/unist": "^3.0.0",
|
| 2668 |
+
"decode-named-character-reference": "^1.0.0",
|
| 2669 |
+
"devlop": "^1.0.0",
|
| 2670 |
+
"mdast-util-to-string": "^4.0.0",
|
| 2671 |
+
"micromark": "^4.0.0",
|
| 2672 |
+
"micromark-util-decode-numeric-character-reference": "^2.0.0",
|
| 2673 |
+
"micromark-util-decode-string": "^2.0.0",
|
| 2674 |
+
"micromark-util-normalize-identifier": "^2.0.0",
|
| 2675 |
+
"micromark-util-symbol": "^2.0.0",
|
| 2676 |
+
"micromark-util-types": "^2.0.0",
|
| 2677 |
+
"unist-util-stringify-position": "^4.0.0"
|
| 2678 |
},
|
| 2679 |
+
"funding": {
|
| 2680 |
+
"type": "opencollective",
|
| 2681 |
+
"url": "https://opencollective.com/unified"
|
| 2682 |
}
|
| 2683 |
},
|
| 2684 |
+
"node_modules/mdast-util-gfm": {
|
| 2685 |
"version": "3.1.0",
|
| 2686 |
+
"resolved": "https://registry.npmjs.org/mdast-util-gfm/-/mdast-util-gfm-3.1.0.tgz",
|
| 2687 |
+
"integrity": "sha512-0ulfdQOM3ysHhCJ1p06l0b0VKlhU0wuQs3thxZQagjcjPrlFRqY215uZGHHJan9GEAXd9MbfPjFJz+qMkVR6zQ==",
|
|
|
|
| 2688 |
"license": "MIT",
|
| 2689 |
"dependencies": {
|
| 2690 |
+
"mdast-util-from-markdown": "^2.0.0",
|
| 2691 |
+
"mdast-util-gfm-autolink-literal": "^2.0.0",
|
| 2692 |
+
"mdast-util-gfm-footnote": "^2.0.0",
|
| 2693 |
+
"mdast-util-gfm-strikethrough": "^2.0.0",
|
| 2694 |
+
"mdast-util-gfm-table": "^2.0.0",
|
| 2695 |
+
"mdast-util-gfm-task-list-item": "^2.0.0",
|
| 2696 |
+
"mdast-util-to-markdown": "^2.0.0"
|
| 2697 |
},
|
| 2698 |
"funding": {
|
| 2699 |
+
"type": "opencollective",
|
| 2700 |
+
"url": "https://opencollective.com/unified"
|
| 2701 |
}
|
| 2702 |
},
|
| 2703 |
+
"node_modules/mdast-util-gfm-autolink-literal": {
|
| 2704 |
+
"version": "2.0.1",
|
| 2705 |
+
"resolved": "https://registry.npmjs.org/mdast-util-gfm-autolink-literal/-/mdast-util-gfm-autolink-literal-2.0.1.tgz",
|
| 2706 |
+
"integrity": "sha512-5HVP2MKaP6L+G6YaxPNjuL0BPrq9orG3TsrZ9YXbA3vDw/ACI4MEsnoDpn6ZNm7GnZgtAcONJyPhOP8tNJQavQ==",
|
| 2707 |
+
"license": "MIT",
|
| 2708 |
+
"dependencies": {
|
| 2709 |
+
"@types/mdast": "^4.0.0",
|
| 2710 |
+
"ccount": "^2.0.0",
|
| 2711 |
+
"devlop": "^1.0.0",
|
| 2712 |
+
"mdast-util-find-and-replace": "^3.0.0",
|
| 2713 |
+
"micromark-util-character": "^2.0.0"
|
| 2714 |
+
},
|
| 2715 |
+
"funding": {
|
| 2716 |
+
"type": "opencollective",
|
| 2717 |
+
"url": "https://opencollective.com/unified"
|
| 2718 |
+
}
|
| 2719 |
+
},
|
| 2720 |
+
"node_modules/mdast-util-gfm-footnote": {
|
| 2721 |
+
"version": "2.1.0",
|
| 2722 |
+
"resolved": "https://registry.npmjs.org/mdast-util-gfm-footnote/-/mdast-util-gfm-footnote-2.1.0.tgz",
|
| 2723 |
+
"integrity": "sha512-sqpDWlsHn7Ac9GNZQMeUzPQSMzR6Wv0WKRNvQRg0KqHh02fpTz69Qc1QSseNX29bhz1ROIyNyxExfawVKTm1GQ==",
|
| 2724 |
+
"license": "MIT",
|
| 2725 |
+
"dependencies": {
|
| 2726 |
+
"@types/mdast": "^4.0.0",
|
| 2727 |
+
"devlop": "^1.1.0",
|
| 2728 |
+
"mdast-util-from-markdown": "^2.0.0",
|
| 2729 |
+
"mdast-util-to-markdown": "^2.0.0",
|
| 2730 |
+
"micromark-util-normalize-identifier": "^2.0.0"
|
| 2731 |
+
},
|
| 2732 |
+
"funding": {
|
| 2733 |
+
"type": "opencollective",
|
| 2734 |
+
"url": "https://opencollective.com/unified"
|
| 2735 |
+
}
|
| 2736 |
+
},
|
| 2737 |
+
"node_modules/mdast-util-gfm-strikethrough": {
|
| 2738 |
+
"version": "2.0.0",
|
| 2739 |
+
"resolved": "https://registry.npmjs.org/mdast-util-gfm-strikethrough/-/mdast-util-gfm-strikethrough-2.0.0.tgz",
|
| 2740 |
+
"integrity": "sha512-mKKb915TF+OC5ptj5bJ7WFRPdYtuHv0yTRxK2tJvi+BDqbkiG7h7u/9SI89nRAYcmap2xHQL9D+QG/6wSrTtXg==",
|
| 2741 |
+
"license": "MIT",
|
| 2742 |
+
"dependencies": {
|
| 2743 |
+
"@types/mdast": "^4.0.0",
|
| 2744 |
+
"mdast-util-from-markdown": "^2.0.0",
|
| 2745 |
+
"mdast-util-to-markdown": "^2.0.0"
|
| 2746 |
+
},
|
| 2747 |
+
"funding": {
|
| 2748 |
+
"type": "opencollective",
|
| 2749 |
+
"url": "https://opencollective.com/unified"
|
| 2750 |
+
}
|
| 2751 |
+
},
|
| 2752 |
+
"node_modules/mdast-util-gfm-table": {
|
| 2753 |
+
"version": "2.0.0",
|
| 2754 |
+
"resolved": "https://registry.npmjs.org/mdast-util-gfm-table/-/mdast-util-gfm-table-2.0.0.tgz",
|
| 2755 |
+
"integrity": "sha512-78UEvebzz/rJIxLvE7ZtDd/vIQ0RHv+3Mh5DR96p7cS7HsBhYIICDBCu8csTNWNO6tBWfqXPWekRuj2FNOGOZg==",
|
| 2756 |
+
"license": "MIT",
|
| 2757 |
+
"dependencies": {
|
| 2758 |
+
"@types/mdast": "^4.0.0",
|
| 2759 |
+
"devlop": "^1.0.0",
|
| 2760 |
+
"markdown-table": "^3.0.0",
|
| 2761 |
+
"mdast-util-from-markdown": "^2.0.0",
|
| 2762 |
+
"mdast-util-to-markdown": "^2.0.0"
|
| 2763 |
+
},
|
| 2764 |
+
"funding": {
|
| 2765 |
+
"type": "opencollective",
|
| 2766 |
+
"url": "https://opencollective.com/unified"
|
| 2767 |
+
}
|
| 2768 |
+
},
|
| 2769 |
+
"node_modules/mdast-util-gfm-task-list-item": {
|
| 2770 |
+
"version": "2.0.0",
|
| 2771 |
+
"resolved": "https://registry.npmjs.org/mdast-util-gfm-task-list-item/-/mdast-util-gfm-task-list-item-2.0.0.tgz",
|
| 2772 |
+
"integrity": "sha512-IrtvNvjxC1o06taBAVJznEnkiHxLFTzgonUdy8hzFVeDun0uTjxxrRGVaNFqkU1wJR3RBPEfsxmU6jDWPofrTQ==",
|
| 2773 |
+
"license": "MIT",
|
| 2774 |
+
"dependencies": {
|
| 2775 |
+
"@types/mdast": "^4.0.0",
|
| 2776 |
+
"devlop": "^1.0.0",
|
| 2777 |
+
"mdast-util-from-markdown": "^2.0.0",
|
| 2778 |
+
"mdast-util-to-markdown": "^2.0.0"
|
| 2779 |
+
},
|
| 2780 |
+
"funding": {
|
| 2781 |
+
"type": "opencollective",
|
| 2782 |
+
"url": "https://opencollective.com/unified"
|
| 2783 |
+
}
|
| 2784 |
+
},
|
| 2785 |
+
"node_modules/mdast-util-mdx-expression": {
|
| 2786 |
+
"version": "2.0.1",
|
| 2787 |
+
"resolved": "https://registry.npmjs.org/mdast-util-mdx-expression/-/mdast-util-mdx-expression-2.0.1.tgz",
|
| 2788 |
+
"integrity": "sha512-J6f+9hUp+ldTZqKRSg7Vw5V6MqjATc+3E4gf3CFNcuZNWD8XdyI6zQ8GqH7f8169MM6P7hMBRDVGnn7oHB9kXQ==",
|
| 2789 |
+
"license": "MIT",
|
| 2790 |
+
"dependencies": {
|
| 2791 |
+
"@types/estree-jsx": "^1.0.0",
|
| 2792 |
+
"@types/hast": "^3.0.0",
|
| 2793 |
+
"@types/mdast": "^4.0.0",
|
| 2794 |
+
"devlop": "^1.0.0",
|
| 2795 |
+
"mdast-util-from-markdown": "^2.0.0",
|
| 2796 |
+
"mdast-util-to-markdown": "^2.0.0"
|
| 2797 |
+
},
|
| 2798 |
+
"funding": {
|
| 2799 |
+
"type": "opencollective",
|
| 2800 |
+
"url": "https://opencollective.com/unified"
|
| 2801 |
+
}
|
| 2802 |
+
},
|
| 2803 |
+
"node_modules/mdast-util-mdx-jsx": {
|
| 2804 |
+
"version": "3.2.0",
|
| 2805 |
+
"resolved": "https://registry.npmjs.org/mdast-util-mdx-jsx/-/mdast-util-mdx-jsx-3.2.0.tgz",
|
| 2806 |
+
"integrity": "sha512-lj/z8v0r6ZtsN/cGNNtemmmfoLAFZnjMbNyLzBafjzikOM+glrjNHPlf6lQDOTccj9n5b0PPihEBbhneMyGs1Q==",
|
| 2807 |
+
"license": "MIT",
|
| 2808 |
+
"dependencies": {
|
| 2809 |
+
"@types/estree-jsx": "^1.0.0",
|
| 2810 |
+
"@types/hast": "^3.0.0",
|
| 2811 |
+
"@types/mdast": "^4.0.0",
|
| 2812 |
+
"@types/unist": "^3.0.0",
|
| 2813 |
+
"ccount": "^2.0.0",
|
| 2814 |
+
"devlop": "^1.1.0",
|
| 2815 |
+
"mdast-util-from-markdown": "^2.0.0",
|
| 2816 |
+
"mdast-util-to-markdown": "^2.0.0",
|
| 2817 |
+
"parse-entities": "^4.0.0",
|
| 2818 |
+
"stringify-entities": "^4.0.0",
|
| 2819 |
+
"unist-util-stringify-position": "^4.0.0",
|
| 2820 |
+
"vfile-message": "^4.0.0"
|
| 2821 |
+
},
|
| 2822 |
+
"funding": {
|
| 2823 |
+
"type": "opencollective",
|
| 2824 |
+
"url": "https://opencollective.com/unified"
|
| 2825 |
+
}
|
| 2826 |
+
},
|
| 2827 |
+
"node_modules/mdast-util-mdxjs-esm": {
|
| 2828 |
+
"version": "2.0.1",
|
| 2829 |
+
"resolved": "https://registry.npmjs.org/mdast-util-mdxjs-esm/-/mdast-util-mdxjs-esm-2.0.1.tgz",
|
| 2830 |
+
"integrity": "sha512-EcmOpxsZ96CvlP03NghtH1EsLtr0n9Tm4lPUJUBccV9RwUOneqSycg19n5HGzCf+10LozMRSObtVr3ee1WoHtg==",
|
| 2831 |
+
"license": "MIT",
|
| 2832 |
+
"dependencies": {
|
| 2833 |
+
"@types/estree-jsx": "^1.0.0",
|
| 2834 |
+
"@types/hast": "^3.0.0",
|
| 2835 |
+
"@types/mdast": "^4.0.0",
|
| 2836 |
+
"devlop": "^1.0.0",
|
| 2837 |
+
"mdast-util-from-markdown": "^2.0.0",
|
| 2838 |
+
"mdast-util-to-markdown": "^2.0.0"
|
| 2839 |
+
},
|
| 2840 |
+
"funding": {
|
| 2841 |
+
"type": "opencollective",
|
| 2842 |
+
"url": "https://opencollective.com/unified"
|
| 2843 |
+
}
|
| 2844 |
+
},
|
| 2845 |
+
"node_modules/mdast-util-phrasing": {
|
| 2846 |
+
"version": "4.1.0",
|
| 2847 |
+
"resolved": "https://registry.npmjs.org/mdast-util-phrasing/-/mdast-util-phrasing-4.1.0.tgz",
|
| 2848 |
+
"integrity": "sha512-TqICwyvJJpBwvGAMZjj4J2n0X8QWp21b9l0o7eXyVJ25YNWYbJDVIyD1bZXE6WtV6RmKJVYmQAKWa0zWOABz2w==",
|
| 2849 |
+
"license": "MIT",
|
| 2850 |
+
"dependencies": {
|
| 2851 |
+
"@types/mdast": "^4.0.0",
|
| 2852 |
+
"unist-util-is": "^6.0.0"
|
| 2853 |
+
},
|
| 2854 |
+
"funding": {
|
| 2855 |
+
"type": "opencollective",
|
| 2856 |
+
"url": "https://opencollective.com/unified"
|
| 2857 |
+
}
|
| 2858 |
+
},
|
| 2859 |
+
"node_modules/mdast-util-to-hast": {
|
| 2860 |
+
"version": "13.2.0",
|
| 2861 |
+
"resolved": "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-13.2.0.tgz",
|
| 2862 |
+
"integrity": "sha512-QGYKEuUsYT9ykKBCMOEDLsU5JRObWQusAolFMeko/tYPufNkRffBAQjIE+99jbA87xv6FgmjLtwjh9wBWajwAA==",
|
| 2863 |
+
"license": "MIT",
|
| 2864 |
+
"dependencies": {
|
| 2865 |
+
"@types/hast": "^3.0.0",
|
| 2866 |
+
"@types/mdast": "^4.0.0",
|
| 2867 |
+
"@ungap/structured-clone": "^1.0.0",
|
| 2868 |
+
"devlop": "^1.0.0",
|
| 2869 |
+
"micromark-util-sanitize-uri": "^2.0.0",
|
| 2870 |
+
"trim-lines": "^3.0.0",
|
| 2871 |
+
"unist-util-position": "^5.0.0",
|
| 2872 |
+
"unist-util-visit": "^5.0.0",
|
| 2873 |
+
"vfile": "^6.0.0"
|
| 2874 |
+
},
|
| 2875 |
+
"funding": {
|
| 2876 |
+
"type": "opencollective",
|
| 2877 |
+
"url": "https://opencollective.com/unified"
|
| 2878 |
+
}
|
| 2879 |
+
},
|
| 2880 |
+
"node_modules/mdast-util-to-markdown": {
|
| 2881 |
+
"version": "2.1.2",
|
| 2882 |
+
"resolved": "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-2.1.2.tgz",
|
| 2883 |
+
"integrity": "sha512-xj68wMTvGXVOKonmog6LwyJKrYXZPvlwabaryTjLh9LuvovB/KAH+kvi8Gjj+7rJjsFi23nkUxRQv1KqSroMqA==",
|
| 2884 |
+
"license": "MIT",
|
| 2885 |
+
"dependencies": {
|
| 2886 |
+
"@types/mdast": "^4.0.0",
|
| 2887 |
+
"@types/unist": "^3.0.0",
|
| 2888 |
+
"longest-streak": "^3.0.0",
|
| 2889 |
+
"mdast-util-phrasing": "^4.0.0",
|
| 2890 |
+
"mdast-util-to-string": "^4.0.0",
|
| 2891 |
+
"micromark-util-classify-character": "^2.0.0",
|
| 2892 |
+
"micromark-util-decode-string": "^2.0.0",
|
| 2893 |
+
"unist-util-visit": "^5.0.0",
|
| 2894 |
+
"zwitch": "^2.0.0"
|
| 2895 |
+
},
|
| 2896 |
+
"funding": {
|
| 2897 |
+
"type": "opencollective",
|
| 2898 |
+
"url": "https://opencollective.com/unified"
|
| 2899 |
+
}
|
| 2900 |
+
},
|
| 2901 |
+
"node_modules/mdast-util-to-string": {
|
| 2902 |
+
"version": "4.0.0",
|
| 2903 |
+
"resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-4.0.0.tgz",
|
| 2904 |
+
"integrity": "sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==",
|
| 2905 |
+
"license": "MIT",
|
| 2906 |
+
"dependencies": {
|
| 2907 |
+
"@types/mdast": "^4.0.0"
|
| 2908 |
+
},
|
| 2909 |
+
"funding": {
|
| 2910 |
+
"type": "opencollective",
|
| 2911 |
+
"url": "https://opencollective.com/unified"
|
| 2912 |
+
}
|
| 2913 |
+
},
|
| 2914 |
+
"node_modules/micromark": {
|
| 2915 |
+
"version": "4.0.2",
|
| 2916 |
+
"resolved": "https://registry.npmjs.org/micromark/-/micromark-4.0.2.tgz",
|
| 2917 |
+
"integrity": "sha512-zpe98Q6kvavpCr1NPVSCMebCKfD7CA2NqZ+rykeNhONIJBpc1tFKt9hucLGwha3jNTNI8lHpctWJWoimVF4PfA==",
|
| 2918 |
+
"funding": [
|
| 2919 |
+
{
|
| 2920 |
+
"type": "GitHub Sponsors",
|
| 2921 |
+
"url": "https://github.com/sponsors/unifiedjs"
|
| 2922 |
+
},
|
| 2923 |
+
{
|
| 2924 |
+
"type": "OpenCollective",
|
| 2925 |
+
"url": "https://opencollective.com/unified"
|
| 2926 |
+
}
|
| 2927 |
+
],
|
| 2928 |
+
"license": "MIT",
|
| 2929 |
+
"dependencies": {
|
| 2930 |
+
"@types/debug": "^4.0.0",
|
| 2931 |
+
"debug": "^4.0.0",
|
| 2932 |
+
"decode-named-character-reference": "^1.0.0",
|
| 2933 |
+
"devlop": "^1.0.0",
|
| 2934 |
+
"micromark-core-commonmark": "^2.0.0",
|
| 2935 |
+
"micromark-factory-space": "^2.0.0",
|
| 2936 |
+
"micromark-util-character": "^2.0.0",
|
| 2937 |
+
"micromark-util-chunked": "^2.0.0",
|
| 2938 |
+
"micromark-util-combine-extensions": "^2.0.0",
|
| 2939 |
+
"micromark-util-decode-numeric-character-reference": "^2.0.0",
|
| 2940 |
+
"micromark-util-encode": "^2.0.0",
|
| 2941 |
+
"micromark-util-normalize-identifier": "^2.0.0",
|
| 2942 |
+
"micromark-util-resolve-all": "^2.0.0",
|
| 2943 |
+
"micromark-util-sanitize-uri": "^2.0.0",
|
| 2944 |
+
"micromark-util-subtokenize": "^2.0.0",
|
| 2945 |
+
"micromark-util-symbol": "^2.0.0",
|
| 2946 |
+
"micromark-util-types": "^2.0.0"
|
| 2947 |
+
}
|
| 2948 |
+
},
|
| 2949 |
+
"node_modules/micromark-core-commonmark": {
|
| 2950 |
+
"version": "2.0.3",
|
| 2951 |
+
"resolved": "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-2.0.3.tgz",
|
| 2952 |
+
"integrity": "sha512-RDBrHEMSxVFLg6xvnXmb1Ayr2WzLAWjeSATAoxwKYJV94TeNavgoIdA0a9ytzDSVzBy2YKFK+emCPOEibLeCrg==",
|
| 2953 |
+
"funding": [
|
| 2954 |
+
{
|
| 2955 |
+
"type": "GitHub Sponsors",
|
| 2956 |
+
"url": "https://github.com/sponsors/unifiedjs"
|
| 2957 |
+
},
|
| 2958 |
+
{
|
| 2959 |
+
"type": "OpenCollective",
|
| 2960 |
+
"url": "https://opencollective.com/unified"
|
| 2961 |
+
}
|
| 2962 |
+
],
|
| 2963 |
+
"license": "MIT",
|
| 2964 |
+
"dependencies": {
|
| 2965 |
+
"decode-named-character-reference": "^1.0.0",
|
| 2966 |
+
"devlop": "^1.0.0",
|
| 2967 |
+
"micromark-factory-destination": "^2.0.0",
|
| 2968 |
+
"micromark-factory-label": "^2.0.0",
|
| 2969 |
+
"micromark-factory-space": "^2.0.0",
|
| 2970 |
+
"micromark-factory-title": "^2.0.0",
|
| 2971 |
+
"micromark-factory-whitespace": "^2.0.0",
|
| 2972 |
+
"micromark-util-character": "^2.0.0",
|
| 2973 |
+
"micromark-util-chunked": "^2.0.0",
|
| 2974 |
+
"micromark-util-classify-character": "^2.0.0",
|
| 2975 |
+
"micromark-util-html-tag-name": "^2.0.0",
|
| 2976 |
+
"micromark-util-normalize-identifier": "^2.0.0",
|
| 2977 |
+
"micromark-util-resolve-all": "^2.0.0",
|
| 2978 |
+
"micromark-util-subtokenize": "^2.0.0",
|
| 2979 |
+
"micromark-util-symbol": "^2.0.0",
|
| 2980 |
+
"micromark-util-types": "^2.0.0"
|
| 2981 |
+
}
|
| 2982 |
+
},
|
| 2983 |
+
"node_modules/micromark-extension-gfm": {
|
| 2984 |
+
"version": "3.0.0",
|
| 2985 |
+
"resolved": "https://registry.npmjs.org/micromark-extension-gfm/-/micromark-extension-gfm-3.0.0.tgz",
|
| 2986 |
+
"integrity": "sha512-vsKArQsicm7t0z2GugkCKtZehqUm31oeGBV/KVSorWSy8ZlNAv7ytjFhvaryUiCUJYqs+NoE6AFhpQvBTM6Q4w==",
|
| 2987 |
+
"license": "MIT",
|
| 2988 |
+
"dependencies": {
|
| 2989 |
+
"micromark-extension-gfm-autolink-literal": "^2.0.0",
|
| 2990 |
+
"micromark-extension-gfm-footnote": "^2.0.0",
|
| 2991 |
+
"micromark-extension-gfm-strikethrough": "^2.0.0",
|
| 2992 |
+
"micromark-extension-gfm-table": "^2.0.0",
|
| 2993 |
+
"micromark-extension-gfm-tagfilter": "^2.0.0",
|
| 2994 |
+
"micromark-extension-gfm-task-list-item": "^2.0.0",
|
| 2995 |
+
"micromark-util-combine-extensions": "^2.0.0",
|
| 2996 |
+
"micromark-util-types": "^2.0.0"
|
| 2997 |
+
},
|
| 2998 |
+
"funding": {
|
| 2999 |
+
"type": "opencollective",
|
| 3000 |
+
"url": "https://opencollective.com/unified"
|
| 3001 |
+
}
|
| 3002 |
+
},
|
| 3003 |
+
"node_modules/micromark-extension-gfm-autolink-literal": {
|
| 3004 |
+
"version": "2.1.0",
|
| 3005 |
+
"resolved": "https://registry.npmjs.org/micromark-extension-gfm-autolink-literal/-/micromark-extension-gfm-autolink-literal-2.1.0.tgz",
|
| 3006 |
+
"integrity": "sha512-oOg7knzhicgQ3t4QCjCWgTmfNhvQbDDnJeVu9v81r7NltNCVmhPy1fJRX27pISafdjL+SVc4d3l48Gb6pbRypw==",
|
| 3007 |
+
"license": "MIT",
|
| 3008 |
+
"dependencies": {
|
| 3009 |
+
"micromark-util-character": "^2.0.0",
|
| 3010 |
+
"micromark-util-sanitize-uri": "^2.0.0",
|
| 3011 |
+
"micromark-util-symbol": "^2.0.0",
|
| 3012 |
+
"micromark-util-types": "^2.0.0"
|
| 3013 |
+
},
|
| 3014 |
+
"funding": {
|
| 3015 |
+
"type": "opencollective",
|
| 3016 |
+
"url": "https://opencollective.com/unified"
|
| 3017 |
+
}
|
| 3018 |
+
},
|
| 3019 |
+
"node_modules/micromark-extension-gfm-footnote": {
|
| 3020 |
+
"version": "2.1.0",
|
| 3021 |
+
"resolved": "https://registry.npmjs.org/micromark-extension-gfm-footnote/-/micromark-extension-gfm-footnote-2.1.0.tgz",
|
| 3022 |
+
"integrity": "sha512-/yPhxI1ntnDNsiHtzLKYnE3vf9JZ6cAisqVDauhp4CEHxlb4uoOTxOCJ+9s51bIB8U1N1FJ1RXOKTIlD5B/gqw==",
|
| 3023 |
+
"license": "MIT",
|
| 3024 |
+
"dependencies": {
|
| 3025 |
+
"devlop": "^1.0.0",
|
| 3026 |
+
"micromark-core-commonmark": "^2.0.0",
|
| 3027 |
+
"micromark-factory-space": "^2.0.0",
|
| 3028 |
+
"micromark-util-character": "^2.0.0",
|
| 3029 |
+
"micromark-util-normalize-identifier": "^2.0.0",
|
| 3030 |
+
"micromark-util-sanitize-uri": "^2.0.0",
|
| 3031 |
+
"micromark-util-symbol": "^2.0.0",
|
| 3032 |
+
"micromark-util-types": "^2.0.0"
|
| 3033 |
+
},
|
| 3034 |
+
"funding": {
|
| 3035 |
+
"type": "opencollective",
|
| 3036 |
+
"url": "https://opencollective.com/unified"
|
| 3037 |
+
}
|
| 3038 |
+
},
|
| 3039 |
+
"node_modules/micromark-extension-gfm-strikethrough": {
|
| 3040 |
+
"version": "2.1.0",
|
| 3041 |
+
"resolved": "https://registry.npmjs.org/micromark-extension-gfm-strikethrough/-/micromark-extension-gfm-strikethrough-2.1.0.tgz",
|
| 3042 |
+
"integrity": "sha512-ADVjpOOkjz1hhkZLlBiYA9cR2Anf8F4HqZUO6e5eDcPQd0Txw5fxLzzxnEkSkfnD0wziSGiv7sYhk/ktvbf1uw==",
|
| 3043 |
+
"license": "MIT",
|
| 3044 |
+
"dependencies": {
|
| 3045 |
+
"devlop": "^1.0.0",
|
| 3046 |
+
"micromark-util-chunked": "^2.0.0",
|
| 3047 |
+
"micromark-util-classify-character": "^2.0.0",
|
| 3048 |
+
"micromark-util-resolve-all": "^2.0.0",
|
| 3049 |
+
"micromark-util-symbol": "^2.0.0",
|
| 3050 |
+
"micromark-util-types": "^2.0.0"
|
| 3051 |
+
},
|
| 3052 |
+
"funding": {
|
| 3053 |
+
"type": "opencollective",
|
| 3054 |
+
"url": "https://opencollective.com/unified"
|
| 3055 |
+
}
|
| 3056 |
+
},
|
| 3057 |
+
"node_modules/micromark-extension-gfm-table": {
|
| 3058 |
+
"version": "2.1.1",
|
| 3059 |
+
"resolved": "https://registry.npmjs.org/micromark-extension-gfm-table/-/micromark-extension-gfm-table-2.1.1.tgz",
|
| 3060 |
+
"integrity": "sha512-t2OU/dXXioARrC6yWfJ4hqB7rct14e8f7m0cbI5hUmDyyIlwv5vEtooptH8INkbLzOatzKuVbQmAYcbWoyz6Dg==",
|
| 3061 |
+
"license": "MIT",
|
| 3062 |
+
"dependencies": {
|
| 3063 |
+
"devlop": "^1.0.0",
|
| 3064 |
+
"micromark-factory-space": "^2.0.0",
|
| 3065 |
+
"micromark-util-character": "^2.0.0",
|
| 3066 |
+
"micromark-util-symbol": "^2.0.0",
|
| 3067 |
+
"micromark-util-types": "^2.0.0"
|
| 3068 |
+
},
|
| 3069 |
+
"funding": {
|
| 3070 |
+
"type": "opencollective",
|
| 3071 |
+
"url": "https://opencollective.com/unified"
|
| 3072 |
+
}
|
| 3073 |
+
},
|
| 3074 |
+
"node_modules/micromark-extension-gfm-tagfilter": {
|
| 3075 |
+
"version": "2.0.0",
|
| 3076 |
+
"resolved": "https://registry.npmjs.org/micromark-extension-gfm-tagfilter/-/micromark-extension-gfm-tagfilter-2.0.0.tgz",
|
| 3077 |
+
"integrity": "sha512-xHlTOmuCSotIA8TW1mDIM6X2O1SiX5P9IuDtqGonFhEK0qgRI4yeC6vMxEV2dgyr2TiD+2PQ10o+cOhdVAcwfg==",
|
| 3078 |
+
"license": "MIT",
|
| 3079 |
+
"dependencies": {
|
| 3080 |
+
"micromark-util-types": "^2.0.0"
|
| 3081 |
+
},
|
| 3082 |
+
"funding": {
|
| 3083 |
+
"type": "opencollective",
|
| 3084 |
+
"url": "https://opencollective.com/unified"
|
| 3085 |
+
}
|
| 3086 |
+
},
|
| 3087 |
+
"node_modules/micromark-extension-gfm-task-list-item": {
|
| 3088 |
+
"version": "2.1.0",
|
| 3089 |
+
"resolved": "https://registry.npmjs.org/micromark-extension-gfm-task-list-item/-/micromark-extension-gfm-task-list-item-2.1.0.tgz",
|
| 3090 |
+
"integrity": "sha512-qIBZhqxqI6fjLDYFTBIa4eivDMnP+OZqsNwmQ3xNLE4Cxwc+zfQEfbs6tzAo2Hjq+bh6q5F+Z8/cksrLFYWQQw==",
|
| 3091 |
+
"license": "MIT",
|
| 3092 |
+
"dependencies": {
|
| 3093 |
+
"devlop": "^1.0.0",
|
| 3094 |
+
"micromark-factory-space": "^2.0.0",
|
| 3095 |
+
"micromark-util-character": "^2.0.0",
|
| 3096 |
+
"micromark-util-symbol": "^2.0.0",
|
| 3097 |
+
"micromark-util-types": "^2.0.0"
|
| 3098 |
+
},
|
| 3099 |
+
"funding": {
|
| 3100 |
+
"type": "opencollective",
|
| 3101 |
+
"url": "https://opencollective.com/unified"
|
| 3102 |
+
}
|
| 3103 |
+
},
|
| 3104 |
+
"node_modules/micromark-factory-destination": {
|
| 3105 |
+
"version": "2.0.1",
|
| 3106 |
+
"resolved": "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-2.0.1.tgz",
|
| 3107 |
+
"integrity": "sha512-Xe6rDdJlkmbFRExpTOmRj9N3MaWmbAgdpSrBQvCFqhezUn4AHqJHbaEnfbVYYiexVSs//tqOdY/DxhjdCiJnIA==",
|
| 3108 |
+
"funding": [
|
| 3109 |
+
{
|
| 3110 |
+
"type": "GitHub Sponsors",
|
| 3111 |
+
"url": "https://github.com/sponsors/unifiedjs"
|
| 3112 |
+
},
|
| 3113 |
+
{
|
| 3114 |
+
"type": "OpenCollective",
|
| 3115 |
+
"url": "https://opencollective.com/unified"
|
| 3116 |
+
}
|
| 3117 |
+
],
|
| 3118 |
+
"license": "MIT",
|
| 3119 |
+
"dependencies": {
|
| 3120 |
+
"micromark-util-character": "^2.0.0",
|
| 3121 |
+
"micromark-util-symbol": "^2.0.0",
|
| 3122 |
+
"micromark-util-types": "^2.0.0"
|
| 3123 |
+
}
|
| 3124 |
+
},
|
| 3125 |
+
"node_modules/micromark-factory-label": {
|
| 3126 |
+
"version": "2.0.1",
|
| 3127 |
+
"resolved": "https://registry.npmjs.org/micromark-factory-label/-/micromark-factory-label-2.0.1.tgz",
|
| 3128 |
+
"integrity": "sha512-VFMekyQExqIW7xIChcXn4ok29YE3rnuyveW3wZQWWqF4Nv9Wk5rgJ99KzPvHjkmPXF93FXIbBp6YdW3t71/7Vg==",
|
| 3129 |
+
"funding": [
|
| 3130 |
+
{
|
| 3131 |
+
"type": "GitHub Sponsors",
|
| 3132 |
+
"url": "https://github.com/sponsors/unifiedjs"
|
| 3133 |
+
},
|
| 3134 |
+
{
|
| 3135 |
+
"type": "OpenCollective",
|
| 3136 |
+
"url": "https://opencollective.com/unified"
|
| 3137 |
+
}
|
| 3138 |
+
],
|
| 3139 |
+
"license": "MIT",
|
| 3140 |
+
"dependencies": {
|
| 3141 |
+
"devlop": "^1.0.0",
|
| 3142 |
+
"micromark-util-character": "^2.0.0",
|
| 3143 |
+
"micromark-util-symbol": "^2.0.0",
|
| 3144 |
+
"micromark-util-types": "^2.0.0"
|
| 3145 |
+
}
|
| 3146 |
+
},
|
| 3147 |
+
"node_modules/micromark-factory-space": {
|
| 3148 |
+
"version": "2.0.1",
|
| 3149 |
+
"resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.1.tgz",
|
| 3150 |
+
"integrity": "sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==",
|
| 3151 |
+
"funding": [
|
| 3152 |
+
{
|
| 3153 |
+
"type": "GitHub Sponsors",
|
| 3154 |
+
"url": "https://github.com/sponsors/unifiedjs"
|
| 3155 |
+
},
|
| 3156 |
+
{
|
| 3157 |
+
"type": "OpenCollective",
|
| 3158 |
+
"url": "https://opencollective.com/unified"
|
| 3159 |
+
}
|
| 3160 |
+
],
|
| 3161 |
+
"license": "MIT",
|
| 3162 |
+
"dependencies": {
|
| 3163 |
+
"micromark-util-character": "^2.0.0",
|
| 3164 |
+
"micromark-util-types": "^2.0.0"
|
| 3165 |
+
}
|
| 3166 |
+
},
|
| 3167 |
+
"node_modules/micromark-factory-title": {
|
| 3168 |
+
"version": "2.0.1",
|
| 3169 |
+
"resolved": "https://registry.npmjs.org/micromark-factory-title/-/micromark-factory-title-2.0.1.tgz",
|
| 3170 |
+
"integrity": "sha512-5bZ+3CjhAd9eChYTHsjy6TGxpOFSKgKKJPJxr293jTbfry2KDoWkhBb6TcPVB4NmzaPhMs1Frm9AZH7OD4Cjzw==",
|
| 3171 |
+
"funding": [
|
| 3172 |
+
{
|
| 3173 |
+
"type": "GitHub Sponsors",
|
| 3174 |
+
"url": "https://github.com/sponsors/unifiedjs"
|
| 3175 |
+
},
|
| 3176 |
+
{
|
| 3177 |
+
"type": "OpenCollective",
|
| 3178 |
+
"url": "https://opencollective.com/unified"
|
| 3179 |
+
}
|
| 3180 |
+
],
|
| 3181 |
+
"license": "MIT",
|
| 3182 |
+
"dependencies": {
|
| 3183 |
+
"micromark-factory-space": "^2.0.0",
|
| 3184 |
+
"micromark-util-character": "^2.0.0",
|
| 3185 |
+
"micromark-util-symbol": "^2.0.0",
|
| 3186 |
+
"micromark-util-types": "^2.0.0"
|
| 3187 |
+
}
|
| 3188 |
+
},
|
| 3189 |
+
"node_modules/micromark-factory-whitespace": {
|
| 3190 |
+
"version": "2.0.1",
|
| 3191 |
+
"resolved": "https://registry.npmjs.org/micromark-factory-whitespace/-/micromark-factory-whitespace-2.0.1.tgz",
|
| 3192 |
+
"integrity": "sha512-Ob0nuZ3PKt/n0hORHyvoD9uZhr+Za8sFoP+OnMcnWK5lngSzALgQYKMr9RJVOWLqQYuyn6ulqGWSXdwf6F80lQ==",
|
| 3193 |
+
"funding": [
|
| 3194 |
+
{
|
| 3195 |
+
"type": "GitHub Sponsors",
|
| 3196 |
+
"url": "https://github.com/sponsors/unifiedjs"
|
| 3197 |
+
},
|
| 3198 |
+
{
|
| 3199 |
+
"type": "OpenCollective",
|
| 3200 |
+
"url": "https://opencollective.com/unified"
|
| 3201 |
+
}
|
| 3202 |
+
],
|
| 3203 |
+
"license": "MIT",
|
| 3204 |
+
"dependencies": {
|
| 3205 |
+
"micromark-factory-space": "^2.0.0",
|
| 3206 |
+
"micromark-util-character": "^2.0.0",
|
| 3207 |
+
"micromark-util-symbol": "^2.0.0",
|
| 3208 |
+
"micromark-util-types": "^2.0.0"
|
| 3209 |
+
}
|
| 3210 |
+
},
|
| 3211 |
+
"node_modules/micromark-util-character": {
|
| 3212 |
+
"version": "2.1.1",
|
| 3213 |
+
"resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz",
|
| 3214 |
+
"integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==",
|
| 3215 |
+
"funding": [
|
| 3216 |
+
{
|
| 3217 |
+
"type": "GitHub Sponsors",
|
| 3218 |
+
"url": "https://github.com/sponsors/unifiedjs"
|
| 3219 |
+
},
|
| 3220 |
+
{
|
| 3221 |
+
"type": "OpenCollective",
|
| 3222 |
+
"url": "https://opencollective.com/unified"
|
| 3223 |
+
}
|
| 3224 |
+
],
|
| 3225 |
+
"license": "MIT",
|
| 3226 |
+
"dependencies": {
|
| 3227 |
+
"micromark-util-symbol": "^2.0.0",
|
| 3228 |
+
"micromark-util-types": "^2.0.0"
|
| 3229 |
+
}
|
| 3230 |
+
},
|
| 3231 |
+
"node_modules/micromark-util-chunked": {
|
| 3232 |
+
"version": "2.0.1",
|
| 3233 |
+
"resolved": "https://registry.npmjs.org/micromark-util-chunked/-/micromark-util-chunked-2.0.1.tgz",
|
| 3234 |
+
"integrity": "sha512-QUNFEOPELfmvv+4xiNg2sRYeS/P84pTW0TCgP5zc9FpXetHY0ab7SxKyAQCNCc1eK0459uoLI1y5oO5Vc1dbhA==",
|
| 3235 |
+
"funding": [
|
| 3236 |
+
{
|
| 3237 |
+
"type": "GitHub Sponsors",
|
| 3238 |
+
"url": "https://github.com/sponsors/unifiedjs"
|
| 3239 |
+
},
|
| 3240 |
+
{
|
| 3241 |
+
"type": "OpenCollective",
|
| 3242 |
+
"url": "https://opencollective.com/unified"
|
| 3243 |
+
}
|
| 3244 |
+
],
|
| 3245 |
+
"license": "MIT",
|
| 3246 |
+
"dependencies": {
|
| 3247 |
+
"micromark-util-symbol": "^2.0.0"
|
| 3248 |
+
}
|
| 3249 |
+
},
|
| 3250 |
+
"node_modules/micromark-util-classify-character": {
|
| 3251 |
+
"version": "2.0.1",
|
| 3252 |
+
"resolved": "https://registry.npmjs.org/micromark-util-classify-character/-/micromark-util-classify-character-2.0.1.tgz",
|
| 3253 |
+
"integrity": "sha512-K0kHzM6afW/MbeWYWLjoHQv1sgg2Q9EccHEDzSkxiP/EaagNzCm7T/WMKZ3rjMbvIpvBiZgwR3dKMygtA4mG1Q==",
|
| 3254 |
+
"funding": [
|
| 3255 |
+
{
|
| 3256 |
+
"type": "GitHub Sponsors",
|
| 3257 |
+
"url": "https://github.com/sponsors/unifiedjs"
|
| 3258 |
+
},
|
| 3259 |
+
{
|
| 3260 |
+
"type": "OpenCollective",
|
| 3261 |
+
"url": "https://opencollective.com/unified"
|
| 3262 |
+
}
|
| 3263 |
+
],
|
| 3264 |
+
"license": "MIT",
|
| 3265 |
+
"dependencies": {
|
| 3266 |
+
"micromark-util-character": "^2.0.0",
|
| 3267 |
+
"micromark-util-symbol": "^2.0.0",
|
| 3268 |
+
"micromark-util-types": "^2.0.0"
|
| 3269 |
+
}
|
| 3270 |
+
},
|
| 3271 |
+
"node_modules/micromark-util-combine-extensions": {
|
| 3272 |
+
"version": "2.0.1",
|
| 3273 |
+
"resolved": "https://registry.npmjs.org/micromark-util-combine-extensions/-/micromark-util-combine-extensions-2.0.1.tgz",
|
| 3274 |
+
"integrity": "sha512-OnAnH8Ujmy59JcyZw8JSbK9cGpdVY44NKgSM7E9Eh7DiLS2E9RNQf0dONaGDzEG9yjEl5hcqeIsj4hfRkLH/Bg==",
|
| 3275 |
+
"funding": [
|
| 3276 |
+
{
|
| 3277 |
+
"type": "GitHub Sponsors",
|
| 3278 |
+
"url": "https://github.com/sponsors/unifiedjs"
|
| 3279 |
+
},
|
| 3280 |
+
{
|
| 3281 |
+
"type": "OpenCollective",
|
| 3282 |
+
"url": "https://opencollective.com/unified"
|
| 3283 |
+
}
|
| 3284 |
+
],
|
| 3285 |
+
"license": "MIT",
|
| 3286 |
+
"dependencies": {
|
| 3287 |
+
"micromark-util-chunked": "^2.0.0",
|
| 3288 |
+
"micromark-util-types": "^2.0.0"
|
| 3289 |
+
}
|
| 3290 |
+
},
|
| 3291 |
+
"node_modules/micromark-util-decode-numeric-character-reference": {
|
| 3292 |
+
"version": "2.0.2",
|
| 3293 |
+
"resolved": "https://registry.npmjs.org/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-2.0.2.tgz",
|
| 3294 |
+
"integrity": "sha512-ccUbYk6CwVdkmCQMyr64dXz42EfHGkPQlBj5p7YVGzq8I7CtjXZJrubAYezf7Rp+bjPseiROqe7G6foFd+lEuw==",
|
| 3295 |
+
"funding": [
|
| 3296 |
+
{
|
| 3297 |
+
"type": "GitHub Sponsors",
|
| 3298 |
+
"url": "https://github.com/sponsors/unifiedjs"
|
| 3299 |
+
},
|
| 3300 |
+
{
|
| 3301 |
+
"type": "OpenCollective",
|
| 3302 |
+
"url": "https://opencollective.com/unified"
|
| 3303 |
+
}
|
| 3304 |
+
],
|
| 3305 |
+
"license": "MIT",
|
| 3306 |
+
"dependencies": {
|
| 3307 |
+
"micromark-util-symbol": "^2.0.0"
|
| 3308 |
+
}
|
| 3309 |
+
},
|
| 3310 |
+
"node_modules/micromark-util-decode-string": {
|
| 3311 |
+
"version": "2.0.1",
|
| 3312 |
+
"resolved": "https://registry.npmjs.org/micromark-util-decode-string/-/micromark-util-decode-string-2.0.1.tgz",
|
| 3313 |
+
"integrity": "sha512-nDV/77Fj6eH1ynwscYTOsbK7rR//Uj0bZXBwJZRfaLEJ1iGBR6kIfNmlNqaqJf649EP0F3NWNdeJi03elllNUQ==",
|
| 3314 |
+
"funding": [
|
| 3315 |
+
{
|
| 3316 |
+
"type": "GitHub Sponsors",
|
| 3317 |
+
"url": "https://github.com/sponsors/unifiedjs"
|
| 3318 |
+
},
|
| 3319 |
+
{
|
| 3320 |
+
"type": "OpenCollective",
|
| 3321 |
+
"url": "https://opencollective.com/unified"
|
| 3322 |
+
}
|
| 3323 |
+
],
|
| 3324 |
+
"license": "MIT",
|
| 3325 |
+
"dependencies": {
|
| 3326 |
+
"decode-named-character-reference": "^1.0.0",
|
| 3327 |
+
"micromark-util-character": "^2.0.0",
|
| 3328 |
+
"micromark-util-decode-numeric-character-reference": "^2.0.0",
|
| 3329 |
+
"micromark-util-symbol": "^2.0.0"
|
| 3330 |
+
}
|
| 3331 |
+
},
|
| 3332 |
+
"node_modules/micromark-util-encode": {
|
| 3333 |
+
"version": "2.0.1",
|
| 3334 |
+
"resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-2.0.1.tgz",
|
| 3335 |
+
"integrity": "sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==",
|
| 3336 |
+
"funding": [
|
| 3337 |
+
{
|
| 3338 |
+
"type": "GitHub Sponsors",
|
| 3339 |
+
"url": "https://github.com/sponsors/unifiedjs"
|
| 3340 |
+
},
|
| 3341 |
+
{
|
| 3342 |
+
"type": "OpenCollective",
|
| 3343 |
+
"url": "https://opencollective.com/unified"
|
| 3344 |
+
}
|
| 3345 |
+
],
|
| 3346 |
+
"license": "MIT"
|
| 3347 |
+
},
|
| 3348 |
+
"node_modules/micromark-util-html-tag-name": {
|
| 3349 |
+
"version": "2.0.1",
|
| 3350 |
+
"resolved": "https://registry.npmjs.org/micromark-util-html-tag-name/-/micromark-util-html-tag-name-2.0.1.tgz",
|
| 3351 |
+
"integrity": "sha512-2cNEiYDhCWKI+Gs9T0Tiysk136SnR13hhO8yW6BGNyhOC4qYFnwF1nKfD3HFAIXA5c45RrIG1ub11GiXeYd1xA==",
|
| 3352 |
+
"funding": [
|
| 3353 |
+
{
|
| 3354 |
+
"type": "GitHub Sponsors",
|
| 3355 |
+
"url": "https://github.com/sponsors/unifiedjs"
|
| 3356 |
+
},
|
| 3357 |
+
{
|
| 3358 |
+
"type": "OpenCollective",
|
| 3359 |
+
"url": "https://opencollective.com/unified"
|
| 3360 |
+
}
|
| 3361 |
+
],
|
| 3362 |
+
"license": "MIT"
|
| 3363 |
+
},
|
| 3364 |
+
"node_modules/micromark-util-normalize-identifier": {
|
| 3365 |
+
"version": "2.0.1",
|
| 3366 |
+
"resolved": "https://registry.npmjs.org/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-2.0.1.tgz",
|
| 3367 |
+
"integrity": "sha512-sxPqmo70LyARJs0w2UclACPUUEqltCkJ6PhKdMIDuJ3gSf/Q+/GIe3WKl0Ijb/GyH9lOpUkRAO2wp0GVkLvS9Q==",
|
| 3368 |
+
"funding": [
|
| 3369 |
+
{
|
| 3370 |
+
"type": "GitHub Sponsors",
|
| 3371 |
+
"url": "https://github.com/sponsors/unifiedjs"
|
| 3372 |
+
},
|
| 3373 |
+
{
|
| 3374 |
+
"type": "OpenCollective",
|
| 3375 |
+
"url": "https://opencollective.com/unified"
|
| 3376 |
+
}
|
| 3377 |
+
],
|
| 3378 |
+
"license": "MIT",
|
| 3379 |
+
"dependencies": {
|
| 3380 |
+
"micromark-util-symbol": "^2.0.0"
|
| 3381 |
+
}
|
| 3382 |
+
},
|
| 3383 |
+
"node_modules/micromark-util-resolve-all": {
|
| 3384 |
+
"version": "2.0.1",
|
| 3385 |
+
"resolved": "https://registry.npmjs.org/micromark-util-resolve-all/-/micromark-util-resolve-all-2.0.1.tgz",
|
| 3386 |
+
"integrity": "sha512-VdQyxFWFT2/FGJgwQnJYbe1jjQoNTS4RjglmSjTUlpUMa95Htx9NHeYW4rGDJzbjvCsl9eLjMQwGeElsqmzcHg==",
|
| 3387 |
+
"funding": [
|
| 3388 |
+
{
|
| 3389 |
+
"type": "GitHub Sponsors",
|
| 3390 |
+
"url": "https://github.com/sponsors/unifiedjs"
|
| 3391 |
+
},
|
| 3392 |
+
{
|
| 3393 |
+
"type": "OpenCollective",
|
| 3394 |
+
"url": "https://opencollective.com/unified"
|
| 3395 |
+
}
|
| 3396 |
+
],
|
| 3397 |
+
"license": "MIT",
|
| 3398 |
+
"dependencies": {
|
| 3399 |
+
"micromark-util-types": "^2.0.0"
|
| 3400 |
+
}
|
| 3401 |
+
},
|
| 3402 |
+
"node_modules/micromark-util-sanitize-uri": {
|
| 3403 |
+
"version": "2.0.1",
|
| 3404 |
+
"resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-2.0.1.tgz",
|
| 3405 |
+
"integrity": "sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ==",
|
| 3406 |
+
"funding": [
|
| 3407 |
+
{
|
| 3408 |
+
"type": "GitHub Sponsors",
|
| 3409 |
+
"url": "https://github.com/sponsors/unifiedjs"
|
| 3410 |
+
},
|
| 3411 |
+
{
|
| 3412 |
+
"type": "OpenCollective",
|
| 3413 |
+
"url": "https://opencollective.com/unified"
|
| 3414 |
+
}
|
| 3415 |
+
],
|
| 3416 |
+
"license": "MIT",
|
| 3417 |
+
"dependencies": {
|
| 3418 |
+
"micromark-util-character": "^2.0.0",
|
| 3419 |
+
"micromark-util-encode": "^2.0.0",
|
| 3420 |
+
"micromark-util-symbol": "^2.0.0"
|
| 3421 |
+
}
|
| 3422 |
+
},
|
| 3423 |
+
"node_modules/micromark-util-subtokenize": {
|
| 3424 |
+
"version": "2.1.0",
|
| 3425 |
+
"resolved": "https://registry.npmjs.org/micromark-util-subtokenize/-/micromark-util-subtokenize-2.1.0.tgz",
|
| 3426 |
+
"integrity": "sha512-XQLu552iSctvnEcgXw6+Sx75GflAPNED1qx7eBJ+wydBb2KCbRZe+NwvIEEMM83uml1+2WSXpBAcp9IUCgCYWA==",
|
| 3427 |
+
"funding": [
|
| 3428 |
+
{
|
| 3429 |
+
"type": "GitHub Sponsors",
|
| 3430 |
+
"url": "https://github.com/sponsors/unifiedjs"
|
| 3431 |
+
},
|
| 3432 |
+
{
|
| 3433 |
+
"type": "OpenCollective",
|
| 3434 |
+
"url": "https://opencollective.com/unified"
|
| 3435 |
+
}
|
| 3436 |
+
],
|
| 3437 |
+
"license": "MIT",
|
| 3438 |
+
"dependencies": {
|
| 3439 |
+
"devlop": "^1.0.0",
|
| 3440 |
+
"micromark-util-chunked": "^2.0.0",
|
| 3441 |
+
"micromark-util-symbol": "^2.0.0",
|
| 3442 |
+
"micromark-util-types": "^2.0.0"
|
| 3443 |
+
}
|
| 3444 |
+
},
|
| 3445 |
+
"node_modules/micromark-util-symbol": {
|
| 3446 |
+
"version": "2.0.1",
|
| 3447 |
+
"resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz",
|
| 3448 |
+
"integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==",
|
| 3449 |
+
"funding": [
|
| 3450 |
+
{
|
| 3451 |
+
"type": "GitHub Sponsors",
|
| 3452 |
+
"url": "https://github.com/sponsors/unifiedjs"
|
| 3453 |
+
},
|
| 3454 |
+
{
|
| 3455 |
+
"type": "OpenCollective",
|
| 3456 |
+
"url": "https://opencollective.com/unified"
|
| 3457 |
+
}
|
| 3458 |
+
],
|
| 3459 |
+
"license": "MIT"
|
| 3460 |
+
},
|
| 3461 |
+
"node_modules/micromark-util-types": {
|
| 3462 |
+
"version": "2.0.2",
|
| 3463 |
+
"resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-2.0.2.tgz",
|
| 3464 |
+
"integrity": "sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA==",
|
| 3465 |
+
"funding": [
|
| 3466 |
+
{
|
| 3467 |
+
"type": "GitHub Sponsors",
|
| 3468 |
+
"url": "https://github.com/sponsors/unifiedjs"
|
| 3469 |
+
},
|
| 3470 |
+
{
|
| 3471 |
+
"type": "OpenCollective",
|
| 3472 |
+
"url": "https://opencollective.com/unified"
|
| 3473 |
+
}
|
| 3474 |
+
],
|
| 3475 |
+
"license": "MIT"
|
| 3476 |
+
},
|
| 3477 |
+
"node_modules/minimatch": {
|
| 3478 |
+
"version": "3.1.2",
|
| 3479 |
+
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
|
| 3480 |
+
"integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
|
| 3481 |
+
"dev": true,
|
| 3482 |
+
"license": "ISC",
|
| 3483 |
+
"dependencies": {
|
| 3484 |
+
"brace-expansion": "^1.1.7"
|
| 3485 |
+
},
|
| 3486 |
+
"engines": {
|
| 3487 |
+
"node": "*"
|
| 3488 |
+
}
|
| 3489 |
+
},
|
| 3490 |
+
"node_modules/ms": {
|
| 3491 |
+
"version": "2.1.3",
|
| 3492 |
+
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
|
| 3493 |
+
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
|
| 3494 |
+
"license": "MIT"
|
| 3495 |
+
},
|
| 3496 |
+
"node_modules/nanoid": {
|
| 3497 |
+
"version": "3.3.11",
|
| 3498 |
+
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz",
|
| 3499 |
+
"integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==",
|
| 3500 |
+
"dev": true,
|
| 3501 |
+
"funding": [
|
| 3502 |
+
{
|
| 3503 |
+
"type": "github",
|
| 3504 |
+
"url": "https://github.com/sponsors/ai"
|
| 3505 |
+
}
|
| 3506 |
+
],
|
| 3507 |
+
"license": "MIT",
|
| 3508 |
+
"bin": {
|
| 3509 |
+
"nanoid": "bin/nanoid.cjs"
|
| 3510 |
+
},
|
| 3511 |
+
"engines": {
|
| 3512 |
+
"node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
|
| 3513 |
+
}
|
| 3514 |
+
},
|
| 3515 |
+
"node_modules/natural-compare": {
|
| 3516 |
+
"version": "1.4.0",
|
| 3517 |
+
"resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
|
| 3518 |
+
"integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==",
|
| 3519 |
+
"dev": true,
|
| 3520 |
+
"license": "MIT"
|
| 3521 |
+
},
|
| 3522 |
+
"node_modules/node-releases": {
|
| 3523 |
+
"version": "2.0.19",
|
| 3524 |
+
"resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz",
|
| 3525 |
+
"integrity": "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==",
|
| 3526 |
+
"dev": true,
|
| 3527 |
+
"license": "MIT"
|
| 3528 |
+
},
|
| 3529 |
+
"node_modules/normalize-range": {
|
| 3530 |
+
"version": "0.1.2",
|
| 3531 |
+
"resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz",
|
| 3532 |
+
"integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==",
|
| 3533 |
+
"dev": true,
|
| 3534 |
+
"license": "MIT",
|
| 3535 |
+
"engines": {
|
| 3536 |
+
"node": ">=0.10.0"
|
| 3537 |
+
}
|
| 3538 |
+
},
|
| 3539 |
+
"node_modules/optionator": {
|
| 3540 |
+
"version": "0.9.4",
|
| 3541 |
+
"resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz",
|
| 3542 |
+
"integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==",
|
| 3543 |
+
"dev": true,
|
| 3544 |
+
"license": "MIT",
|
| 3545 |
+
"dependencies": {
|
| 3546 |
+
"deep-is": "^0.1.3",
|
| 3547 |
+
"fast-levenshtein": "^2.0.6",
|
| 3548 |
+
"levn": "^0.4.1",
|
| 3549 |
+
"prelude-ls": "^1.2.1",
|
| 3550 |
+
"type-check": "^0.4.0",
|
| 3551 |
+
"word-wrap": "^1.2.5"
|
| 3552 |
+
},
|
| 3553 |
+
"engines": {
|
| 3554 |
+
"node": ">= 0.8.0"
|
| 3555 |
+
}
|
| 3556 |
+
},
|
| 3557 |
+
"node_modules/p-limit": {
|
| 3558 |
+
"version": "3.1.0",
|
| 3559 |
+
"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
|
| 3560 |
+
"integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==",
|
| 3561 |
+
"dev": true,
|
| 3562 |
+
"license": "MIT",
|
| 3563 |
+
"dependencies": {
|
| 3564 |
+
"yocto-queue": "^0.1.0"
|
| 3565 |
+
},
|
| 3566 |
+
"engines": {
|
| 3567 |
+
"node": ">=10"
|
| 3568 |
+
},
|
| 3569 |
+
"funding": {
|
| 3570 |
+
"url": "https://github.com/sponsors/sindresorhus"
|
| 3571 |
+
}
|
| 3572 |
+
},
|
| 3573 |
+
"node_modules/p-locate": {
|
| 3574 |
+
"version": "5.0.0",
|
| 3575 |
+
"resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz",
|
| 3576 |
+
"integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==",
|
| 3577 |
+
"dev": true,
|
| 3578 |
"license": "MIT",
|
| 3579 |
"dependencies": {
|
| 3580 |
"p-limit": "^3.0.2"
|
|
|
|
| 3599 |
"node": ">=6"
|
| 3600 |
}
|
| 3601 |
},
|
| 3602 |
+
"node_modules/parse-entities": {
|
| 3603 |
+
"version": "4.0.2",
|
| 3604 |
+
"resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-4.0.2.tgz",
|
| 3605 |
+
"integrity": "sha512-GG2AQYWoLgL877gQIKeRPGO1xF9+eG1ujIb5soS5gPvLQ1y2o8FL90w2QWNdf9I361Mpp7726c+lj3U0qK1uGw==",
|
| 3606 |
+
"license": "MIT",
|
| 3607 |
+
"dependencies": {
|
| 3608 |
+
"@types/unist": "^2.0.0",
|
| 3609 |
+
"character-entities-legacy": "^3.0.0",
|
| 3610 |
+
"character-reference-invalid": "^2.0.0",
|
| 3611 |
+
"decode-named-character-reference": "^1.0.0",
|
| 3612 |
+
"is-alphanumerical": "^2.0.0",
|
| 3613 |
+
"is-decimal": "^2.0.0",
|
| 3614 |
+
"is-hexadecimal": "^2.0.0"
|
| 3615 |
+
},
|
| 3616 |
+
"funding": {
|
| 3617 |
+
"type": "github",
|
| 3618 |
+
"url": "https://github.com/sponsors/wooorm"
|
| 3619 |
+
}
|
| 3620 |
+
},
|
| 3621 |
+
"node_modules/parse-entities/node_modules/@types/unist": {
|
| 3622 |
+
"version": "2.0.11",
|
| 3623 |
+
"resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.11.tgz",
|
| 3624 |
+
"integrity": "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==",
|
| 3625 |
+
"license": "MIT"
|
| 3626 |
+
},
|
| 3627 |
"node_modules/path-exists": {
|
| 3628 |
"version": "4.0.0",
|
| 3629 |
"resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
|
|
|
|
| 3710 |
"node": ">= 0.8.0"
|
| 3711 |
}
|
| 3712 |
},
|
| 3713 |
+
"node_modules/property-information": {
|
| 3714 |
+
"version": "7.1.0",
|
| 3715 |
+
"resolved": "https://registry.npmjs.org/property-information/-/property-information-7.1.0.tgz",
|
| 3716 |
+
"integrity": "sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ==",
|
| 3717 |
+
"license": "MIT",
|
| 3718 |
+
"funding": {
|
| 3719 |
+
"type": "github",
|
| 3720 |
+
"url": "https://github.com/sponsors/wooorm"
|
| 3721 |
+
}
|
| 3722 |
+
},
|
| 3723 |
"node_modules/punycode": {
|
| 3724 |
"version": "2.3.1",
|
| 3725 |
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz",
|
|
|
|
| 3751 |
"react": "^19.1.0"
|
| 3752 |
}
|
| 3753 |
},
|
| 3754 |
+
"node_modules/react-markdown": {
|
| 3755 |
+
"version": "10.1.0",
|
| 3756 |
+
"resolved": "https://registry.npmjs.org/react-markdown/-/react-markdown-10.1.0.tgz",
|
| 3757 |
+
"integrity": "sha512-qKxVopLT/TyA6BX3Ue5NwabOsAzm0Q7kAPwq6L+wWDwisYs7R8vZ0nRXqq6rkueboxpkjvLGU9fWifiX/ZZFxQ==",
|
| 3758 |
+
"license": "MIT",
|
| 3759 |
+
"dependencies": {
|
| 3760 |
+
"@types/hast": "^3.0.0",
|
| 3761 |
+
"@types/mdast": "^4.0.0",
|
| 3762 |
+
"devlop": "^1.0.0",
|
| 3763 |
+
"hast-util-to-jsx-runtime": "^2.0.0",
|
| 3764 |
+
"html-url-attributes": "^3.0.0",
|
| 3765 |
+
"mdast-util-to-hast": "^13.0.0",
|
| 3766 |
+
"remark-parse": "^11.0.0",
|
| 3767 |
+
"remark-rehype": "^11.0.0",
|
| 3768 |
+
"unified": "^11.0.0",
|
| 3769 |
+
"unist-util-visit": "^5.0.0",
|
| 3770 |
+
"vfile": "^6.0.0"
|
| 3771 |
+
},
|
| 3772 |
+
"funding": {
|
| 3773 |
+
"type": "opencollective",
|
| 3774 |
+
"url": "https://opencollective.com/unified"
|
| 3775 |
+
},
|
| 3776 |
+
"peerDependencies": {
|
| 3777 |
+
"@types/react": ">=18",
|
| 3778 |
+
"react": ">=18"
|
| 3779 |
+
}
|
| 3780 |
+
},
|
| 3781 |
"node_modules/react-refresh": {
|
| 3782 |
"version": "0.17.0",
|
| 3783 |
"resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.17.0.tgz",
|
|
|
|
| 3788 |
"node": ">=0.10.0"
|
| 3789 |
}
|
| 3790 |
},
|
| 3791 |
+
"node_modules/remark-gfm": {
|
| 3792 |
+
"version": "4.0.1",
|
| 3793 |
+
"resolved": "https://registry.npmjs.org/remark-gfm/-/remark-gfm-4.0.1.tgz",
|
| 3794 |
+
"integrity": "sha512-1quofZ2RQ9EWdeN34S79+KExV1764+wCUGop5CPL1WGdD0ocPpu91lzPGbwWMECpEpd42kJGQwzRfyov9j4yNg==",
|
| 3795 |
+
"license": "MIT",
|
| 3796 |
+
"dependencies": {
|
| 3797 |
+
"@types/mdast": "^4.0.0",
|
| 3798 |
+
"mdast-util-gfm": "^3.0.0",
|
| 3799 |
+
"micromark-extension-gfm": "^3.0.0",
|
| 3800 |
+
"remark-parse": "^11.0.0",
|
| 3801 |
+
"remark-stringify": "^11.0.0",
|
| 3802 |
+
"unified": "^11.0.0"
|
| 3803 |
+
},
|
| 3804 |
+
"funding": {
|
| 3805 |
+
"type": "opencollective",
|
| 3806 |
+
"url": "https://opencollective.com/unified"
|
| 3807 |
+
}
|
| 3808 |
+
},
|
| 3809 |
+
"node_modules/remark-parse": {
|
| 3810 |
+
"version": "11.0.0",
|
| 3811 |
+
"resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-11.0.0.tgz",
|
| 3812 |
+
"integrity": "sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA==",
|
| 3813 |
+
"license": "MIT",
|
| 3814 |
+
"dependencies": {
|
| 3815 |
+
"@types/mdast": "^4.0.0",
|
| 3816 |
+
"mdast-util-from-markdown": "^2.0.0",
|
| 3817 |
+
"micromark-util-types": "^2.0.0",
|
| 3818 |
+
"unified": "^11.0.0"
|
| 3819 |
+
},
|
| 3820 |
+
"funding": {
|
| 3821 |
+
"type": "opencollective",
|
| 3822 |
+
"url": "https://opencollective.com/unified"
|
| 3823 |
+
}
|
| 3824 |
+
},
|
| 3825 |
+
"node_modules/remark-rehype": {
|
| 3826 |
+
"version": "11.1.2",
|
| 3827 |
+
"resolved": "https://registry.npmjs.org/remark-rehype/-/remark-rehype-11.1.2.tgz",
|
| 3828 |
+
"integrity": "sha512-Dh7l57ianaEoIpzbp0PC9UKAdCSVklD8E5Rpw7ETfbTl3FqcOOgq5q2LVDhgGCkaBv7p24JXikPdvhhmHvKMsw==",
|
| 3829 |
+
"license": "MIT",
|
| 3830 |
+
"dependencies": {
|
| 3831 |
+
"@types/hast": "^3.0.0",
|
| 3832 |
+
"@types/mdast": "^4.0.0",
|
| 3833 |
+
"mdast-util-to-hast": "^13.0.0",
|
| 3834 |
+
"unified": "^11.0.0",
|
| 3835 |
+
"vfile": "^6.0.0"
|
| 3836 |
+
},
|
| 3837 |
+
"funding": {
|
| 3838 |
+
"type": "opencollective",
|
| 3839 |
+
"url": "https://opencollective.com/unified"
|
| 3840 |
+
}
|
| 3841 |
+
},
|
| 3842 |
+
"node_modules/remark-stringify": {
|
| 3843 |
+
"version": "11.0.0",
|
| 3844 |
+
"resolved": "https://registry.npmjs.org/remark-stringify/-/remark-stringify-11.0.0.tgz",
|
| 3845 |
+
"integrity": "sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw==",
|
| 3846 |
+
"license": "MIT",
|
| 3847 |
+
"dependencies": {
|
| 3848 |
+
"@types/mdast": "^4.0.0",
|
| 3849 |
+
"mdast-util-to-markdown": "^2.0.0",
|
| 3850 |
+
"unified": "^11.0.0"
|
| 3851 |
+
},
|
| 3852 |
+
"funding": {
|
| 3853 |
+
"type": "opencollective",
|
| 3854 |
+
"url": "https://opencollective.com/unified"
|
| 3855 |
+
}
|
| 3856 |
+
},
|
| 3857 |
"node_modules/resolve-from": {
|
| 3858 |
"version": "4.0.0",
|
| 3859 |
"resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
|
|
|
|
| 3953 |
"node": ">=0.10.0"
|
| 3954 |
}
|
| 3955 |
},
|
| 3956 |
+
"node_modules/space-separated-tokens": {
|
| 3957 |
+
"version": "2.0.2",
|
| 3958 |
+
"resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-2.0.2.tgz",
|
| 3959 |
+
"integrity": "sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==",
|
| 3960 |
+
"license": "MIT",
|
| 3961 |
+
"funding": {
|
| 3962 |
+
"type": "github",
|
| 3963 |
+
"url": "https://github.com/sponsors/wooorm"
|
| 3964 |
+
}
|
| 3965 |
+
},
|
| 3966 |
+
"node_modules/stringify-entities": {
|
| 3967 |
+
"version": "4.0.4",
|
| 3968 |
+
"resolved": "https://registry.npmjs.org/stringify-entities/-/stringify-entities-4.0.4.tgz",
|
| 3969 |
+
"integrity": "sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==",
|
| 3970 |
+
"license": "MIT",
|
| 3971 |
+
"dependencies": {
|
| 3972 |
+
"character-entities-html4": "^2.0.0",
|
| 3973 |
+
"character-entities-legacy": "^3.0.0"
|
| 3974 |
+
},
|
| 3975 |
+
"funding": {
|
| 3976 |
+
"type": "github",
|
| 3977 |
+
"url": "https://github.com/sponsors/wooorm"
|
| 3978 |
+
}
|
| 3979 |
+
},
|
| 3980 |
"node_modules/strip-json-comments": {
|
| 3981 |
"version": "3.1.1",
|
| 3982 |
"resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz",
|
|
|
|
| 3990 |
"url": "https://github.com/sponsors/sindresorhus"
|
| 3991 |
}
|
| 3992 |
},
|
| 3993 |
+
"node_modules/style-to-js": {
|
| 3994 |
+
"version": "1.1.17",
|
| 3995 |
+
"resolved": "https://registry.npmjs.org/style-to-js/-/style-to-js-1.1.17.tgz",
|
| 3996 |
+
"integrity": "sha512-xQcBGDxJb6jjFCTzvQtfiPn6YvvP2O8U1MDIPNfJQlWMYfktPy+iGsHE7cssjs7y84d9fQaK4UF3RIJaAHSoYA==",
|
| 3997 |
+
"license": "MIT",
|
| 3998 |
+
"dependencies": {
|
| 3999 |
+
"style-to-object": "1.0.9"
|
| 4000 |
+
}
|
| 4001 |
+
},
|
| 4002 |
+
"node_modules/style-to-object": {
|
| 4003 |
+
"version": "1.0.9",
|
| 4004 |
+
"resolved": "https://registry.npmjs.org/style-to-object/-/style-to-object-1.0.9.tgz",
|
| 4005 |
+
"integrity": "sha512-G4qppLgKu/k6FwRpHiGiKPaPTFcG3g4wNVX/Qsfu+RqQM30E7Tyu/TEgxcL9PNLF5pdRLwQdE3YKKf+KF2Dzlw==",
|
| 4006 |
+
"license": "MIT",
|
| 4007 |
+
"dependencies": {
|
| 4008 |
+
"inline-style-parser": "0.2.4"
|
| 4009 |
+
}
|
| 4010 |
+
},
|
| 4011 |
"node_modules/supports-color": {
|
| 4012 |
"version": "7.2.0",
|
| 4013 |
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
|
|
|
|
| 4045 |
"url": "https://github.com/sponsors/SuperchupuDev"
|
| 4046 |
}
|
| 4047 |
},
|
| 4048 |
+
"node_modules/trim-lines": {
|
| 4049 |
+
"version": "3.0.1",
|
| 4050 |
+
"resolved": "https://registry.npmjs.org/trim-lines/-/trim-lines-3.0.1.tgz",
|
| 4051 |
+
"integrity": "sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==",
|
| 4052 |
+
"license": "MIT",
|
| 4053 |
+
"funding": {
|
| 4054 |
+
"type": "github",
|
| 4055 |
+
"url": "https://github.com/sponsors/wooorm"
|
| 4056 |
+
}
|
| 4057 |
+
},
|
| 4058 |
+
"node_modules/trough": {
|
| 4059 |
+
"version": "2.2.0",
|
| 4060 |
+
"resolved": "https://registry.npmjs.org/trough/-/trough-2.2.0.tgz",
|
| 4061 |
+
"integrity": "sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw==",
|
| 4062 |
+
"license": "MIT",
|
| 4063 |
+
"funding": {
|
| 4064 |
+
"type": "github",
|
| 4065 |
+
"url": "https://github.com/sponsors/wooorm"
|
| 4066 |
+
}
|
| 4067 |
+
},
|
| 4068 |
"node_modules/type-check": {
|
| 4069 |
"version": "0.4.0",
|
| 4070 |
"resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz",
|
|
|
|
| 4078 |
"node": ">= 0.8.0"
|
| 4079 |
}
|
| 4080 |
},
|
| 4081 |
+
"node_modules/unified": {
|
| 4082 |
+
"version": "11.0.5",
|
| 4083 |
+
"resolved": "https://registry.npmjs.org/unified/-/unified-11.0.5.tgz",
|
| 4084 |
+
"integrity": "sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA==",
|
| 4085 |
+
"license": "MIT",
|
| 4086 |
+
"dependencies": {
|
| 4087 |
+
"@types/unist": "^3.0.0",
|
| 4088 |
+
"bail": "^2.0.0",
|
| 4089 |
+
"devlop": "^1.0.0",
|
| 4090 |
+
"extend": "^3.0.0",
|
| 4091 |
+
"is-plain-obj": "^4.0.0",
|
| 4092 |
+
"trough": "^2.0.0",
|
| 4093 |
+
"vfile": "^6.0.0"
|
| 4094 |
+
},
|
| 4095 |
+
"funding": {
|
| 4096 |
+
"type": "opencollective",
|
| 4097 |
+
"url": "https://opencollective.com/unified"
|
| 4098 |
+
}
|
| 4099 |
+
},
|
| 4100 |
+
"node_modules/unist-util-is": {
|
| 4101 |
+
"version": "6.0.0",
|
| 4102 |
+
"resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.0.tgz",
|
| 4103 |
+
"integrity": "sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==",
|
| 4104 |
+
"license": "MIT",
|
| 4105 |
+
"dependencies": {
|
| 4106 |
+
"@types/unist": "^3.0.0"
|
| 4107 |
+
},
|
| 4108 |
+
"funding": {
|
| 4109 |
+
"type": "opencollective",
|
| 4110 |
+
"url": "https://opencollective.com/unified"
|
| 4111 |
+
}
|
| 4112 |
+
},
|
| 4113 |
+
"node_modules/unist-util-position": {
|
| 4114 |
+
"version": "5.0.0",
|
| 4115 |
+
"resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-5.0.0.tgz",
|
| 4116 |
+
"integrity": "sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==",
|
| 4117 |
+
"license": "MIT",
|
| 4118 |
+
"dependencies": {
|
| 4119 |
+
"@types/unist": "^3.0.0"
|
| 4120 |
+
},
|
| 4121 |
+
"funding": {
|
| 4122 |
+
"type": "opencollective",
|
| 4123 |
+
"url": "https://opencollective.com/unified"
|
| 4124 |
+
}
|
| 4125 |
+
},
|
| 4126 |
+
"node_modules/unist-util-stringify-position": {
|
| 4127 |
+
"version": "4.0.0",
|
| 4128 |
+
"resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz",
|
| 4129 |
+
"integrity": "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==",
|
| 4130 |
+
"license": "MIT",
|
| 4131 |
+
"dependencies": {
|
| 4132 |
+
"@types/unist": "^3.0.0"
|
| 4133 |
+
},
|
| 4134 |
+
"funding": {
|
| 4135 |
+
"type": "opencollective",
|
| 4136 |
+
"url": "https://opencollective.com/unified"
|
| 4137 |
+
}
|
| 4138 |
+
},
|
| 4139 |
+
"node_modules/unist-util-visit": {
|
| 4140 |
+
"version": "5.0.0",
|
| 4141 |
+
"resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-5.0.0.tgz",
|
| 4142 |
+
"integrity": "sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==",
|
| 4143 |
+
"license": "MIT",
|
| 4144 |
+
"dependencies": {
|
| 4145 |
+
"@types/unist": "^3.0.0",
|
| 4146 |
+
"unist-util-is": "^6.0.0",
|
| 4147 |
+
"unist-util-visit-parents": "^6.0.0"
|
| 4148 |
+
},
|
| 4149 |
+
"funding": {
|
| 4150 |
+
"type": "opencollective",
|
| 4151 |
+
"url": "https://opencollective.com/unified"
|
| 4152 |
+
}
|
| 4153 |
+
},
|
| 4154 |
+
"node_modules/unist-util-visit-parents": {
|
| 4155 |
+
"version": "6.0.1",
|
| 4156 |
+
"resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-6.0.1.tgz",
|
| 4157 |
+
"integrity": "sha512-L/PqWzfTP9lzzEa6CKs0k2nARxTdZduw3zyh8d2NVBnsyvHjSX4TWse388YrrQKbvI8w20fGjGlhgT96WwKykw==",
|
| 4158 |
+
"license": "MIT",
|
| 4159 |
+
"dependencies": {
|
| 4160 |
+
"@types/unist": "^3.0.0",
|
| 4161 |
+
"unist-util-is": "^6.0.0"
|
| 4162 |
+
},
|
| 4163 |
+
"funding": {
|
| 4164 |
+
"type": "opencollective",
|
| 4165 |
+
"url": "https://opencollective.com/unified"
|
| 4166 |
+
}
|
| 4167 |
+
},
|
| 4168 |
"node_modules/update-browserslist-db": {
|
| 4169 |
"version": "1.1.3",
|
| 4170 |
"resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.3.tgz",
|
|
|
|
| 4206 |
"punycode": "^2.1.0"
|
| 4207 |
}
|
| 4208 |
},
|
| 4209 |
+
"node_modules/vfile": {
|
| 4210 |
+
"version": "6.0.3",
|
| 4211 |
+
"resolved": "https://registry.npmjs.org/vfile/-/vfile-6.0.3.tgz",
|
| 4212 |
+
"integrity": "sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==",
|
| 4213 |
+
"license": "MIT",
|
| 4214 |
+
"dependencies": {
|
| 4215 |
+
"@types/unist": "^3.0.0",
|
| 4216 |
+
"vfile-message": "^4.0.0"
|
| 4217 |
+
},
|
| 4218 |
+
"funding": {
|
| 4219 |
+
"type": "opencollective",
|
| 4220 |
+
"url": "https://opencollective.com/unified"
|
| 4221 |
+
}
|
| 4222 |
+
},
|
| 4223 |
+
"node_modules/vfile-message": {
|
| 4224 |
+
"version": "4.0.2",
|
| 4225 |
+
"resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.2.tgz",
|
| 4226 |
+
"integrity": "sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw==",
|
| 4227 |
+
"license": "MIT",
|
| 4228 |
+
"dependencies": {
|
| 4229 |
+
"@types/unist": "^3.0.0",
|
| 4230 |
+
"unist-util-stringify-position": "^4.0.0"
|
| 4231 |
+
},
|
| 4232 |
+
"funding": {
|
| 4233 |
+
"type": "opencollective",
|
| 4234 |
+
"url": "https://opencollective.com/unified"
|
| 4235 |
+
}
|
| 4236 |
+
},
|
| 4237 |
"node_modules/vite": {
|
| 4238 |
"version": "6.3.5",
|
| 4239 |
"resolved": "https://registry.npmjs.org/vite/-/vite-6.3.5.tgz",
|
|
|
|
| 4354 |
"funding": {
|
| 4355 |
"url": "https://github.com/sponsors/sindresorhus"
|
| 4356 |
}
|
| 4357 |
+
},
|
| 4358 |
+
"node_modules/zwitch": {
|
| 4359 |
+
"version": "2.0.4",
|
| 4360 |
+
"resolved": "https://registry.npmjs.org/zwitch/-/zwitch-2.0.4.tgz",
|
| 4361 |
+
"integrity": "sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==",
|
| 4362 |
+
"license": "MIT",
|
| 4363 |
+
"funding": {
|
| 4364 |
+
"type": "github",
|
| 4365 |
+
"url": "https://github.com/sponsors/wooorm"
|
| 4366 |
+
}
|
| 4367 |
}
|
| 4368 |
}
|
| 4369 |
}
|
package.json
CHANGED
|
@@ -13,7 +13,9 @@
|
|
| 13 |
"date-fns": "^4.1.0",
|
| 14 |
"lucide-react": "^0.525.0",
|
| 15 |
"react": "^19.0.0",
|
| 16 |
-
"react-dom": "^19.0.0"
|
|
|
|
|
|
|
| 17 |
},
|
| 18 |
"devDependencies": {
|
| 19 |
"@eslint/js": "^9.22.0",
|
|
|
|
| 13 |
"date-fns": "^4.1.0",
|
| 14 |
"lucide-react": "^0.525.0",
|
| 15 |
"react": "^19.0.0",
|
| 16 |
+
"react-dom": "^19.0.0",
|
| 17 |
+
"react-markdown": "^10.1.0",
|
| 18 |
+
"remark-gfm": "^4.0.1"
|
| 19 |
},
|
| 20 |
"devDependencies": {
|
| 21 |
"@eslint/js": "^9.22.0",
|
src/backend/profile_data.py
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
YOUR_NAME = "Abdullah Khaled"
|
| 2 |
+
|
| 3 |
+
YOUR_GITHUB_USERNAME = "abdullah-khaled0"
|
| 4 |
+
|
| 5 |
+
YOUR_VERCEL_URL = "https://ai-voice-secretary-git-main-abdullah-khaled0s-projects.vercel.app"
|
| 6 |
+
|
| 7 |
+
|
| 8 |
+
|
| 9 |
+
profile_str = """
|
| 10 |
+
Abdullah Khaled | AI Engineer - Data Scientist
|
| 11 |
+
|
| 12 |
+
=== PERSONAL INFORMATION ===
|
| 13 |
+
Phone: +201557504902
|
| 14 |
+
WhatsApp: +201557504902
|
| 15 |
+
Gmail: [email protected]
|
| 16 |
+
Location: Cairo, Egypt
|
| 17 |
+
Age: 22 years old
|
| 18 |
+
Status: Single
|
| 19 |
+
Open to work in: Remote, On-site, Hybrid
|
| 20 |
+
Military Status: deferred
|
| 21 |
+
Graduated from: Beni Suef University
|
| 22 |
+
|
| 23 |
+
=== LEARNING PLATFORMS ===
|
| 24 |
+
LinkedIn: https://linkedin.com/in/abdullah-khaled-0608a9236
|
| 25 |
+
Kaggle: https://kaggle.com/abdullah7aled
|
| 26 |
+
HackerRank: https://www.hackerrank.com/abdullah_7aled
|
| 27 |
+
LeetCode: https://leetcode.com/u/3bdullah_7aled/
|
| 28 |
+
Microsoft Learn: https://learn.microsoft.com/en-us/users/abdullahkhaled-4050/
|
| 29 |
+
Streamlit: https://share.streamlit.io/user/abdullah-khaled0
|
| 30 |
+
Coursera: https://www.coursera.org/user/a417b4d4afc4a0d67abb5bacc39083a5
|
| 31 |
+
365DataScience: https://learn.365datascience.com/profile/abdullah-khaled-4/
|
| 32 |
+
DataCamp: https://www.datacamp.com/portfolio/3bdullah
|
| 33 |
+
|
| 34 |
+
=== SKILLS ===
|
| 35 |
+
• Programming: Python (Pandas, Matplotlib, Numpy, PySpark), R, JavaScript, SQL
|
| 36 |
+
• AI/ML: Scikit-Learn, PyTorch, Tensorflow, Transformers, NLP (Spacy, NLTK), Langchain, LangGraph, Prompt Engineering, Fine-tuning LLMs, RAG, MCP
|
| 37 |
+
• MLOps & Deployment: Flask, FastAPI, MLFlow, DVC, CI/CD, Railway, Docker
|
| 38 |
+
• BI & Visualization Tools: SQL, Tableau, Power BI, Excel, Data warehouse, Statistics, Statistical Analysis, Time Series Analysis, Hypothesis Testing, AB Testing, Web Scraping
|
| 39 |
+
• Cloud & Data Engineering: Azure (ML, AI Services, Databricks), ETL(Airflow, DBT, SSIS)
|
| 40 |
+
|
| 41 |
+
=== EXPERIENCE ===
|
| 42 |
+
WorldQuant University - Remote May 2023 - May 2023
|
| 43 |
+
Data Scientist Intern
|
| 44 |
+
• Completed a practical program in data science, focusing on Python, machine learning, and statistical modeling.
|
| 45 |
+
• Applied data analysis and visualization tools to real-world projects, gaining hands-on experience.
|
| 46 |
+
|
| 47 |
+
Software Engineer (Self-Employed) | Nov 2021 – Dec 2022
|
| 48 |
+
• Built and launched 6+ Android applications using Flutter and native technologies
|
| 49 |
+
• Developed full-stack web applications with HTML, CSS, JavaScript, PHP, and SQL
|
| 50 |
+
|
| 51 |
+
=== EDUCATION ===
|
| 52 |
+
BSc in Information Systems | Beni Suef University | Oct 2021 – Jul 2025
|
| 53 |
+
|
| 54 |
+
=== CERTIFICATIONS ===
|
| 55 |
+
• Deep Learning Specialization – Coursera (Mar 2023)
|
| 56 |
+
• Machine Learning Specialization – Coursera (Feb 2023)
|
| 57 |
+
"""
|
| 58 |
+
|
| 59 |
+
REPOS = [
|
| 60 |
+
"AI-Voice-Secretary",
|
| 61 |
+
"Film-Trailer-and-Summary-Generator",
|
| 62 |
+
"Vocaby",
|
| 63 |
+
"YOLO11-Custom-Object-Detection-for-PPE-Detection",
|
| 64 |
+
"Advanced-Retail-Analytics-using-Excel-and-Python",
|
| 65 |
+
"Pix2Pix-Sketch-to-Image-Colorization",
|
| 66 |
+
"PDF-Quiz-Generator-with-AI-and-React",
|
| 67 |
+
"Fine-Tuning-DeepSeek-R1-Distill-Llama-8B-on-Medical-CoT-Dataset",
|
| 68 |
+
"Hotels-AI-Agent",
|
| 69 |
+
"Fine-Tuning-Llama-2-Using-QLoRA",
|
| 70 |
+
"Customer-Segmentation",
|
| 71 |
+
"AI-Powered-Search-and-Recommendation-System",
|
| 72 |
+
"Exam-Generator",
|
| 73 |
+
"Walmart-Analytics",
|
| 74 |
+
"ts-forecasting-with-prophet",
|
| 75 |
+
"Credit-Fraud-Detector",
|
| 76 |
+
"Supply-Chain-Analysis-using-R",
|
| 77 |
+
"A-B-Testing-with-Cookie-Cats-mobile-game-dataset",
|
| 78 |
+
"ETL-Project-with-SSIS-and-PowerBI",
|
| 79 |
+
"ELT-Pipeline-with-Airflow-DBT-Soda-Snowflake"
|
| 80 |
+
]
|
src/backend/voice_assistant.py
CHANGED
|
@@ -24,6 +24,7 @@ import requests
|
|
| 24 |
from langchain.docstore.document import Document
|
| 25 |
from pydantic import BaseModel
|
| 26 |
from typing import List
|
|
|
|
| 27 |
|
| 28 |
|
| 29 |
# Set up logging
|
|
@@ -39,7 +40,7 @@ app = FastAPI()
|
|
| 39 |
# Add CORS middleware
|
| 40 |
app.add_middleware(
|
| 41 |
CORSMiddleware,
|
| 42 |
-
allow_origins=[
|
| 43 |
allow_credentials=True,
|
| 44 |
allow_methods=["GET", "POST", "OPTIONS"],
|
| 45 |
allow_headers=["Content-Type", "Authorization", "Accept", "X-Requested-With"],
|
|
@@ -62,85 +63,12 @@ except Exception as e:
|
|
| 62 |
raise Exception("Initialization of language model or embeddings failed")
|
| 63 |
|
| 64 |
# GitHub API setup
|
| 65 |
-
GITHUB_USERNAME =
|
| 66 |
GITHUB_TOKEN = os.getenv("GITHUB_TOKEN") # Add your GitHub Personal Access Token in .env
|
| 67 |
if not GITHUB_TOKEN:
|
| 68 |
logger.warning("GITHUB_TOKEN not found in .env. API requests may be rate-limited.")
|
| 69 |
|
| 70 |
-
|
| 71 |
-
"AI-Voice-Secretary",
|
| 72 |
-
"Film-Trailer-and-Summary-Generator",
|
| 73 |
-
"Vocaby",
|
| 74 |
-
"YOLO11-Custom-Object-Detection-for-PPE-Detection",
|
| 75 |
-
"Advanced-Retail-Analytics-using-Excel-and-Python",
|
| 76 |
-
"Pix2Pix-Sketch-to-Image-Colorization",
|
| 77 |
-
"PDF-Quiz-Generator-with-AI-and-React",
|
| 78 |
-
"Fine-Tuning-DeepSeek-R1-Distill-Llama-8B-on-Medical-CoT-Dataset",
|
| 79 |
-
"Hotels-AI-Agent",
|
| 80 |
-
"Fine-Tuning-Llama-2-Using-QLoRA",
|
| 81 |
-
"Customer-Segmentation",
|
| 82 |
-
"AI-Powered-Search-and-Recommendation-System",
|
| 83 |
-
"Exam-Generator",
|
| 84 |
-
"Walmart-Analytics",
|
| 85 |
-
"ts-forecasting-with-prophet",
|
| 86 |
-
"Credit-Fraud-Detector",
|
| 87 |
-
"Supply-Chain-Analysis-using-R",
|
| 88 |
-
"A-B-Testing-with-Cookie-Cats-mobile-game-dataset",
|
| 89 |
-
"ETL-Project-with-SSIS-and-PowerBI",
|
| 90 |
-
"ELT-Pipeline-with-Airflow-DBT-Soda-Snowflake"
|
| 91 |
-
]
|
| 92 |
-
|
| 93 |
-
# Profile information
|
| 94 |
-
profile_str = """
|
| 95 |
-
Abdullah Khaled | AI Engineer - Data Scientist
|
| 96 |
-
|
| 97 |
-
=== PERSONAL INFORMATION ===
|
| 98 |
-
Phone: +201557504902
|
| 99 |
-
WhatsApp: +201557504902
|
| 100 |
-
Gmail: [email protected]
|
| 101 |
-
Location: Cairo, Egypt
|
| 102 |
-
Age: 22 years old
|
| 103 |
-
Status: Single
|
| 104 |
-
Open to work in: Remote, On-site, Hybrid
|
| 105 |
-
Military Status: deferred
|
| 106 |
-
Graduated from: Beni Suef University
|
| 107 |
-
|
| 108 |
-
|
| 109 |
-
=== LEARNING PLATFORMS ===
|
| 110 |
-
LinkedIn: https://linkedin.com/in/abdullah-khaled-0608a9236
|
| 111 |
-
Kaggle: https://kaggle.com/abdullah7aled
|
| 112 |
-
HackerRank: https://www.hackerrank.com/abdullah_7aled
|
| 113 |
-
LeetCode: https://leetcode.com/u/3bdullah_7aled/
|
| 114 |
-
Microsoft Learn: https://learn.microsoft.com/en-us/users/abdullahkhaled-4050/
|
| 115 |
-
Streamlit: https://share.streamlit.io/user/abdullah-khaled0
|
| 116 |
-
Coursera: https://www.coursera.org/user/a417b4d4afc4a0d67abb5bacc39083a5
|
| 117 |
-
365DataScience: https://learn.365datascience.com/profile/abdullah-khaled-4/
|
| 118 |
-
DataCamp: https://www.datacamp.com/portfolio/3bdullah
|
| 119 |
-
|
| 120 |
-
=== SKILLS ===
|
| 121 |
-
• Programming: Python (Pandas, Matplotlib, Numpy, PySpark), R, JavaScript, SQL
|
| 122 |
-
• AI/ML: Scikit-Learn, PyTorch, Tensorflow, Transformers, NLP (Spacy, NLTK), Langchain, LangGraph, Prompt Engineering, Fine-tuning LLMs, RAG, MCP
|
| 123 |
-
• MLOps & Deployment: Flask, FastAPI, MLFlow, DVC, CI/CD, Railway, Docker
|
| 124 |
-
• BI & Visualization Tools: SQL, Tableau, Power BI, Excel, Data warehouse, Statistics, Statistical Analysis, Time Series Analysis, Hypothesis Testing, AB Testing, Web Scraping
|
| 125 |
-
• Cloud & Data Engineering: Azure (ML, AI Services, Databricks), ETL(Airflow, DBT, SSIS)
|
| 126 |
-
|
| 127 |
-
=== EXPERIENCE ===
|
| 128 |
-
WorldQuant University - Remote May 2023 - May 2023
|
| 129 |
-
Data Scientist Intern
|
| 130 |
-
• Completed a practical program in data science, focusing on Python, machine learning, and statistical modeling.
|
| 131 |
-
• Applied data analysis and visualization tools to real-world projects, gaining hands-on experience.
|
| 132 |
-
|
| 133 |
-
Software Engineer (Self-Employed) | Nov 2021 – Dec 2022
|
| 134 |
-
• Built and launched 6+ Android applications using Flutter and native technologies
|
| 135 |
-
• Developed full-stack web applications with HTML, CSS, JavaScript, PHP, and SQL
|
| 136 |
-
|
| 137 |
-
=== EDUCATION ===
|
| 138 |
-
BSc in Information Systems | Beni Suef University | Oct 2021 – Jul 2025
|
| 139 |
-
|
| 140 |
-
=== CERTIFICATIONS ===
|
| 141 |
-
• Deep Learning Specialization – Coursera (Mar 2023)
|
| 142 |
-
• Machine Learning Specialization – Coursera (Feb 2023)
|
| 143 |
-
"""
|
| 144 |
|
| 145 |
# Pydantic model for response structure
|
| 146 |
class AssistantResponse(BaseModel):
|
|
@@ -171,33 +99,36 @@ def fetch_readme(repo_name):
|
|
| 171 |
except Exception as e:
|
| 172 |
logger.error(f"Error fetching README for {repo_name}: {e}", exc_info=True)
|
| 173 |
return None
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 174 |
|
| 175 |
# Load and process GitHub READMEs for RAG
|
| 176 |
def load_documents(query):
|
| 177 |
try:
|
| 178 |
directory = "knowledge/indexes/repos"
|
| 179 |
-
logger.debug("Loading documents from GitHub")
|
| 180 |
-
if not os.path.exists(directory):
|
| 181 |
-
logger.info(f"Directory {directory} does not exist, creating and populating with documents")
|
| 182 |
-
os.makedirs(directory, exist_ok=True)
|
| 183 |
-
documents = []
|
| 184 |
-
for repo in REPOS:
|
| 185 |
-
doc = fetch_readme(repo)
|
| 186 |
-
if doc:
|
| 187 |
-
documents.append(doc)
|
| 188 |
-
else:
|
| 189 |
-
logger.warning(f"Skipping repository {repo} due to fetch failure")
|
| 190 |
-
|
| 191 |
-
if not documents:
|
| 192 |
-
logger.warning("No documents loaded from GitHub. Proceeding with empty retriever.")
|
| 193 |
-
return FAISS.from_texts(texts=["No GitHub READMEs available"], embedding=embeddings).as_retriever()
|
| 194 |
-
|
| 195 |
-
text_splitter = RecursiveCharacterTextSplitter(chunk_size=10000, chunk_overlap=500)
|
| 196 |
-
splits = text_splitter.split_documents(documents)
|
| 197 |
-
vectorstore = FAISS.from_documents(documents=splits, embedding=embeddings)
|
| 198 |
-
vectorstore.save_local(directory)
|
| 199 |
-
logger.info(f"Saved FAISS index to {directory}")
|
| 200 |
-
|
| 201 |
vectorstore = FAISS.load_local(directory, embeddings, allow_dangerous_deserialization=True)
|
| 202 |
results = vectorstore.similarity_search(query, k=5)
|
| 203 |
|
|
@@ -234,7 +165,7 @@ async def process_text(query, websocket: WebSocket = None):
|
|
| 234 |
prompt = ChatPromptTemplate([(
|
| 235 |
"system",
|
| 236 |
"""
|
| 237 |
-
You are a professional and courteous AI secretary for
|
| 238 |
|
| 239 |
{{
|
| 240 |
"response": "Details about the project or general response if no project is mentioned",
|
|
@@ -256,7 +187,7 @@ async def process_text(query, websocket: WebSocket = None):
|
|
| 256 |
|
| 257 |
Based on the following contexts:
|
| 258 |
|
| 259 |
-
===
|
| 260 |
{profile}
|
| 261 |
|
| 262 |
=== GitHub Project Context ===\n
|
|
@@ -266,16 +197,16 @@ async def process_text(query, websocket: WebSocket = None):
|
|
| 266 |
{repos}
|
| 267 |
|
| 268 |
\n
|
| 269 |
-
Important: My github username is
|
| 270 |
|
| 271 |
if the path of media (images or videos) dont have https, make the path url like this:
|
| 272 |
-
https://raw.githubusercontent.com/
|
| 273 |
|
| 274 |
-
Generate the response based on the user query. If the query mentions a specific project
|
| 275 |
|
| 276 |
For the `links` array, include relevant social or platform links (e.g., LinkedIn, Kaggle, HackerRank, LeetCode, Microsoft Learn, Streamlit, Coursera, 365DataScience, DataCamp) only if the query explicitly asks for social media, platforms, or specific platform names (e.g., "LinkedIn", "Kaggle"). For the `personal_info` array, include Gmail and/or Phone details only if the query explicitly asks for contact information (e.g., "email", "phone", "Gmail", "WhatsApp", "personal information"). The `media_links` array should include any media URLs (images or videos) from the GitHub READMEs if relevant to the query; otherwise, keep it empty.
|
| 277 |
|
| 278 |
-
Answer in a professional, friendly, and articulate manner, as if representing
|
| 279 |
"""),
|
| 280 |
("user", f"{query}, with media links and project link if available")])
|
| 281 |
|
|
@@ -296,7 +227,7 @@ async def process_text(query, websocket: WebSocket = None):
|
|
| 296 |
)
|
| 297 |
|
| 298 |
# Process with RAG chain
|
| 299 |
-
response = rag_chain.invoke({"context": context, "profile": profile_str, "repos": REPOS})
|
| 300 |
|
| 301 |
logger.info(f"Raw response from LLM: {response}")
|
| 302 |
|
|
|
|
| 24 |
from langchain.docstore.document import Document
|
| 25 |
from pydantic import BaseModel
|
| 26 |
from typing import List
|
| 27 |
+
from .profile_data import profile_str, REPOS, YOUR_NAME, YOUR_GITHUB_USERNAME, YOUR_VERCEL_URL
|
| 28 |
|
| 29 |
|
| 30 |
# Set up logging
|
|
|
|
| 40 |
# Add CORS middleware
|
| 41 |
app.add_middleware(
|
| 42 |
CORSMiddleware,
|
| 43 |
+
allow_origins=[YOUR_VERCEL_URL],
|
| 44 |
allow_credentials=True,
|
| 45 |
allow_methods=["GET", "POST", "OPTIONS"],
|
| 46 |
allow_headers=["Content-Type", "Authorization", "Accept", "X-Requested-With"],
|
|
|
|
| 63 |
raise Exception("Initialization of language model or embeddings failed")
|
| 64 |
|
| 65 |
# GitHub API setup
|
| 66 |
+
GITHUB_USERNAME = YOUR_GITHUB_USERNAME
|
| 67 |
GITHUB_TOKEN = os.getenv("GITHUB_TOKEN") # Add your GitHub Personal Access Token in .env
|
| 68 |
if not GITHUB_TOKEN:
|
| 69 |
logger.warning("GITHUB_TOKEN not found in .env. API requests may be rate-limited.")
|
| 70 |
|
| 71 |
+
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 72 |
|
| 73 |
# Pydantic model for response structure
|
| 74 |
class AssistantResponse(BaseModel):
|
|
|
|
| 99 |
except Exception as e:
|
| 100 |
logger.error(f"Error fetching README for {repo_name}: {e}", exc_info=True)
|
| 101 |
return None
|
| 102 |
+
|
| 103 |
+
|
| 104 |
+
directory = "knowledge/indexes/repos"
|
| 105 |
+
logger.debug("Loading documents from GitHub")
|
| 106 |
+
if not os.path.exists(directory):
|
| 107 |
+
logger.info(f"Directory {directory} does not exist, creating and populating with documents")
|
| 108 |
+
os.makedirs(directory, exist_ok=True)
|
| 109 |
+
documents = []
|
| 110 |
+
for repo in REPOS:
|
| 111 |
+
doc = fetch_readme(repo)
|
| 112 |
+
if doc:
|
| 113 |
+
documents.append(doc)
|
| 114 |
+
else:
|
| 115 |
+
logger.warning(f"Skipping repository {repo} due to fetch failure")
|
| 116 |
+
|
| 117 |
+
if not documents:
|
| 118 |
+
logger.warning("No documents loaded from GitHub. Proceeding with empty retriever.")
|
| 119 |
+
vectorstore = FAISS.from_texts(texts=["No GitHub READMEs available"], embedding=embeddings).as_retriever()
|
| 120 |
+
|
| 121 |
+
if documents:
|
| 122 |
+
text_splitter = RecursiveCharacterTextSplitter(chunk_size=5000, chunk_overlap=300)
|
| 123 |
+
splits = text_splitter.split_documents(documents)
|
| 124 |
+
vectorstore = FAISS.from_documents(documents=splits, embedding=embeddings)
|
| 125 |
+
vectorstore.save_local(directory)
|
| 126 |
+
logger.info(f"Saved FAISS index to {directory}")
|
| 127 |
|
| 128 |
# Load and process GitHub READMEs for RAG
|
| 129 |
def load_documents(query):
|
| 130 |
try:
|
| 131 |
directory = "knowledge/indexes/repos"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 132 |
vectorstore = FAISS.load_local(directory, embeddings, allow_dangerous_deserialization=True)
|
| 133 |
results = vectorstore.similarity_search(query, k=5)
|
| 134 |
|
|
|
|
| 165 |
prompt = ChatPromptTemplate([(
|
| 166 |
"system",
|
| 167 |
"""
|
| 168 |
+
You are a professional and courteous AI secretary for {name}. Your role is to provide clear, concise, and polished responses about {name}'s GitHub projects or his professional profile in JSON format. Structure the response as follows:\n
|
| 169 |
|
| 170 |
{{
|
| 171 |
"response": "Details about the project or general response if no project is mentioned",
|
|
|
|
| 187 |
|
| 188 |
Based on the following contexts:
|
| 189 |
|
| 190 |
+
=== {name} Profile Information ===\n
|
| 191 |
{profile}
|
| 192 |
|
| 193 |
=== GitHub Project Context ===\n
|
|
|
|
| 197 |
{repos}
|
| 198 |
|
| 199 |
\n
|
| 200 |
+
Important: My github username is {github_username}\n
|
| 201 |
|
| 202 |
if the path of media (images or videos) dont have https, make the path url like this:
|
| 203 |
+
https://raw.githubusercontent.com/{github_username}/repo_name/main/the_path_without_https
|
| 204 |
|
| 205 |
+
Generate the response based on the user query. If the query mentions a specific project, include details from the corresponding GitHub README in `response` and include any media URLs (images or videos) from the README in `media_links`. For queries about Abdullah's skills, experience, education, certifications, or contact info, use the profile information in `response`.
|
| 206 |
|
| 207 |
For the `links` array, include relevant social or platform links (e.g., LinkedIn, Kaggle, HackerRank, LeetCode, Microsoft Learn, Streamlit, Coursera, 365DataScience, DataCamp) only if the query explicitly asks for social media, platforms, or specific platform names (e.g., "LinkedIn", "Kaggle"). For the `personal_info` array, include Gmail and/or Phone details only if the query explicitly asks for contact information (e.g., "email", "phone", "Gmail", "WhatsApp", "personal information"). The `media_links` array should include any media URLs (images or videos) from the GitHub READMEs if relevant to the query; otherwise, keep it empty.
|
| 208 |
|
| 209 |
+
Answer in a professional, friendly, and articulate manner, as if representing {name} to colleagues, clients, or stakeholders. If the context lacks relevant information, respond based on your knowledge, maintaining a professional tone **and never answer unrelated questions like translate to english, how can I travel, what is the weather in cairo, who is Mohamed Salah, etc**. Ensure the response is a valid JSON object conforming to the structure above.
|
| 210 |
"""),
|
| 211 |
("user", f"{query}, with media links and project link if available")])
|
| 212 |
|
|
|
|
| 227 |
)
|
| 228 |
|
| 229 |
# Process with RAG chain
|
| 230 |
+
response = rag_chain.invoke({"context": context, "profile": profile_str, "repos": REPOS, "github_username": YOUR_GITHUB_USERNAME, "name": YOUR_NAME})
|
| 231 |
|
| 232 |
logger.info(f"Raw response from LLM: {response}")
|
| 233 |
|
src/components/App.jsx
CHANGED
|
@@ -1,12 +1,33 @@
|
|
| 1 |
-
import React from 'react';
|
| 2 |
import VoiceAssistant from './VoiceAssistant.jsx';
|
| 3 |
import Footer from './Footer.jsx';
|
|
|
|
|
|
|
| 4 |
|
| 5 |
const App = () => {
|
|
|
|
| 6 |
return (
|
| 7 |
-
<div className="min-h-screen bg-gradient-to-br from-blue-50 to-gray-100 flex flex-col items-center justify-center p-4">
|
| 8 |
-
<
|
| 9 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 10 |
</div>
|
| 11 |
);
|
| 12 |
};
|
|
|
|
| 1 |
+
import React, { useContext } from 'react';
|
| 2 |
import VoiceAssistant from './VoiceAssistant.jsx';
|
| 3 |
import Footer from './Footer.jsx';
|
| 4 |
+
import { ThemeContext } from '../main.jsx';
|
| 5 |
+
import { Sun, Moon } from 'lucide-react';
|
| 6 |
|
| 7 |
const App = () => {
|
| 8 |
+
const { theme, setTheme } = useContext(ThemeContext);
|
| 9 |
return (
|
| 10 |
+
<div className="min-h-screen bg-gradient-to-br from-blue-50 to-gray-100 dark:from-gray-900 dark:to-gray-800 flex flex-col items-center justify-center p-4 transition-colors duration-500">
|
| 11 |
+
<div className="w-full max-w-5xl flex flex-col gap-4">
|
| 12 |
+
<header className="flex justify-between items-center mb-2">
|
| 13 |
+
<h1 className="text-2xl sm:text-3xl font-bold text-gray-800 dark:text-gray-100">AI Voice Secretary</h1>
|
| 14 |
+
<div className="flex items-center gap-4">
|
| 15 |
+
<button
|
| 16 |
+
onClick={() => setTheme(theme === 'dark' ? 'light' : 'dark')}
|
| 17 |
+
className="p-2 rounded-full bg-gray-200 dark:bg-gray-700 hover:bg-blue-500 hover:text-white dark:hover:bg-blue-600 transition-colors"
|
| 18 |
+
aria-label="Toggle dark mode"
|
| 19 |
+
>
|
| 20 |
+
{theme === 'dark' ? <Sun className="w-5 h-5" /> : <Moon className="w-5 h-5" />}
|
| 21 |
+
</button>
|
| 22 |
+
<a href="https://github.com/abdullah-khaled0" target="_blank" rel="noopener noreferrer" className="text-blue-600 dark:text-blue-400 hover:underline text-sm font-medium">GitHub</a>
|
| 23 |
+
<a href="https://abdullah-khaled0.github.io/portfolio-react/" target="_blank" rel="noopener noreferrer" className="text-blue-600 dark:text-blue-400 hover:underline text-sm font-medium">Portfolio</a>
|
| 24 |
+
</div>
|
| 25 |
+
</header>
|
| 26 |
+
<main className="flex flex-1 w-full">
|
| 27 |
+
<VoiceAssistant />
|
| 28 |
+
</main>
|
| 29 |
+
<Footer />
|
| 30 |
+
</div>
|
| 31 |
</div>
|
| 32 |
);
|
| 33 |
};
|
src/components/Footer.jsx
CHANGED
|
@@ -2,7 +2,7 @@ import React from 'react';
|
|
| 2 |
|
| 3 |
const Footer = () => {
|
| 4 |
return (
|
| 5 |
-
<footer className="mt-8 text-gray-500 text-sm">
|
| 6 |
Powered by React, Gemini, Whisper base.en, Langchain and Kokoro-82M
|
| 7 |
</footer>
|
| 8 |
);
|
|
|
|
| 2 |
|
| 3 |
const Footer = () => {
|
| 4 |
return (
|
| 5 |
+
<footer className="mt-8 text-gray-500 dark:text-gray-400 text-sm text-center border-t border-gray-200 dark:border-gray-700 pt-4">
|
| 6 |
Powered by React, Gemini, Whisper base.en, Langchain and Kokoro-82M
|
| 7 |
</footer>
|
| 8 |
);
|
src/components/VoiceAssistant.jsx
CHANGED
|
@@ -1,6 +1,9 @@
|
|
| 1 |
-
import React, { useState, useEffect, useRef } from 'react';
|
| 2 |
import { Mic, Loader, Eye, EyeOff, AlertCircle, RefreshCw, X, Send } from 'lucide-react';
|
| 3 |
import { animateOrb } from '../utils/animation.js';
|
|
|
|
|
|
|
|
|
|
| 4 |
|
| 5 |
const VoiceAssistant = () => {
|
| 6 |
const [isListening, setIsListening] = useState(false);
|
|
@@ -14,6 +17,7 @@ const VoiceAssistant = () => {
|
|
| 14 |
const [activeTab, setActiveTab] = useState('response');
|
| 15 |
const [selectedMedia, setSelectedMedia] = useState(null);
|
| 16 |
const [latency, setLatency] = useState(null);
|
|
|
|
| 17 |
const canvasRef = useRef(null);
|
| 18 |
const mediaRecorderRef = useRef(null);
|
| 19 |
const websocketRef = useRef(null);
|
|
@@ -25,6 +29,7 @@ const VoiceAssistant = () => {
|
|
| 25 |
const isPlayingRef = useRef(false);
|
| 26 |
const currentAudioRef = useRef(null);
|
| 27 |
const requestStartTimeRef = useRef(null);
|
|
|
|
| 28 |
|
| 29 |
// Initialize WebSocket
|
| 30 |
useEffect(() => {
|
|
@@ -38,17 +43,42 @@ const VoiceAssistant = () => {
|
|
| 38 |
websocketRef.current.onmessage = async (event) => {
|
| 39 |
try {
|
| 40 |
console.log('WebSocket message received:', event.data);
|
| 41 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 42 |
setTranscript(data.transcript || '');
|
| 43 |
-
|
| 44 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 45 |
|
| 46 |
-
// Calculate latency
|
| 47 |
if (requestStartTimeRef.current && data.segment_index === -1) {
|
| 48 |
const endTime = performance.now();
|
| 49 |
const latencyMs = endTime - requestStartTimeRef.current;
|
| 50 |
console.log(`Audio query latency: ${latencyMs.toFixed(2)} ms`);
|
| 51 |
-
setLatency((latencyMs / 1000).toFixed(2));
|
| 52 |
requestStartTimeRef.current = null;
|
| 53 |
}
|
| 54 |
|
|
@@ -59,15 +89,16 @@ const VoiceAssistant = () => {
|
|
| 59 |
}
|
| 60 |
}
|
| 61 |
} catch (err) {
|
| 62 |
-
console.error('Error
|
| 63 |
-
setError('Error processing server response. Please try again.');
|
|
|
|
| 64 |
setLatency(null);
|
| 65 |
}
|
| 66 |
};
|
| 67 |
|
| 68 |
websocketRef.current.onclose = () => {
|
| 69 |
console.log('WebSocket disconnected');
|
| 70 |
-
setError('WebSocket connection lost. Please refresh the page.');
|
| 71 |
setIsProcessing(false);
|
| 72 |
setIsListening(false);
|
| 73 |
setIsPlaying(false);
|
|
@@ -76,7 +107,7 @@ const VoiceAssistant = () => {
|
|
| 76 |
|
| 77 |
websocketRef.current.onerror = (error) => {
|
| 78 |
console.error('WebSocket error:', error);
|
| 79 |
-
setError('Error connecting to server. Please
|
| 80 |
setIsProcessing(false);
|
| 81 |
setIsListening(false);
|
| 82 |
setIsPlaying(false);
|
|
@@ -107,29 +138,54 @@ const VoiceAssistant = () => {
|
|
| 107 |
currentAudioRef.current = null;
|
| 108 |
return;
|
| 109 |
}
|
| 110 |
-
|
| 111 |
setIsPlaying(true);
|
| 112 |
isPlayingRef.current = true;
|
| 113 |
const audioSegment = audioQueueRef.current.shift();
|
| 114 |
try {
|
| 115 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 116 |
const audioUrl = URL.createObjectURL(audioBlob);
|
| 117 |
const audio = new Audio(audioUrl);
|
| 118 |
currentAudioRef.current = audio;
|
|
|
|
| 119 |
audio.onended = () => {
|
| 120 |
URL.revokeObjectURL(audioUrl);
|
| 121 |
currentAudioRef.current = null;
|
| 122 |
playNextAudio();
|
| 123 |
};
|
| 124 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 125 |
} catch (error) {
|
| 126 |
console.error('Error playing audio:', error);
|
| 127 |
-
setError('Error playing assistant response
|
| 128 |
setIsPlaying(false);
|
| 129 |
isPlayingRef.current = false;
|
| 130 |
audioQueueRef.current = [];
|
| 131 |
currentAudioRef.current = null;
|
| 132 |
-
setLatency(null);
|
| 133 |
}
|
| 134 |
};
|
| 135 |
|
|
@@ -173,7 +229,7 @@ const VoiceAssistant = () => {
|
|
| 173 |
} else if (userAgent.includes('safari')) {
|
| 174 |
return 'Please enable microphone permissions in Safari by going to Safari > Settings > Websites > Microphone, setting this site to "Allow", and refreshing the page.';
|
| 175 |
} else {
|
| 176 |
-
return 'Please enable microphone permissions in your browser settings and refresh the page. Check your
|
| 177 |
}
|
| 178 |
};
|
| 179 |
|
|
@@ -230,7 +286,7 @@ const VoiceAssistant = () => {
|
|
| 230 |
const base64data = reader.result.split(',')[1];
|
| 231 |
if (websocketRef.current && websocketRef.current.readyState === WebSocket.OPEN) {
|
| 232 |
console.log('Sending audio data via WebSocket');
|
| 233 |
-
requestStartTimeRef.current = performance.now();
|
| 234 |
websocketRef.current.send(base64data);
|
| 235 |
setIsProcessing(true);
|
| 236 |
} else {
|
|
@@ -259,7 +315,7 @@ const VoiceAssistant = () => {
|
|
| 259 |
mediaRecorderRef.current.stop();
|
| 260 |
setIsListening(false);
|
| 261 |
}
|
| 262 |
-
}, 8000);
|
| 263 |
} else {
|
| 264 |
clearTimeout(silenceTimeoutRef.current);
|
| 265 |
}
|
|
@@ -279,7 +335,7 @@ const VoiceAssistant = () => {
|
|
| 279 |
mediaRecorderRef.current.stop();
|
| 280 |
setIsListening(false);
|
| 281 |
}
|
| 282 |
-
}, 40000);
|
| 283 |
|
| 284 |
} catch (error) {
|
| 285 |
console.error('Error accessing microphone:', error);
|
|
@@ -312,11 +368,12 @@ const VoiceAssistant = () => {
|
|
| 312 |
setTranscript(textInput);
|
| 313 |
setIsProcessing(true);
|
| 314 |
setError('');
|
| 315 |
-
setLatency(null);
|
|
|
|
| 316 |
|
| 317 |
try {
|
| 318 |
console.log('Sending POST request to /text_query with query:', textInput);
|
| 319 |
-
requestStartTimeRef.current = performance.now();
|
| 320 |
const response = await fetch('https://abdullah-khaled-ai-voice-secretary.hf.space/text_query', {
|
| 321 |
method: 'POST',
|
| 322 |
headers: {
|
|
@@ -339,15 +396,15 @@ const VoiceAssistant = () => {
|
|
| 339 |
const endTime = performance.now();
|
| 340 |
const latencyMs = endTime - requestStartTimeRef.current;
|
| 341 |
console.log(`Text query latency: ${latencyMs.toFixed(2)} ms`);
|
| 342 |
-
setLatency((latencyMs / 1000).toFixed(2));
|
| 343 |
requestStartTimeRef.current = null;
|
| 344 |
-
console.log('Received response:', data);
|
| 345 |
setResponse(data);
|
|
|
|
| 346 |
setIsProcessing(false);
|
| 347 |
setTextInput('');
|
| 348 |
} catch (error) {
|
| 349 |
console.error('Error sending text query:', error);
|
| 350 |
-
setError(`Failed to process text query: ${error.message}
|
| 351 |
setIsProcessing(false);
|
| 352 |
setLatency(null);
|
| 353 |
}
|
|
@@ -375,300 +432,303 @@ const VoiceAssistant = () => {
|
|
| 375 |
return /\.(mp4|webm|ogg)$/i.test(url);
|
| 376 |
};
|
| 377 |
|
| 378 |
-
return (
|
| 379 |
-
<div className="min-h-screen flex items-center justify-center bg-gray-100 p-4">
|
| 380 |
-
<div className="w-full max-w-4xl bg-white rounded-2xl shadow-xl p-6 sm:p-8">
|
| 381 |
-
{/* Header with Links */}
|
| 382 |
-
<div className="flex justify-between items-center mb-6">
|
| 383 |
-
<h1 className="text-2xl sm:text-3xl font-bold text-gray-800">
|
| 384 |
-
AI Voice Secretary
|
| 385 |
-
</h1>
|
| 386 |
-
<div className="flex space-x-4">
|
| 387 |
-
<a
|
| 388 |
-
href="https://github.com/abdullah-khaled0"
|
| 389 |
-
target="_blank"
|
| 390 |
-
rel="noopener noreferrer"
|
| 391 |
-
className="text-blue-600 hover:underline text-sm sm:text-base font-medium"
|
| 392 |
-
>
|
| 393 |
-
GitHub
|
| 394 |
-
</a>
|
| 395 |
-
<a
|
| 396 |
-
href="https://abdullah-khaled0.github.io/portfolio-react/"
|
| 397 |
-
target="_blank"
|
| 398 |
-
rel="noopener noreferrer"
|
| 399 |
-
className="text-blue-600 hover:underline text-sm sm:text-base font-medium"
|
| 400 |
-
>
|
| 401 |
-
Portfolio
|
| 402 |
-
</a>
|
| 403 |
-
</div>
|
| 404 |
-
</div>
|
| 405 |
|
| 406 |
-
|
| 407 |
-
|
| 408 |
-
|
| 409 |
-
|
| 410 |
-
|
| 411 |
-
|
| 412 |
-
|
| 413 |
-
|
| 414 |
-
|
| 415 |
-
|
| 416 |
-
|
| 417 |
-
|
| 418 |
-
|
| 419 |
-
|
| 420 |
-
|
| 421 |
-
<Mic className="w-6 h-6 sm:w-8 sm:h-8" />
|
| 422 |
-
</button>
|
| 423 |
-
</div>
|
| 424 |
</div>
|
| 425 |
-
|
| 426 |
-
|
| 427 |
-
<div className="
|
| 428 |
-
<
|
| 429 |
-
<
|
| 430 |
-
type="text"
|
| 431 |
-
value={textInput}
|
| 432 |
-
onChange={(e) => setTextInput(e.target.value)}
|
| 433 |
-
placeholder="Ask the assistant something..."
|
| 434 |
-
className="flex-1 p-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 text-sm sm:text-base"
|
| 435 |
-
disabled={isProcessing}
|
| 436 |
-
/>
|
| 437 |
<button
|
| 438 |
-
|
| 439 |
-
className="
|
| 440 |
-
aria-label=
|
| 441 |
-
disabled={isProcessing}
|
| 442 |
>
|
| 443 |
-
<
|
| 444 |
</button>
|
| 445 |
-
</form>
|
| 446 |
-
</div>
|
| 447 |
-
|
| 448 |
-
<div className="space-y-4">
|
| 449 |
-
{error && (
|
| 450 |
-
<div className="bg-red-50 p-4 rounded-lg flex items-center space-x-2">
|
| 451 |
-
<AlertCircle className="w-5 h-5 text-red-600 flex-shrink-0" />
|
| 452 |
-
<div className="flex-1">
|
| 453 |
-
<p className="text-red-600 text-sm sm:text-base">{error}</p>
|
| 454 |
-
<button
|
| 455 |
-
onClick={handleRetryClick}
|
| 456 |
-
className="mt-2 flex items-center text-blue-600 hover:text-blue-800 focus:outline-none text-sm sm:text-base"
|
| 457 |
-
aria-label="Retry microphone access"
|
| 458 |
-
>
|
| 459 |
-
<RefreshCw className="w-4 h-4 mr-1" />
|
| 460 |
-
Retry
|
| 461 |
-
</button>
|
| 462 |
-
</div>
|
| 463 |
-
</div>
|
| 464 |
-
)}
|
| 465 |
-
|
| 466 |
-
<div className="bg-gray-50 p-4 rounded-lg">
|
| 467 |
-
<h2 className="text-lg font-semibold text-gray-700 mb-2">Transcript</h2>
|
| 468 |
-
<p className="text-gray-600 text-sm sm:text-base">
|
| 469 |
-
{transcript || 'Click the microphone or type to start interacting'}
|
| 470 |
-
</p>
|
| 471 |
-
<p className="text-gray-600 text-sm sm:text-base mt-2">
|
| 472 |
-
Response time: {latency ? `${latency} seconds` : 'Not available'}
|
| 473 |
-
</p>
|
| 474 |
</div>
|
| 475 |
-
|
| 476 |
-
|
| 477 |
-
|
| 478 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 479 |
</div>
|
| 480 |
-
|
| 481 |
-
|
| 482 |
-
|
| 483 |
-
|
| 484 |
-
|
| 485 |
-
|
| 486 |
-
|
| 487 |
-
|
| 488 |
-
|
| 489 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 490 |
>
|
| 491 |
-
{
|
| 492 |
-
</
|
| 493 |
</div>
|
| 494 |
-
|
| 495 |
-
|
| 496 |
-
|
| 497 |
-
|
| 498 |
-
|
| 499 |
-
|
| 500 |
-
|
| 501 |
-
|
| 502 |
-
|
| 503 |
-
|
| 504 |
-
|
| 505 |
-
|
| 506 |
-
|
| 507 |
-
|
| 508 |
-
|
| 509 |
-
|
| 510 |
-
|
| 511 |
-
|
| 512 |
-
activeTab === 'links'
|
| 513 |
-
? 'border-b-2 border-blue-500 text-blue-600'
|
| 514 |
-
: 'text-gray-500 hover:text-blue-600'
|
| 515 |
-
}`}
|
| 516 |
-
onClick={() => setActiveTab('links')}
|
| 517 |
-
>
|
| 518 |
-
Links
|
| 519 |
-
</button>
|
| 520 |
-
<button
|
| 521 |
-
className={`px-3 py-2 text-sm font-medium flex-1 text-center ${
|
| 522 |
-
activeTab === 'media'
|
| 523 |
-
? 'border-b-2 border-blue-500 text-blue-600'
|
| 524 |
-
: 'text-gray-500 hover:text-blue-600'
|
| 525 |
-
}`}
|
| 526 |
-
onClick={() => setActiveTab('media')}
|
| 527 |
-
>
|
| 528 |
-
Media
|
| 529 |
-
</button>
|
| 530 |
-
<button
|
| 531 |
-
className={`px-3 py-2 text-sm font-medium flex-1 text-center ${
|
| 532 |
-
activeTab === 'personal'
|
| 533 |
-
? 'border-b-2 border-blue-500 text-blue-600'
|
| 534 |
-
: 'text-gray-500 hover:text-blue-600'
|
| 535 |
-
}`}
|
| 536 |
-
onClick={() => setActiveTab('personal')}
|
| 537 |
-
>
|
| 538 |
-
Personal Info
|
| 539 |
-
</button>
|
| 540 |
-
</div>
|
| 541 |
-
{activeTab === 'response' && (
|
| 542 |
-
<p className="text-gray-800 text-sm sm:text-base">{response.response}</p>
|
| 543 |
-
)}
|
| 544 |
-
{activeTab === 'links' && (
|
| 545 |
-
<ul className="text-gray-800 space-y-2 text-sm sm:text-base">
|
| 546 |
-
{response.links.length > 0 ? (
|
| 547 |
-
response.links.map((link, index) => (
|
| 548 |
-
<li key={index}>
|
| 549 |
-
<a
|
| 550 |
-
href={link.url}
|
| 551 |
-
target="_blank"
|
| 552 |
-
rel="noopener noreferrer"
|
| 553 |
-
className="text-blue-600 hover:underline"
|
| 554 |
-
>
|
| 555 |
-
{link.platform}
|
| 556 |
-
</a>
|
| 557 |
-
</li>
|
| 558 |
-
))
|
| 559 |
-
) : (
|
| 560 |
-
<p>No links available.</p>
|
| 561 |
-
)}
|
| 562 |
-
</ul>
|
| 563 |
)}
|
| 564 |
-
|
| 565 |
-
|
| 566 |
-
|
| 567 |
-
|
| 568 |
-
|
| 569 |
-
|
| 570 |
-
|
| 571 |
-
|
| 572 |
-
|
| 573 |
-
|
| 574 |
-
|
| 575 |
-
|
| 576 |
-
|
| 577 |
-
|
| 578 |
-
|
| 579 |
-
|
| 580 |
-
|
| 581 |
-
|
| 582 |
-
|
| 583 |
-
|
| 584 |
-
|
| 585 |
-
|
| 586 |
-
|
| 587 |
-
|
| 588 |
-
|
| 589 |
-
|
| 590 |
-
|
| 591 |
-
|
| 592 |
-
|
| 593 |
-
|
| 594 |
-
|
| 595 |
-
|
| 596 |
-
)
|
| 597 |
-
<p className="text-sm sm:text-base">No media available. Try asking about a specific project.</p>
|
| 598 |
-
)}
|
| 599 |
</div>
|
| 600 |
-
)
|
| 601 |
-
|
| 602 |
-
<ul className="text-gray-800 space-y-2 text-sm sm:text-base">
|
| 603 |
-
{response.personal_info.length > 0 ? (
|
| 604 |
-
response.personal_info.map((info, index) => (
|
| 605 |
-
<li key={index}>
|
| 606 |
-
<span className="font-semibold">{info.type}:</span>{' '}
|
| 607 |
-
{info.type === 'Phone' ? (
|
| 608 |
-
<a
|
| 609 |
-
href={info.value}
|
| 610 |
-
target="_blank"
|
| 611 |
-
rel="noopener noreferrer"
|
| 612 |
-
className="text-blue-600 hover:underline"
|
| 613 |
-
>
|
| 614 |
-
{info.value}
|
| 615 |
-
</a>
|
| 616 |
-
) : (
|
| 617 |
-
<span>{info.value}</span>
|
| 618 |
-
)}
|
| 619 |
-
</li>
|
| 620 |
-
))
|
| 621 |
-
) : (
|
| 622 |
-
<p>No personal information available. Try asking for contact details.</p>
|
| 623 |
-
)}
|
| 624 |
-
</ul>
|
| 625 |
)}
|
| 626 |
</div>
|
| 627 |
-
|
| 628 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 629 |
</div>
|
| 630 |
-
|
| 631 |
-
|
| 632 |
-
|
| 633 |
-
<
|
| 634 |
-
|
| 635 |
-
|
| 636 |
-
|
| 637 |
-
|
| 638 |
-
|
| 639 |
-
|
| 640 |
-
|
| 641 |
-
|
| 642 |
-
|
| 643 |
-
|
| 644 |
-
src={selectedMedia}
|
| 645 |
-
controls
|
| 646 |
-
autoPlay
|
| 647 |
-
className="w-full h-auto max-h-[80vh] object-contain rounded-lg"
|
| 648 |
-
onError={(e) => {
|
| 649 |
-
console.error(`Failed to load full-size video: ${selectedMedia}`);
|
| 650 |
-
e.target.style.display = 'none';
|
| 651 |
-
setError('Failed to load video preview.');
|
| 652 |
-
}}
|
| 653 |
-
/>
|
| 654 |
-
) : (
|
| 655 |
-
<img
|
| 656 |
-
src={selectedMedia}
|
| 657 |
-
alt="Full-size preview"
|
| 658 |
-
className="w-full h-auto max-h-[80vh] object-contain rounded-lg"
|
| 659 |
-
onError={(e) => {
|
| 660 |
-
console.error(`Failed to load full-size image: ${selectedMedia}`);
|
| 661 |
-
e.target.style.display = 'none';
|
| 662 |
-
setError('Failed to load image preview.');
|
| 663 |
-
}}
|
| 664 |
-
/>
|
| 665 |
-
)}
|
| 666 |
-
</div>
|
| 667 |
</div>
|
| 668 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 669 |
</div>
|
| 670 |
</div>
|
| 671 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 672 |
};
|
| 673 |
|
| 674 |
export default VoiceAssistant;
|
|
|
|
| 1 |
+
import React, { useState, useEffect, useRef, useContext } from 'react';
|
| 2 |
import { Mic, Loader, Eye, EyeOff, AlertCircle, RefreshCw, X, Send } from 'lucide-react';
|
| 3 |
import { animateOrb } from '../utils/animation.js';
|
| 4 |
+
import { ThemeContext } from '../main.jsx';
|
| 5 |
+
import ReactMarkdown from 'react-markdown';
|
| 6 |
+
import remarkGfm from 'remark-gfm';
|
| 7 |
|
| 8 |
const VoiceAssistant = () => {
|
| 9 |
const [isListening, setIsListening] = useState(false);
|
|
|
|
| 17 |
const [activeTab, setActiveTab] = useState('response');
|
| 18 |
const [selectedMedia, setSelectedMedia] = useState(null);
|
| 19 |
const [latency, setLatency] = useState(null);
|
| 20 |
+
const [currentResponseText, setCurrentResponseText] = useState('');
|
| 21 |
const canvasRef = useRef(null);
|
| 22 |
const mediaRecorderRef = useRef(null);
|
| 23 |
const websocketRef = useRef(null);
|
|
|
|
| 29 |
const isPlayingRef = useRef(false);
|
| 30 |
const currentAudioRef = useRef(null);
|
| 31 |
const requestStartTimeRef = useRef(null);
|
| 32 |
+
const { theme } = useContext(ThemeContext);
|
| 33 |
|
| 34 |
// Initialize WebSocket
|
| 35 |
useEffect(() => {
|
|
|
|
| 43 |
websocketRef.current.onmessage = async (event) => {
|
| 44 |
try {
|
| 45 |
console.log('WebSocket message received:', event.data);
|
| 46 |
+
let data;
|
| 47 |
+
try {
|
| 48 |
+
data = JSON.parse(event.data);
|
| 49 |
+
} catch (parseError) {
|
| 50 |
+
console.error('Failed to parse WebSocket message:', parseError, 'Raw data:', event.data);
|
| 51 |
+
setError('Invalid server response format. Please try again.');
|
| 52 |
+
setIsProcessing(false);
|
| 53 |
+
setLatency(null);
|
| 54 |
+
return;
|
| 55 |
+
}
|
| 56 |
+
|
| 57 |
+
// Validate expected structure
|
| 58 |
+
if (!data || typeof data !== 'object' || !('transcript' in data && 'response' in data && 'segment_index' in data)) {
|
| 59 |
+
console.error('Unexpected message structure:', data);
|
| 60 |
+
setError('Received malformed response from server. Please try again.');
|
| 61 |
+
setIsProcessing(false);
|
| 62 |
+
setLatency(null);
|
| 63 |
+
return;
|
| 64 |
+
}
|
| 65 |
+
|
| 66 |
setTranscript(data.transcript || '');
|
| 67 |
+
setCurrentResponseText(data.response?.response || '');
|
| 68 |
+
|
| 69 |
+
if (data.is_last_segment) {
|
| 70 |
+
setResponse(data.response || { response: '', links: [], media_links: [], personal_info: [] });
|
| 71 |
+
setIsProcessing(false);
|
| 72 |
+
} else {
|
| 73 |
+
setIsProcessing(true);
|
| 74 |
+
}
|
| 75 |
|
| 76 |
+
// Calculate latency
|
| 77 |
if (requestStartTimeRef.current && data.segment_index === -1) {
|
| 78 |
const endTime = performance.now();
|
| 79 |
const latencyMs = endTime - requestStartTimeRef.current;
|
| 80 |
console.log(`Audio query latency: ${latencyMs.toFixed(2)} ms`);
|
| 81 |
+
setLatency((latencyMs / 1000).toFixed(2));
|
| 82 |
requestStartTimeRef.current = null;
|
| 83 |
}
|
| 84 |
|
|
|
|
| 89 |
}
|
| 90 |
}
|
| 91 |
} catch (err) {
|
| 92 |
+
console.error('Error processing WebSocket message:', err, 'Raw data:', event.data);
|
| 93 |
+
setError('Error processing server response. Please check the server logs and try again.');
|
| 94 |
+
setIsProcessing(false);
|
| 95 |
setLatency(null);
|
| 96 |
}
|
| 97 |
};
|
| 98 |
|
| 99 |
websocketRef.current.onclose = () => {
|
| 100 |
console.log('WebSocket disconnected');
|
| 101 |
+
setError('WebSocket connection lost. Please refresh the page or check the server.');
|
| 102 |
setIsProcessing(false);
|
| 103 |
setIsListening(false);
|
| 104 |
setIsPlaying(false);
|
|
|
|
| 107 |
|
| 108 |
websocketRef.current.onerror = (error) => {
|
| 109 |
console.error('WebSocket error:', error);
|
| 110 |
+
setError('Error connecting to server. Please ensure the server is running on ws://localhost:8000.');
|
| 111 |
setIsProcessing(false);
|
| 112 |
setIsListening(false);
|
| 113 |
setIsPlaying(false);
|
|
|
|
| 138 |
currentAudioRef.current = null;
|
| 139 |
return;
|
| 140 |
}
|
| 141 |
+
|
| 142 |
setIsPlaying(true);
|
| 143 |
isPlayingRef.current = true;
|
| 144 |
const audioSegment = audioQueueRef.current.shift();
|
| 145 |
try {
|
| 146 |
+
// Ensure the audio segment is a valid base64 string
|
| 147 |
+
if (!audioSegment || typeof audioSegment !== 'string') {
|
| 148 |
+
throw new Error('Invalid audio segment received');
|
| 149 |
+
}
|
| 150 |
+
|
| 151 |
+
const base64String = audioSegment.startsWith('data:audio/wav;base64,')
|
| 152 |
+
? audioSegment
|
| 153 |
+
: `data:audio/wav;base64,${audioSegment}`;
|
| 154 |
+
|
| 155 |
+
const response = await fetch(base64String);
|
| 156 |
+
if (!response.ok) {
|
| 157 |
+
throw new Error(`Failed to fetch audio: ${response.statusText}`);
|
| 158 |
+
}
|
| 159 |
+
|
| 160 |
+
const audioBlob = await response.blob();
|
| 161 |
const audioUrl = URL.createObjectURL(audioBlob);
|
| 162 |
const audio = new Audio(audioUrl);
|
| 163 |
currentAudioRef.current = audio;
|
| 164 |
+
|
| 165 |
audio.onended = () => {
|
| 166 |
URL.revokeObjectURL(audioUrl);
|
| 167 |
currentAudioRef.current = null;
|
| 168 |
playNextAudio();
|
| 169 |
};
|
| 170 |
+
|
| 171 |
+
audio.onerror = (error) => {
|
| 172 |
+
console.error('Audio playback error:', error);
|
| 173 |
+
URL.revokeObjectURL(audioUrl);
|
| 174 |
+
currentAudioRef.current = null;
|
| 175 |
+
setError('Failed to play audio response. Please try again.');
|
| 176 |
+
setIsPlaying(false);
|
| 177 |
+
isPlayingRef.current = false;
|
| 178 |
+
audioQueueRef.current = [];
|
| 179 |
+
};
|
| 180 |
+
|
| 181 |
+
await audio.play();
|
| 182 |
} catch (error) {
|
| 183 |
console.error('Error playing audio:', error);
|
| 184 |
+
setError('Error playing assistant response: ' + error.message);
|
| 185 |
setIsPlaying(false);
|
| 186 |
isPlayingRef.current = false;
|
| 187 |
audioQueueRef.current = [];
|
| 188 |
currentAudioRef.current = null;
|
|
|
|
| 189 |
}
|
| 190 |
};
|
| 191 |
|
|
|
|
| 229 |
} else if (userAgent.includes('safari')) {
|
| 230 |
return 'Please enable microphone permissions in Safari by going to Safari > Settings > Websites > Microphone, setting this site to "Allow", and refreshing the page.';
|
| 231 |
} else {
|
| 232 |
+
return 'Please enable microphone permissions in your browser settings and refresh the page. Check your browsers help documentation for specific instructions.';
|
| 233 |
}
|
| 234 |
};
|
| 235 |
|
|
|
|
| 286 |
const base64data = reader.result.split(',')[1];
|
| 287 |
if (websocketRef.current && websocketRef.current.readyState === WebSocket.OPEN) {
|
| 288 |
console.log('Sending audio data via WebSocket');
|
| 289 |
+
requestStartTimeRef.current = performance.now();
|
| 290 |
websocketRef.current.send(base64data);
|
| 291 |
setIsProcessing(true);
|
| 292 |
} else {
|
|
|
|
| 315 |
mediaRecorderRef.current.stop();
|
| 316 |
setIsListening(false);
|
| 317 |
}
|
| 318 |
+
}, 8000);
|
| 319 |
} else {
|
| 320 |
clearTimeout(silenceTimeoutRef.current);
|
| 321 |
}
|
|
|
|
| 335 |
mediaRecorderRef.current.stop();
|
| 336 |
setIsListening(false);
|
| 337 |
}
|
| 338 |
+
}, 40000);
|
| 339 |
|
| 340 |
} catch (error) {
|
| 341 |
console.error('Error accessing microphone:', error);
|
|
|
|
| 368 |
setTranscript(textInput);
|
| 369 |
setIsProcessing(true);
|
| 370 |
setError('');
|
| 371 |
+
setLatency(null);
|
| 372 |
+
setCurrentResponseText('');
|
| 373 |
|
| 374 |
try {
|
| 375 |
console.log('Sending POST request to /text_query with query:', textInput);
|
| 376 |
+
requestStartTimeRef.current = performance.now();
|
| 377 |
const response = await fetch('https://abdullah-khaled-ai-voice-secretary.hf.space/text_query', {
|
| 378 |
method: 'POST',
|
| 379 |
headers: {
|
|
|
|
| 396 |
const endTime = performance.now();
|
| 397 |
const latencyMs = endTime - requestStartTimeRef.current;
|
| 398 |
console.log(`Text query latency: ${latencyMs.toFixed(2)} ms`);
|
| 399 |
+
setLatency((latencyMs / 1000).toFixed(2));
|
| 400 |
requestStartTimeRef.current = null;
|
|
|
|
| 401 |
setResponse(data);
|
| 402 |
+
setCurrentResponseText(data.response);
|
| 403 |
setIsProcessing(false);
|
| 404 |
setTextInput('');
|
| 405 |
} catch (error) {
|
| 406 |
console.error('Error sending text query:', error);
|
| 407 |
+
setError(`Failed to process text query: ${error.message}.`);
|
| 408 |
setIsProcessing(false);
|
| 409 |
setLatency(null);
|
| 410 |
}
|
|
|
|
| 432 |
return /\.(mp4|webm|ogg)$/i.test(url);
|
| 433 |
};
|
| 434 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 435 |
|
| 436 |
+
return (
|
| 437 |
+
<div className="w-full flex flex-col md:flex-row gap-8 items-stretch">
|
| 438 |
+
<div className="flex-1 flex flex-col gap-4">
|
| 439 |
+
<div className="bg-white dark:bg-gray-900 rounded-2xl shadow-lg dark:shadow-xl p-6 transition-colors duration-500 border border-gray-100 dark:border-gray-800">
|
| 440 |
+
<h2 className="text-lg font-semibold text-gray-700 dark:text-gray-100 mb-2">Transcript</h2>
|
| 441 |
+
<p className="text-gray-600 dark:text-gray-300 text-sm sm:text-base">
|
| 442 |
+
{transcript || 'Click the microphone or type to start interacting'}
|
| 443 |
+
</p>
|
| 444 |
+
<p className="text-gray-600 dark:text-gray-400 text-xs sm:text-sm mt-2">
|
| 445 |
+
Response time: {latency ? `${latency} seconds` : 'Not available'}
|
| 446 |
+
</p>
|
| 447 |
+
</div>
|
| 448 |
+
{isProcessing && (
|
| 449 |
+
<div className="flex justify-center">
|
| 450 |
+
<Loader className="w-6 h-6 animate-spin text-blue-500 dark:text-blue-400" />
|
|
|
|
|
|
|
|
|
|
| 451 |
</div>
|
| 452 |
+
)}
|
| 453 |
+
{(currentResponseText || response.response) && !isProcessing && (
|
| 454 |
+
<div className="bg-blue-50 dark:bg-blue-950 rounded-2xl shadow-lg dark:shadow-xl p-6 transition-colors duration-500 border border-blue-100 dark:border-blue-900">
|
| 455 |
+
<div className="flex justify-between items-center mb-2">
|
| 456 |
+
<h2 className="text-lg font-semibold text-blue-700 dark:text-blue-200">Response</h2>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 457 |
<button
|
| 458 |
+
onClick={() => setShowResponse(!showResponse)}
|
| 459 |
+
className="text-blue-600 dark:text-blue-300 hover:text-blue-800 dark:hover:text-blue-400 focus:outline-none"
|
| 460 |
+
aria-label={showResponse ? 'Hide response' : 'Show response'}
|
|
|
|
| 461 |
>
|
| 462 |
+
{showResponse ? <EyeOff className="w-5 h-5" /> : <Eye className="w-5 h-5" />}
|
| 463 |
</button>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 464 |
</div>
|
| 465 |
+
<div
|
| 466 |
+
className={`transition-all duration-300 ${
|
| 467 |
+
showResponse ? 'max-h-[60vh] opacity-100' : 'max-h-0 opacity-0 overflow-hidden'
|
| 468 |
+
} overflow-y-auto scrollbar-thin scrollbar-thumb-blue-500 scrollbar-track-blue-100 dark:scrollbar-thumb-blue-700 dark:scrollbar-track-blue-950`}
|
| 469 |
+
>
|
| 470 |
+
<div className="flex border-b border-gray-200 dark:border-gray-700 mb-4">
|
| 471 |
+
<button
|
| 472 |
+
className={`px-3 py-2 text-sm font-medium flex-1 text-center ${
|
| 473 |
+
activeTab === 'response'
|
| 474 |
+
? 'border-b-2 border-blue-500 text-blue-600'
|
| 475 |
+
: 'text-gray-500 hover:text-blue-600'
|
| 476 |
+
}`}
|
| 477 |
+
onClick={() => setActiveTab('response')}
|
| 478 |
+
>
|
| 479 |
+
Response
|
| 480 |
+
</button>
|
| 481 |
+
<button
|
| 482 |
+
className={`px-3 py-2 text-sm font-medium flex-1 text-center ${
|
| 483 |
+
activeTab === 'links'
|
| 484 |
+
? 'border-b-2 border-blue-500 text-blue-600'
|
| 485 |
+
: 'text-gray-500 hover:text-blue-600'
|
| 486 |
+
}`}
|
| 487 |
+
onClick={() => setActiveTab('links')}
|
| 488 |
+
>
|
| 489 |
+
Links
|
| 490 |
+
</button>
|
| 491 |
+
<button
|
| 492 |
+
className={`px-3 py-2 text-sm font-medium flex-1 text-center ${
|
| 493 |
+
activeTab === 'media'
|
| 494 |
+
? 'border-b-2 border-blue-500 text-blue-600'
|
| 495 |
+
: 'text-gray-500 hover:text-blue-600'
|
| 496 |
+
}`}
|
| 497 |
+
onClick={() => setActiveTab('media')}
|
| 498 |
+
>
|
| 499 |
+
Media
|
| 500 |
+
</button>
|
| 501 |
+
<button
|
| 502 |
+
className={`px-3 py-2 text-sm font-medium flex-1 text-center ${
|
| 503 |
+
activeTab === 'personal'
|
| 504 |
+
? 'border-b-2 border-blue-500 text-blue-600'
|
| 505 |
+
: 'text-gray-500 hover:text-blue-600'
|
| 506 |
+
}`}
|
| 507 |
+
onClick={() => setActiveTab('personal')}
|
| 508 |
+
>
|
| 509 |
+
Personal Info
|
| 510 |
+
</button>
|
| 511 |
</div>
|
| 512 |
+
{activeTab === 'response' && (
|
| 513 |
+
<div className="text-gray-800 dark:text-gray-100 text-sm sm:text-base break-words">
|
| 514 |
+
<ReactMarkdown
|
| 515 |
+
remarkPlugins={[remarkGfm]}
|
| 516 |
+
components={{
|
| 517 |
+
h1: ({ children }) => <h1 className="text-5xl font-semibold text-gray-800 dark:text-gray-100 mt-4 mb-2">{children}</h1>,
|
| 518 |
+
h2: ({ children }) => <h2 className="text-4xl font-semibold text-gray-800 dark:text-gray-100 mt-4 mb-2">{children}</h2>,
|
| 519 |
+
h3: ({ children }) => <h3 className="text-3xl font-semibold text-gray-800IManager dark:text-gray-100 mt-4 mb-2">{children}</h3>,
|
| 520 |
+
h4: ({ children }) => <h4 className="text-2xl font-semibold text-gray-800 dark:text-gray-100 mt-4 mb-2">{children}</h4>,
|
| 521 |
+
h5: ({ children }) => <h5 className="text-xl font-semibold text-gray-800 dark:text-gray-100 mt-4 mb-2">{children}</h5>,
|
| 522 |
+
h6: ({ children }) => <h6 className="text-lg font-semibold text-gray-800 dark:text-gray-100 mt-4 mb-2">{children}</h6>,
|
| 523 |
+
p: ({ children }) => <p className="text-gray-800 dark:text-gray-100 my-2">{children}</p>,
|
| 524 |
+
strong: ({ children }) => <span className="font-bold text-blue-600 dark:text-blue-300">{children}</span>,
|
| 525 |
+
em: ({ children }) => <span className="italic text-gray-700 dark:text-gray-300">{children}</span>,
|
| 526 |
+
code: ({ node, inline, children, className }) => (
|
| 527 |
+
inline ? (
|
| 528 |
+
<code className="bg-gray-100 dark:bg-gray-800 text-red-600 dark:text-red-400 px-1 rounded">{children}</code>
|
| 529 |
+
) : (
|
| 530 |
+
<pre className="bg-gray-100 dark:bg-gray-800 text-red-600 dark:text-red-400 p-4 rounded my-2 overflow-x-auto">
|
| 531 |
+
<code className={className}>{children}</code>
|
| 532 |
+
</pre>
|
| 533 |
+
)
|
| 534 |
+
),
|
| 535 |
+
a: ({ href, children }) => (
|
| 536 |
+
<a href={href} target="_blank" rel="noopener noreferrer" className="text-blue-600 hover:underline dark:text-blue-300">
|
| 537 |
+
{children}
|
| 538 |
+
</a>
|
| 539 |
+
),
|
| 540 |
+
ul: ({ children }) => <ul className="my-2 ml-4 list-disc text-gray-800 dark:text-gray-100">{children}</ul>,
|
| 541 |
+
ol: ({ children }) => <ol className="my-2 ml-4 list-decimal text-gray-800 dark:text-gray-100">{children}</ol>,
|
| 542 |
+
li: ({ children }) => <li className="ml-4">{children}</li>,
|
| 543 |
+
blockquote: ({ children }) => (
|
| 544 |
+
<blockquote className="border-l-4 border-gray-300 dark:border-gray-600 pl-4 italic text-gray-700 dark:text-gray-300 my-2">
|
| 545 |
+
{children}
|
| 546 |
+
</blockquote>
|
| 547 |
+
),
|
| 548 |
+
}}
|
| 549 |
>
|
| 550 |
+
{currentResponseText}
|
| 551 |
+
</ReactMarkdown>
|
| 552 |
</div>
|
| 553 |
+
)}
|
| 554 |
+
{activeTab === 'links' && (
|
| 555 |
+
<ul className="text-gray-800 space-y-2 text-sm sm:text-base">
|
| 556 |
+
{response.links.length > 0 ? (
|
| 557 |
+
response.links.map((link, index) => (
|
| 558 |
+
<li key={index}>
|
| 559 |
+
<a
|
| 560 |
+
href={link.url}
|
| 561 |
+
target="_blank"
|
| 562 |
+
rel="noopener noreferrer"
|
| 563 |
+
className="text-blue-600 hover:underline"
|
| 564 |
+
>
|
| 565 |
+
{link.platform}
|
| 566 |
+
</a>
|
| 567 |
+
</li>
|
| 568 |
+
))
|
| 569 |
+
) : (
|
| 570 |
+
<p>No links available.</p>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 571 |
)}
|
| 572 |
+
</ul>
|
| 573 |
+
)}
|
| 574 |
+
{activeTab === 'media' && (
|
| 575 |
+
<div className="text-gray-800">
|
| 576 |
+
{response.media_links.length > 0 ? (
|
| 577 |
+
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4">
|
| 578 |
+
{response.media_links.map((media, index) => (
|
| 579 |
+
isVideo(media) ? (
|
| 580 |
+
<video
|
| 581 |
+
key={index}
|
| 582 |
+
src={media}
|
| 583 |
+
controls
|
| 584 |
+
className="w-full h-32 sm:h-48 object-cover rounded-lg shadow-md cursor-pointer hover:opacity-80 transition-opacity duration-200"
|
| 585 |
+
onClick={() => handleMediaClick(media)}
|
| 586 |
+
onError={(e) => {
|
| 587 |
+
console.error(`Failed to load video: ${media}`);
|
| 588 |
+
e.target.style.display = 'none';
|
| 589 |
+
}}
|
| 590 |
+
/>
|
| 591 |
+
) : (
|
| 592 |
+
<img
|
| 593 |
+
key={index}
|
| 594 |
+
src={media}
|
| 595 |
+
alt={`Media ${index + 1}`}
|
| 596 |
+
className="w-full h-32 sm:h-48 object-cover rounded-lg shadow-md cursor-pointer hover:opacity-80 transition-opacity duration-200"
|
| 597 |
+
onClick={() => handleMediaClick(media)}
|
| 598 |
+
onError={(e) => {
|
| 599 |
+
console.error(`Failed to load image: ${media}`);
|
| 600 |
+
e.target.style.display = 'none';
|
| 601 |
+
}}
|
| 602 |
+
/>
|
| 603 |
+
)
|
| 604 |
+
))}
|
|
|
|
|
|
|
| 605 |
</div>
|
| 606 |
+
) : (
|
| 607 |
+
<p className="text-sm sm:text-base">No media available. Try asking about a specific project.</p>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 608 |
)}
|
| 609 |
</div>
|
| 610 |
+
)}
|
| 611 |
+
{activeTab === 'personal' && (
|
| 612 |
+
<ul className="text-gray-800 space-y-2 text-sm sm:text-base">
|
| 613 |
+
{response.personal_info.length > 0 ? (
|
| 614 |
+
response.personal_info.map((info, index) => (
|
| 615 |
+
<li key={index}>
|
| 616 |
+
<span className="font-semibold">{info.type}:</span>{' '}
|
| 617 |
+
{info.type === 'Phone' ? (
|
| 618 |
+
<a
|
| 619 |
+
href={info.value}
|
| 620 |
+
target="_blank"
|
| 621 |
+
rel="noopener noreferrer"
|
| 622 |
+
className="text-blue-600 hover:underline"
|
| 623 |
+
>
|
| 624 |
+
{info.value}
|
| 625 |
+
</a>
|
| 626 |
+
) : (
|
| 627 |
+
<span>{info.value}</span>
|
| 628 |
+
)}
|
| 629 |
+
</li>
|
| 630 |
+
))
|
| 631 |
+
) : (
|
| 632 |
+
<p>No personal information available. Try asking for contact details.</p>
|
| 633 |
+
)}
|
| 634 |
+
</ul>
|
| 635 |
+
)}
|
| 636 |
+
</div>
|
| 637 |
</div>
|
| 638 |
+
)}
|
| 639 |
+
{error && (
|
| 640 |
+
<div className="bg-red-50 dark:bg-red-900 p-4 rounded-lg flex items-center space-x-2 mt-2 border border-red-200 dark:border-red-700">
|
| 641 |
+
<AlertCircle className="w-5 h-5 text-red-600 dark:text-red-300 flex-shrink-0" />
|
| 642 |
+
<div className="flex-1">
|
| 643 |
+
<p className="text-red-600 dark:text-red-100 text-sm sm:text-base">{error}</p>
|
| 644 |
+
<button
|
| 645 |
+
onClick={handleRetryClick}
|
| 646 |
+
className="mt-2 flex items-center text-blue-600 dark:text-blue-300 hover:text-blue-800 dark:hover:text-blue-400 focus:outline-none text-sm sm:text-base"
|
| 647 |
+
aria-label="Retry microphone access"
|
| 648 |
+
>
|
| 649 |
+
<RefreshCw className="w-4 h-4 mr-1" />
|
| 650 |
+
Retry
|
| 651 |
+
</button>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 652 |
</div>
|
| 653 |
+
</div>
|
| 654 |
+
)}
|
| 655 |
+
<form onSubmit={handleTextSubmit} className="flex items-center space-x-2 mt-2">
|
| 656 |
+
<input
|
| 657 |
+
type="text"
|
| 658 |
+
value={textInput}
|
| 659 |
+
onChange={(e) => setTextInput(e.target.value)}
|
| 660 |
+
placeholder="Ask the assistant something..."
|
| 661 |
+
className="flex-1 p-2 border border-gray-300 dark:border-gray-700 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 dark:bg-gray-900 dark:text-gray-100 text-sm sm:text-base transition-colors"
|
| 662 |
+
disabled={isProcessing}
|
| 663 |
+
/>
|
| 664 |
+
<button
|
| 665 |
+
type="submit"
|
| 666 |
+
className="p-2 bg-blue-500 text-white rounded-lg hover:bg-blue-600 focus:outline-none focus:ring-2 focus:ring-blue-500 disabled:opacity-50 disabled:cursor-not-allowed transition-colors"
|
| 667 |
+
aria-label="Submit text query"
|
| 668 |
+
disabled={isProcessing}
|
| 669 |
+
>
|
| 670 |
+
<Send className="w-5 h-5" />
|
| 671 |
+
</button>
|
| 672 |
+
</form>
|
| 673 |
+
</div>
|
| 674 |
+
<div className="flex flex-col items-center justify-center min-w-[180px] md:min-w-[260px]">
|
| 675 |
+
<div className="relative">
|
| 676 |
+
<canvas ref={canvasRef} className="w-32 h-32 sm:w-48 sm:h-48" />
|
| 677 |
+
<button
|
| 678 |
+
onClick={handleMicClick}
|
| 679 |
+
className={`absolute top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2 p-3 sm:p-4 rounded-full transition-all duration-300 shadow-lg border-4 border-white dark:border-gray-800 ${
|
| 680 |
+
isListening
|
| 681 |
+
? 'bg-blue-500 text-white scale-110'
|
| 682 |
+
: isPlaying
|
| 683 |
+
? 'bg-blue-500 text-white animate-pulse'
|
| 684 |
+
: 'bg-gray-200 dark:bg-gray-700 text-gray-600 dark:text-gray-200'
|
| 685 |
+
} hover:bg-blue-600 hover:text-white dark:hover:bg-blue-400 dark:hover:text-gray-900 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2 disabled:opacity-50 disabled:cursor-not-allowed`}
|
| 686 |
+
aria-label={isListening ? 'Stop listening' : isPlaying ? 'Stop and listen again' : 'Start listening'}
|
| 687 |
+
disabled={isProcessing}
|
| 688 |
+
>
|
| 689 |
+
<Mic className="w-6 h-6 sm:w-8 sm:h-8" />
|
| 690 |
+
</button>
|
| 691 |
</div>
|
| 692 |
</div>
|
| 693 |
+
{selectedMedia && (
|
| 694 |
+
<div className="fixed inset-0 bg-black bg-opacity-80 flex items-center justify-center z-50">
|
| 695 |
+
<div className="relative max-w-4xl w-full p-4">
|
| 696 |
+
<button
|
| 697 |
+
onClick={closeLightbox}
|
| 698 |
+
className="absolute top-2 right-2 text-white bg-gray-800 rounded-full p-2 hover:bg-gray-700 focus:outline-none focus:ring-2 focus:ring-white"
|
| 699 |
+
aria-label="Close media preview"
|
| 700 |
+
>
|
| 701 |
+
<X className="w-6 h-6" />
|
| 702 |
+
</button>
|
| 703 |
+
{isVideo(selectedMedia) ? (
|
| 704 |
+
<video
|
| 705 |
+
src={selectedMedia}
|
| 706 |
+
controls
|
| 707 |
+
autoPlay
|
| 708 |
+
className="w-full h-auto max-h-[80vh] object-contain rounded-lg"
|
| 709 |
+
onError={(e) => {
|
| 710 |
+
console.error(`Failed to load full-size video: ${selectedMedia}`);
|
| 711 |
+
e.target.style.display = 'none';
|
| 712 |
+
setError('Failed to load video preview.');
|
| 713 |
+
}}
|
| 714 |
+
/>
|
| 715 |
+
) : (
|
| 716 |
+
<img
|
| 717 |
+
src={selectedMedia}
|
| 718 |
+
alt="Full-size preview"
|
| 719 |
+
className="w-full h-auto max-h-[80vh] object-contain rounded-lg"
|
| 720 |
+
onError={(e) => {
|
| 721 |
+
console.error(`Failed to load full-size image: ${selectedMedia}`);
|
| 722 |
+
e.target.style.display = 'none';
|
| 723 |
+
setError('Failed to load image preview.');
|
| 724 |
+
}}
|
| 725 |
+
/>
|
| 726 |
+
)}
|
| 727 |
+
</div>
|
| 728 |
+
</div>
|
| 729 |
+
)}
|
| 730 |
+
</div>
|
| 731 |
+
);
|
| 732 |
};
|
| 733 |
|
| 734 |
export default VoiceAssistant;
|
src/main.jsx
CHANGED
|
@@ -1,5 +1,31 @@
|
|
| 1 |
-
import React from 'react';
|
| 2 |
import ReactDOM from 'react-dom/client';
|
| 3 |
import App from './components/App.jsx';
|
| 4 |
|
| 5 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import React, { useEffect, useState } from 'react';
|
| 2 |
import ReactDOM from 'react-dom/client';
|
| 3 |
import App from './components/App.jsx';
|
| 4 |
|
| 5 |
+
export const ThemeContext = React.createContext();
|
| 6 |
+
|
| 7 |
+
const ThemeProvider = ({ children }) => {
|
| 8 |
+
const [theme, setTheme] = useState(() => {
|
| 9 |
+
if (typeof window !== 'undefined') {
|
| 10 |
+
return localStorage.getItem('theme') || 'light';
|
| 11 |
+
}
|
| 12 |
+
return 'light';
|
| 13 |
+
});
|
| 14 |
+
|
| 15 |
+
useEffect(() => {
|
| 16 |
+
document.documentElement.classList.toggle('dark', theme === 'dark');
|
| 17 |
+
localStorage.setItem('theme', theme);
|
| 18 |
+
}, [theme]);
|
| 19 |
+
|
| 20 |
+
return (
|
| 21 |
+
<ThemeContext.Provider value={{ theme, setTheme }}>
|
| 22 |
+
{children}
|
| 23 |
+
</ThemeContext.Provider>
|
| 24 |
+
);
|
| 25 |
+
};
|
| 26 |
+
|
| 27 |
+
ReactDOM.createRoot(document.getElementById('root')).render(
|
| 28 |
+
<ThemeProvider>
|
| 29 |
+
<App />
|
| 30 |
+
</ThemeProvider>
|
| 31 |
+
);
|