diff --git a/BillNote_frontend/package.json b/BillNote_frontend/package.json
index b2c9ee8..fdd9911 100644
--- a/BillNote_frontend/package.json
+++ b/BillNote_frontend/package.json
@@ -57,6 +57,7 @@
"react-router-dom": "^7.5.1",
"react-syntax-highlighter": "^15.6.1",
"rehype-katex": "^6.0.2",
+ "rehype-slug": "5.1.0",
"remark-gfm": "3.0.1",
"remark-math": "^5.1.1",
"sonner": "^2.0.3",
diff --git a/BillNote_frontend/pnpm-lock.yaml b/BillNote_frontend/pnpm-lock.yaml
index 9c272ec..7ea277c 100644
--- a/BillNote_frontend/pnpm-lock.yaml
+++ b/BillNote_frontend/pnpm-lock.yaml
@@ -13,7 +13,7 @@ importers:
version: 2.4.0(antd@5.29.3(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
'@hookform/resolvers':
specifier: ^5.0.1
- version: 5.2.2(react-hook-form@7.72.0(react@19.2.4))
+ version: 5.4.0(react-hook-form@7.72.0(react@19.2.4))
'@lobehub/icons':
specifier: ^1.97.1
version: 1.98.0(@babel/core@7.29.0)(@types/mdast@4.0.4)(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(antd@5.29.3(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(framer-motion@12.38.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(micromark-util-types@2.0.2)(micromark@4.0.2)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
@@ -52,7 +52,7 @@ importers:
version: 1.2.8(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
'@tailwindcss/vite':
specifier: ^4.1.3
- version: 4.2.2(vite@6.4.1(@types/node@22.19.15)(jiti@2.6.1)(lightningcss@1.32.0)(yaml@2.8.3))
+ version: 4.2.2(vite@6.4.2(@types/node@22.19.15)(jiti@2.6.1)(lightningcss@1.32.0)(yaml@2.8.3))
'@tauri-apps/api':
specifier: ^2.11.0
version: 2.11.0
@@ -61,7 +61,7 @@ importers:
version: 2.3.5
'@uiw/react-markdown-preview':
specifier: ^5.1.3
- version: 5.1.5(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
+ version: 5.2.1(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
antd:
specifier: ^5.24.8
version: 5.29.3(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
@@ -76,13 +76,13 @@ importers:
version: 2.1.1
fuse.js:
specifier: ^7.1.0
- version: 7.1.0
+ version: 7.3.0
github-markdown-css:
specifier: ^5.8.1
version: 5.9.0
idb-keyval:
specifier: ^6.2.2
- version: 6.2.2
+ version: 6.2.4
jszip:
specifier: ^3.10.1
version: 3.10.1
@@ -149,6 +149,9 @@ importers:
rehype-katex:
specifier: ^6.0.2
version: 6.0.3
+ rehype-slug:
+ specifier: 5.1.0
+ version: 5.1.0
remark-gfm:
specifier: 3.0.1
version: 3.0.1
@@ -169,7 +172,7 @@ importers:
version: 1.4.0
uuid:
specifier: ^11.1.0
- version: 11.1.0
+ version: 11.1.1
zod:
specifier: ^3.24.2
version: 3.25.76
@@ -197,7 +200,7 @@ importers:
version: 19.2.3(@types/react@19.2.14)
'@vitejs/plugin-react':
specifier: ^4.3.4
- version: 4.7.0(vite@6.4.1(@types/node@22.19.15)(jiti@2.6.1)(lightningcss@1.32.0)(yaml@2.8.3))
+ version: 4.7.0(vite@6.4.2(@types/node@22.19.15)(jiti@2.6.1)(lightningcss@1.32.0)(yaml@2.8.3))
autoprefixer:
specifier: ^10.4.21
version: 10.4.27(postcss@8.5.8)
@@ -227,7 +230,7 @@ importers:
version: 8.57.1(eslint@9.39.4(jiti@2.6.1))(typescript@5.7.3)
vite:
specifier: ^6.2.0
- version: 6.4.1(@types/node@22.19.15)(jiti@2.6.1)(lightningcss@1.32.0)(yaml@2.8.3)
+ version: 6.4.2(@types/node@22.19.15)(jiti@2.6.1)(lightningcss@1.32.0)(yaml@2.8.3)
packages:
@@ -732,8 +735,8 @@ packages:
react: ^16 || ^17 || ^18 || ^19
react-dom: ^16 || ^17 || ^18 || ^19
- '@hookform/resolvers@5.2.2':
- resolution: {integrity: sha512-A/IxlMLShx3KjV/HeTcTfaMxdwy690+L/ZADoeaTltLx+CVuzkeVIPuybK3jrRfw7YZnmdKsVVHAlEPIAEUNlA==}
+ '@hookform/resolvers@5.4.0':
+ resolution: {integrity: sha512-EIsqr/t/qbinPIhGjMdtvutIN1Kk4uwbROE9/UQ93CAVGR7GkA7Y92+fX80OzXi/OB67jVFYwKGO1WzkxmkFZw==}
peerDependencies:
react-hook-form: ^7.55.0
@@ -1786,6 +1789,9 @@ packages:
'@types/estree@1.0.8':
resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==}
+ '@types/estree@1.0.9':
+ resolution: {integrity: sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==}
+
'@types/geojson@7946.0.16':
resolution: {integrity: sha512-6C8nqWur3j98U6+lXDfTUWIfgvZU+EumvpHKcYjujKH7woYyLj2sUmff0tRhrqM7BohUw7Pz3ZB1jj2gW9Fvmg==}
@@ -1910,8 +1916,8 @@ packages:
'@uiw/copy-to-clipboard@1.0.20':
resolution: {integrity: sha512-IFQhS62CLNon1YgYJTEzXR2N3WVXg7V1FaBRDLMlzU6JY5X6Hr3OPAcw4WNoKcz2XcFD6XCgwEjlsmj+JA0mWA==}
- '@uiw/react-markdown-preview@5.1.5':
- resolution: {integrity: sha512-DNOqx1a6gJR7Btt57zpGEKTfHRlb7rWbtctMRO2f82wWcuoJsxPBrM+JWebDdOD0LfD8oe2CQvW2ICQJKHQhZg==}
+ '@uiw/react-markdown-preview@5.2.1':
+ resolution: {integrity: sha512-JjvcHveT6glhlJYJx1XGBZij6wkw+VwREV6Z6m/GpsjPPdLjF1x8nlPBSB/ATyUF4lD7C8ttMkCqVH9N9XMgEA==}
peerDependencies:
react: '>=16.8.0'
react-dom: '>=16.8.0'
@@ -1919,6 +1925,9 @@ packages:
'@ungap/structured-clone@1.3.0':
resolution: {integrity: sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==}
+ '@ungap/structured-clone@1.3.1':
+ resolution: {integrity: sha512-mUFwbeTqrVgDQxFveS+df2yfap6iuP20NAKAsBt5jDEoOTDew+zwLAOilHCeQJOVSvmgCX4ogqIrA0mnyr08yQ==}
+
'@upsetjs/venn.js@2.0.0':
resolution: {integrity: sha512-WbBhLrooyePuQ1VZxrJjtLvTc4NVfpOyKx0sKqioq9bX1C1m7Jgykkn8gLrtwumBioXIqam8DLxp88Adbue6Hw==}
@@ -2689,8 +2698,8 @@ packages:
function-bind@1.1.2:
resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==}
- fuse.js@7.1.0:
- resolution: {integrity: sha512-trLf4SzuuUxfusZADLINj+dE8clK1frKdmqiJNb1Es75fmI5oY6X2mxLVUciLLjxqw/xr72Dhy+lER6dGd02FQ==}
+ fuse.js@7.3.0:
+ resolution: {integrity: sha512-plz8RVjfcDedTGfVngWH1jmJvBvAwi1v2jecfDerbEnMcmOYUEEwKFTHbNoCiYyzaK2Ws8lABkTCcRSqCY1q4w==}
engines: {node: '>=10'}
gensync@1.0.0-beta.2:
@@ -2794,9 +2803,15 @@ packages:
hast-util-from-parse5@8.0.3:
resolution: {integrity: sha512-3kxEVkEKt0zvcZ3hCRYI8rqrgwtlIOFMWkbclACvjlDw8Li9S2hk/d51OI0nr/gIpdMHNepwgOKqZ/sy0Clpyg==}
+ hast-util-has-property@2.0.1:
+ resolution: {integrity: sha512-X2+RwZIMTMKpXUzlotatPzWj8bspCymtXH3cfG3iQKV+wPF53Vgaqxi/eLqGck0wKq1kS9nvoB1wchbCPEL8sg==}
+
hast-util-has-property@3.0.0:
resolution: {integrity: sha512-MNilsvEKLFpV604hwfhVStK0usFY/QmM5zX16bo7EjnAEGofr5YyI37kzopBlZJkHD4t887i+q/C8/tr5Q94cA==}
+ hast-util-heading-rank@2.1.1:
+ resolution: {integrity: sha512-iAuRp+ESgJoRFJbSyaqsfvJDY6zzmFoEnL1gtz1+U8gKtGGj1p0CVlysuUAUjq95qlZESHINLThwJzNGmgGZxA==}
+
hast-util-heading-rank@3.0.0:
resolution: {integrity: sha512-EJKb8oMUXVHcWZTDepnr+WNbfnXKFNf9duMesmr4S8SXTJBJ9M4Yok08pu9vxdJwdlGRhVumk9mEhkEvKGifwA==}
@@ -2833,6 +2848,9 @@ packages:
hast-util-to-parse5@8.0.1:
resolution: {integrity: sha512-MlWT6Pjt4CG9lFCjiz4BH7l9wmrMkfkJYCxFwKQic8+RTZgWPuWxwAfjJElsXkex7DJjfSJsQIt931ilUgmwdA==}
+ hast-util-to-string@2.0.0:
+ resolution: {integrity: sha512-02AQ3vLhuH3FisaMM+i/9sm4OXGSq1UhOOCpTLLQtHdL3tZt7qil69r8M8iDkZYyC0HCFylcYoP+8IO7ddta1A==}
+
hast-util-to-string@3.0.1:
resolution: {integrity: sha512-XelQVTDWvqcl3axRfI0xSeoVKzyIFPwsAGSLIsKdJKQMXDYJS4WYrBNF/8J7RdhIcFI2BOHgAifggsvsxp/3+A==}
@@ -2883,8 +2901,8 @@ packages:
resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==}
engines: {node: '>=0.10.0'}
- idb-keyval@6.2.2:
- resolution: {integrity: sha512-yjD9nARJ/jb1g+CvD0tlhUHOrJ9Sy0P8T9MF3YaLlHnSRpwPfpTX0XIvpmw3gAJUmEu3FiICLBDPXVwyEvrleg==}
+ idb-keyval@6.2.4:
+ resolution: {integrity: sha512-D/NzHWUmYJGXi++z67aMSrnisb9A3621CyRK5G89JyTlN13C8xf0g04DLxUKMufPem3e3L2JAXR6Z00OWy183Q==}
ignore@5.3.2:
resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==}
@@ -4228,12 +4246,6 @@ packages:
'@types/react': '>=16'
react: '>=16'
- react-markdown@9.0.3:
- resolution: {integrity: sha512-Yk7Z94dbgYTOrdk41Z74GoKA7rThnsbbqBTRYuxoe08qvfQ9tJVhmAKw6BJS/ZORG7kTy/s1QvYzSuaoBA1qfw==}
- peerDependencies:
- '@types/react': '>=18'
- react: '>=18'
-
react-medium-image-zoom@5.4.1:
resolution: {integrity: sha512-DD2iZYaCfAwiQGR8AN62r/cDJYoXhezlYJc5HY4TzBUGuGge43CptG0f7m0PEIM72aN6GfpjohvY1yYdtCJB7g==}
peerDependencies:
@@ -4372,8 +4384,8 @@ packages:
regex@6.1.0:
resolution: {integrity: sha512-6VwtthbV4o/7+OaAF9I5L5V3llLEsoPyq9P1JVXkedTP33c7MfCG0/5NOPcSJn0TzXcG9YUrR0gQSWioew3LDg==}
- rehype-attr@3.0.3:
- resolution: {integrity: sha512-Up50Xfra8tyxnkJdCzLBIBtxOcB2M1xdeKe1324U06RAvSjYm7ULSeoM+b/nYPQPVd7jsXJ9+39IG1WAJPXONw==}
+ rehype-attr@4.0.0:
+ resolution: {integrity: sha512-tANn9EmhG4mEZlNdDDRKuS0OXPDvc6P6OjJ1yApzOjIdCvKNLiuU2HdMSLTpiVi3D/FyLK6B+ZZ8PYtRxiGg7Q==}
engines: {node: '>=16'}
rehype-autolink-headings@7.1.0:
@@ -4408,6 +4420,9 @@ packages:
resolution: {integrity: sha512-L/FO96EOzSA6bzOam4DVu61/PB3AGKcSPXpa53yMIozoxH4qg1+bVZDF8zh1EsuxtSauAhzt5cCnvoplAaSLrw==}
engines: {node: '>=16.0.0'}
+ rehype-slug@5.1.0:
+ resolution: {integrity: sha512-Gf91dJoXneiorNEnn+Phx97CO7oRMrpi+6r155tTxzGuLtm+QrI4cTwCa9e1rtePdL4i9tSO58PeSS6HWfgsiw==}
+
rehype-slug@6.0.0:
resolution: {integrity: sha512-lWyvf/jwu+oS5+hL5eClVd3hNdmwM1kAC0BUvEGD19pajQMIzcNUd/k9GsfQ+FfECvX+JE+e9/btsKH0EjJT6A==}
@@ -4822,12 +4837,12 @@ packages:
util-deprecate@1.0.2:
resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==}
- uuid@11.1.0:
- resolution: {integrity: sha512-0/A9rDy9P7cJ+8w1c9WD9V//9Wj15Ce2MPz8Ri6032usz+NfePxx5AcN3bN+r6ZL6jEo066/yNYB3tn4pQEx+A==}
+ uuid@11.1.1:
+ resolution: {integrity: sha512-vIYxrBCC/N/K+Js3qSN88go7kIfNPssr/hHCesKCQNAjmgvYS2oqr69kIufEG+O4+PfezOH4EbIeHCfFov8ZgQ==}
hasBin: true
- uuid@13.0.0:
- resolution: {integrity: sha512-XQegIaBTVUjSHliKqcnFqYypAd4S+WCYt5NIeRs6w/UAry7z8Y9j5ZwRRL4kzq9U3sD6v+85er9FvkEaBpji2w==}
+ uuid@13.0.2:
+ resolution: {integrity: sha512-vzi9uRZ926x4XV73S/4qQaTwPXM2JBj6/6lI/byHH1jOpCzb0zDbfytgA9LcN/hzb2l7WQSQnxITOVx5un/wGw==}
hasBin: true
uvu@0.5.6:
@@ -4856,8 +4871,8 @@ packages:
vfile@6.0.3:
resolution: {integrity: sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==}
- vite@6.4.1:
- resolution: {integrity: sha512-+Oxm7q9hDoLMyJOYfUYBuHQo+dkAloi33apOPP56pzj+vsdJDzr+j1NISE5pyaAuKL4A3UD34qd0lx5+kfKp2g==}
+ vite@6.4.2:
+ resolution: {integrity: sha512-2N/55r4JDJ4gdrCvGgINMy+HH3iRpNIz8K6SFwVsA+JbQScLiC+clmAxBgwiSPgcG9U15QmvqCGWzMbqda5zGQ==}
engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0}
hasBin: true
peerDependencies:
@@ -5534,7 +5549,7 @@ snapshots:
react: 19.2.4
react-dom: 19.2.4(react@19.2.4)
- '@hookform/resolvers@5.2.2(react-hook-form@7.72.0(react@19.2.4))':
+ '@hookform/resolvers@5.4.0(react-hook-form@7.72.0(react@19.2.4))':
dependencies:
'@standard-schema/utils': 0.3.0
react-hook-form: 7.72.0(react@19.2.4)
@@ -5725,7 +5740,7 @@ snapshots:
unified: 11.0.5
url-join: 5.0.0
use-merge-value: 1.2.0(react@19.2.4)
- uuid: 13.0.0
+ uuid: 13.0.2
transitivePeerDependencies:
- '@babel/core'
- '@types/mdast'
@@ -6456,12 +6471,12 @@ snapshots:
postcss: 8.5.8
tailwindcss: 4.2.2
- '@tailwindcss/vite@4.2.2(vite@6.4.1(@types/node@22.19.15)(jiti@2.6.1)(lightningcss@1.32.0)(yaml@2.8.3))':
+ '@tailwindcss/vite@4.2.2(vite@6.4.2(@types/node@22.19.15)(jiti@2.6.1)(lightningcss@1.32.0)(yaml@2.8.3))':
dependencies:
'@tailwindcss/node': 4.2.2
'@tailwindcss/oxide': 4.2.2
tailwindcss: 4.2.2
- vite: 6.4.1(@types/node@22.19.15)(jiti@2.6.1)(lightningcss@1.32.0)(yaml@2.8.3)
+ vite: 6.4.2(@types/node@22.19.15)(jiti@2.6.1)(lightningcss@1.32.0)(yaml@2.8.3)
'@tauri-apps/api@2.11.0': {}
@@ -6664,6 +6679,8 @@ snapshots:
'@types/estree@1.0.8': {}
+ '@types/estree@1.0.9': {}
+
'@types/geojson@7946.0.16': {}
'@types/hast@2.3.10':
@@ -6811,14 +6828,14 @@ snapshots:
'@uiw/copy-to-clipboard@1.0.20': {}
- '@uiw/react-markdown-preview@5.1.5(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)':
+ '@uiw/react-markdown-preview@5.2.1(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)':
dependencies:
'@babel/runtime': 7.29.2
'@uiw/copy-to-clipboard': 1.0.20
react: 19.2.4
react-dom: 19.2.4(react@19.2.4)
- react-markdown: 9.0.3(@types/react@19.2.14)(react@19.2.4)
- rehype-attr: 3.0.3
+ react-markdown: 10.1.0(@types/react@19.2.14)(react@19.2.4)
+ rehype-attr: 4.0.0
rehype-autolink-headings: 7.1.0
rehype-ignore: 2.0.3
rehype-prism-plus: 2.0.0
@@ -6834,6 +6851,8 @@ snapshots:
'@ungap/structured-clone@1.3.0': {}
+ '@ungap/structured-clone@1.3.1': {}
+
'@upsetjs/venn.js@2.0.0':
optionalDependencies:
d3-selection: 3.0.0
@@ -6846,7 +6865,7 @@ snapshots:
'@use-gesture/core': 10.3.1
react: 19.2.4
- '@vitejs/plugin-react@4.7.0(vite@6.4.1(@types/node@22.19.15)(jiti@2.6.1)(lightningcss@1.32.0)(yaml@2.8.3))':
+ '@vitejs/plugin-react@4.7.0(vite@6.4.2(@types/node@22.19.15)(jiti@2.6.1)(lightningcss@1.32.0)(yaml@2.8.3))':
dependencies:
'@babel/core': 7.29.0
'@babel/plugin-transform-react-jsx-self': 7.27.1(@babel/core@7.29.0)
@@ -6854,7 +6873,7 @@ snapshots:
'@rolldown/pluginutils': 1.0.0-beta.27
'@types/babel__core': 7.20.5
react-refresh: 0.17.0
- vite: 6.4.1(@types/node@22.19.15)(jiti@2.6.1)(lightningcss@1.32.0)(yaml@2.8.3)
+ vite: 6.4.2(@types/node@22.19.15)(jiti@2.6.1)(lightningcss@1.32.0)(yaml@2.8.3)
transitivePeerDependencies:
- supports-color
@@ -7630,7 +7649,7 @@ snapshots:
estree-util-attach-comments@3.0.0:
dependencies:
- '@types/estree': 1.0.8
+ '@types/estree': 1.0.9
estree-util-build-jsx@3.0.1:
dependencies:
@@ -7742,7 +7761,7 @@ snapshots:
function-bind@1.1.2: {}
- fuse.js@7.1.0: {}
+ fuse.js@7.3.0: {}
gensync@1.0.0-beta.2: {}
@@ -7871,10 +7890,16 @@ snapshots:
vfile-location: 5.0.3
web-namespaces: 2.0.1
+ hast-util-has-property@2.0.1: {}
+
hast-util-has-property@3.0.0:
dependencies:
'@types/hast': 3.0.4
+ hast-util-heading-rank@2.1.1:
+ dependencies:
+ '@types/hast': 2.3.10
+
hast-util-heading-rank@3.0.0:
dependencies:
'@types/hast': 3.0.4
@@ -7934,7 +7959,7 @@ snapshots:
hast-util-to-estree@3.1.3:
dependencies:
- '@types/estree': 1.0.8
+ '@types/estree': 1.0.9
'@types/estree-jsx': 1.0.5
'@types/hast': 3.0.4
comma-separated-tokens: 2.0.3
@@ -7969,7 +7994,7 @@ snapshots:
hast-util-to-jsx-runtime@2.3.6:
dependencies:
- '@types/estree': 1.0.8
+ '@types/estree': 1.0.9
'@types/hast': 3.0.4
'@types/unist': 3.0.3
comma-separated-tokens: 2.0.3
@@ -7997,6 +8022,10 @@ snapshots:
web-namespaces: 2.0.1
zwitch: 2.0.4
+ hast-util-to-string@2.0.0:
+ dependencies:
+ '@types/hast': 2.3.10
+
hast-util-to-string@3.0.1:
dependencies:
'@types/hast': 3.0.4
@@ -8070,7 +8099,7 @@ snapshots:
dependencies:
safer-buffer: 2.1.2
- idb-keyval@6.2.2: {}
+ idb-keyval@6.2.4: {}
ignore@5.3.2: {}
@@ -8690,7 +8719,7 @@ snapshots:
dependencies:
'@types/hast': 3.0.4
'@types/mdast': 4.0.4
- '@ungap/structured-clone': 1.3.0
+ '@ungap/structured-clone': 1.3.1
devlop: 1.1.0
micromark-util-sanitize-uri: 2.0.1
trim-lines: 3.0.1
@@ -8760,7 +8789,7 @@ snapshots:
roughjs: 4.6.6
stylis: 4.3.6
ts-dedent: 2.2.0
- uuid: 11.1.0
+ uuid: 11.1.1
micromark-core-commonmark@1.1.0:
dependencies:
@@ -8957,7 +8986,7 @@ snapshots:
micromark-extension-mdx-expression@3.0.1:
dependencies:
- '@types/estree': 1.0.8
+ '@types/estree': 1.0.9
devlop: 1.1.0
micromark-factory-mdx-expression: 2.0.3
micromark-factory-space: 2.0.1
@@ -8968,7 +8997,7 @@ snapshots:
micromark-extension-mdx-jsx@3.0.2:
dependencies:
- '@types/estree': 1.0.8
+ '@types/estree': 1.0.9
devlop: 1.1.0
estree-util-is-identifier-name: 3.0.0
micromark-factory-mdx-expression: 2.0.3
@@ -8985,7 +9014,7 @@ snapshots:
micromark-extension-mdxjs-esm@3.0.0:
dependencies:
- '@types/estree': 1.0.8
+ '@types/estree': 1.0.9
devlop: 1.1.0
micromark-core-commonmark: 2.0.3
micromark-util-character: 2.1.1
@@ -9034,7 +9063,7 @@ snapshots:
micromark-factory-mdx-expression@2.0.3:
dependencies:
- '@types/estree': 1.0.8
+ '@types/estree': 1.0.9
devlop: 1.1.0
micromark-factory-space: 2.0.1
micromark-util-character: 2.1.1
@@ -9150,7 +9179,7 @@ snapshots:
micromark-util-events-to-acorn@2.0.3:
dependencies:
- '@types/estree': 1.0.8
+ '@types/estree': 1.0.9
'@types/unist': 3.0.3
devlop: 1.1.0
estree-util-visit: 2.0.0
@@ -9936,23 +9965,6 @@ snapshots:
transitivePeerDependencies:
- supports-color
- react-markdown@9.0.3(@types/react@19.2.14)(react@19.2.4):
- dependencies:
- '@types/hast': 3.0.4
- '@types/react': 19.2.14
- devlop: 1.1.0
- hast-util-to-jsx-runtime: 2.3.6
- html-url-attributes: 3.0.1
- mdast-util-to-hast: 13.2.1
- react: 19.2.4
- remark-parse: 11.0.0
- remark-rehype: 11.1.2
- unified: 11.0.5
- unist-util-visit: 5.1.0
- vfile: 6.0.3
- transitivePeerDependencies:
- - supports-color
-
react-medium-image-zoom@5.4.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4):
dependencies:
react: 19.2.4
@@ -10078,7 +10090,7 @@ snapshots:
recma-parse@1.0.0:
dependencies:
- '@types/estree': 1.0.8
+ '@types/estree': 1.0.9
esast-util-from-js: 2.0.1
unified: 11.0.5
vfile: 6.0.3
@@ -10120,7 +10132,7 @@ snapshots:
dependencies:
regex-utilities: 2.3.0
- rehype-attr@3.0.3:
+ rehype-attr@4.0.0:
dependencies:
unified: 11.0.5
unist-util-visit: 5.0.0
@@ -10201,6 +10213,16 @@ snapshots:
unified: 11.0.5
unist-util-visit: 5.1.0
+ rehype-slug@5.1.0:
+ dependencies:
+ '@types/hast': 2.3.10
+ github-slugger: 2.0.0
+ hast-util-has-property: 2.0.1
+ hast-util-heading-rank: 2.1.1
+ hast-util-to-string: 2.0.0
+ unified: 10.1.2
+ unist-util-visit: 4.1.2
+
rehype-slug@6.0.0:
dependencies:
'@types/hast': 3.0.4
@@ -10696,9 +10718,9 @@ snapshots:
util-deprecate@1.0.2: {}
- uuid@11.1.0: {}
+ uuid@11.1.1: {}
- uuid@13.0.0: {}
+ uuid@13.0.2: {}
uvu@0.5.6:
dependencies:
@@ -10741,7 +10763,7 @@ snapshots:
'@types/unist': 3.0.3
vfile-message: 4.0.3
- vite@6.4.1(@types/node@22.19.15)(jiti@2.6.1)(lightningcss@1.32.0)(yaml@2.8.3):
+ vite@6.4.2(@types/node@22.19.15)(jiti@2.6.1)(lightningcss@1.32.0)(yaml@2.8.3):
dependencies:
esbuild: 0.25.12
fdir: 6.5.0(picomatch@4.0.3)
diff --git a/BillNote_frontend/src/App.tsx b/BillNote_frontend/src/App.tsx
index d871506..a8a2481 100644
--- a/BillNote_frontend/src/App.tsx
+++ b/BillNote_frontend/src/App.tsx
@@ -1,6 +1,6 @@
import './App.css'
import { lazy, Suspense, useEffect } from 'react'
-import { BrowserRouter, Navigate, Routes, Route } from 'react-router-dom'
+import { BrowserRouter, HashRouter, Navigate, Routes, Route } from 'react-router-dom'
import { useTaskPolling } from '@/hooks/useTaskPolling.ts'
import { useCheckBackend } from '@/hooks/useCheckBackend.ts'
import { systemCheck } from '@/services/system.ts'
@@ -57,12 +57,16 @@ function App() {
)
}
+ // 桌面端使用 HashRouter 避免刷新 404;Web 端继续使用 BrowserRouter
+ const isTauri = typeof window !== 'undefined' && '__TAURI_INTERNALS__' in window
+ const Router = isTauri ? HashRouter : BrowserRouter
+
// 后端已初始化,渲染主应用
return (
<>
-
+
加载中…}>
} />
@@ -86,7 +90,7 @@ function App() {
-
+
>
)
}
diff --git a/BillNote_frontend/src/pages/HomePage/components/MarkdownViewer.tsx b/BillNote_frontend/src/pages/HomePage/components/MarkdownViewer.tsx
index ac95cd3..c34a0e5 100644
--- a/BillNote_frontend/src/pages/HomePage/components/MarkdownViewer.tsx
+++ b/BillNote_frontend/src/pages/HomePage/components/MarkdownViewer.tsx
@@ -14,6 +14,7 @@ import 'react-medium-image-zoom/dist/styles.css'
import gfm from 'remark-gfm'
import remarkMath from 'remark-math'
import rehypeKatex from 'rehype-katex'
+import rehypeSlug from 'rehype-slug'
import 'katex/dist/katex.min.css'
import 'github-markdown-css/github-markdown-light.css'
import { ScrollArea } from '@/components/ui/scroll-area.tsx'
@@ -47,7 +48,7 @@ const steps = [
]
const remarkPlugins = [gfm, remarkMath]
-const rehypePlugins = [rehypeKatex]
+const rehypePlugins = [rehypeKatex, rehypeSlug]
/**
* 构建 ReactMarkdown components 对象,baseURL 用于修正图片路径。
@@ -117,6 +118,51 @@ function createMarkdownComponents(baseURL: string) {
)
}
+ // 处理笔记内部锚点链接(如目录跳转)
+ if (href?.startsWith('#')) {
+ const handleAnchorClick = (e: React.MouseEvent) => {
+ e.preventDefault()
+ const id = decodeURIComponent(href.slice(1))
+
+ // 1. 优先精确匹配 id
+ let target = document.getElementById(id)
+
+ // 2. 精确失败时按 heading 文本模糊匹配
+ // LLM 生成的目录锚点可能和 heading 实际文本不完全一致
+ //(例如 heading 带 *Content-[00:00]* 后缀,目录链接里没有)
+ if (!target) {
+ const normalize = (s: string) =>
+ s.replace(/[-::\s*\[\]]/g, '').toLowerCase()
+ const search = normalize(id)
+ const headings = document.querySelectorAll('h1, h2, h3, h4, h5, h6')
+ for (const h of headings) {
+ const text = h.textContent || ''
+ if (normalize(text).includes(search) || search.includes(normalize(text))) {
+ target = h
+ break
+ }
+ }
+ }
+
+ if (target) {
+ target.scrollIntoView({ behavior: 'smooth', block: 'start' })
+ } else {
+ toast.error('未找到对应章节')
+ }
+ }
+
+ return (
+
+ {children}
+
+ )
+ }
+
return (