Add client-side PDF conversion tools
This commit is contained in:
@@ -20,13 +20,16 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@imgly/background-removal": "^1.7.0",
|
"@imgly/background-removal": "^1.7.0",
|
||||||
"@tailwindcss/vite": "^4.3.0",
|
"@tailwindcss/vite": "^4.3.0",
|
||||||
|
"docx": "^9.7.1",
|
||||||
"fabric": "^7.4.0",
|
"fabric": "^7.4.0",
|
||||||
"onnxruntime-web": "1.21.0",
|
"onnxruntime-web": "1.21.0",
|
||||||
"pdf-lib": "^1.17.1",
|
"pdf-lib": "^1.17.1",
|
||||||
|
"pdfjs-dist": "^6.1.200",
|
||||||
"react": "^19.2.6",
|
"react": "^19.2.6",
|
||||||
"react-dom": "^19.2.6",
|
"react-dom": "^19.2.6",
|
||||||
"react-router-dom": "^7.15.0",
|
"react-router-dom": "^7.15.0",
|
||||||
"tailwindcss": "^4.3.0",
|
"tailwindcss": "^4.3.0",
|
||||||
|
"tesseract.js": "^7.0.0",
|
||||||
"zxing-wasm": "^3.1.0"
|
"zxing-wasm": "^3.1.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
|||||||
366
pnpm-lock.yaml
generated
366
pnpm-lock.yaml
generated
@@ -14,6 +14,9 @@ importers:
|
|||||||
'@tailwindcss/vite':
|
'@tailwindcss/vite':
|
||||||
specifier: ^4.3.0
|
specifier: ^4.3.0
|
||||||
version: 4.3.0(vite@8.0.12(@types/node@24.12.4)(jiti@2.7.0))
|
version: 4.3.0(vite@8.0.12(@types/node@24.12.4)(jiti@2.7.0))
|
||||||
|
docx:
|
||||||
|
specifier: ^9.7.1
|
||||||
|
version: 9.7.1
|
||||||
fabric:
|
fabric:
|
||||||
specifier: ^7.4.0
|
specifier: ^7.4.0
|
||||||
version: 7.4.0
|
version: 7.4.0
|
||||||
@@ -23,6 +26,9 @@ importers:
|
|||||||
pdf-lib:
|
pdf-lib:
|
||||||
specifier: ^1.17.1
|
specifier: ^1.17.1
|
||||||
version: 1.17.1
|
version: 1.17.1
|
||||||
|
pdfjs-dist:
|
||||||
|
specifier: ^6.1.200
|
||||||
|
version: 6.1.200
|
||||||
react:
|
react:
|
||||||
specifier: ^19.2.6
|
specifier: ^19.2.6
|
||||||
version: 19.2.6
|
version: 19.2.6
|
||||||
@@ -35,6 +41,9 @@ importers:
|
|||||||
tailwindcss:
|
tailwindcss:
|
||||||
specifier: ^4.3.0
|
specifier: ^4.3.0
|
||||||
version: 4.3.0
|
version: 4.3.0
|
||||||
|
tesseract.js:
|
||||||
|
specifier: ^7.0.0
|
||||||
|
version: 7.0.0
|
||||||
zxing-wasm:
|
zxing-wasm:
|
||||||
specifier: ^3.1.0
|
specifier: ^3.1.0
|
||||||
version: 3.1.0(@types/emscripten@1.41.5)
|
version: 3.1.0(@types/emscripten@1.41.5)
|
||||||
@@ -274,6 +283,81 @@ packages:
|
|||||||
'@jridgewell/trace-mapping@0.3.31':
|
'@jridgewell/trace-mapping@0.3.31':
|
||||||
resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==}
|
resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==}
|
||||||
|
|
||||||
|
'@napi-rs/canvas-android-arm64@1.0.2':
|
||||||
|
resolution: {integrity: sha512-IMXKVQod0ol4vt3gmClUfXz4JAgHYESGPCUqmH3lQxBoL0K/2greJaQE1HVBVxWWFKfLc4OLZVdxg7kXVyXv+g==}
|
||||||
|
engines: {node: '>= 10'}
|
||||||
|
cpu: [arm64]
|
||||||
|
os: [android]
|
||||||
|
|
||||||
|
'@napi-rs/canvas-darwin-arm64@1.0.2':
|
||||||
|
resolution: {integrity: sha512-Sc8tPi6cF+5lqOzCCKFALJHhDiRwyMzTPYm3bbhdXsOunU0lQO5f05ucyOzN2r55I23Hg5bsjH63uSCvWp3EgQ==}
|
||||||
|
engines: {node: '>= 10'}
|
||||||
|
cpu: [arm64]
|
||||||
|
os: [darwin]
|
||||||
|
|
||||||
|
'@napi-rs/canvas-darwin-x64@1.0.2':
|
||||||
|
resolution: {integrity: sha512-niDXZ9LhKB1zLrUdYB64RHQFDGz9rr0eGx061qtJJU3U20EMMIx28ADF5fVYbhtOgkWQrBjFicfaye1yM0U62A==}
|
||||||
|
engines: {node: '>= 10'}
|
||||||
|
cpu: [x64]
|
||||||
|
os: [darwin]
|
||||||
|
|
||||||
|
'@napi-rs/canvas-linux-arm-gnueabihf@1.0.2':
|
||||||
|
resolution: {integrity: sha512-sgatQL9JxGRH/Amzcvu0P3t8Am3duou74CisfuJ41Dwt8cWy723z/9KZ8LlgmxfypEwEZxSTNFJtU8d281lmhQ==}
|
||||||
|
engines: {node: '>= 10'}
|
||||||
|
cpu: [arm]
|
||||||
|
os: [linux]
|
||||||
|
|
||||||
|
'@napi-rs/canvas-linux-arm64-gnu@1.0.2':
|
||||||
|
resolution: {integrity: sha512-dgKuX0peF3xwY6ZF5QxGS4wbfDqpoFAJYXiLSp+guZKARQUKMkRqZSDrXKj7nfrec3UCMzC0PFCPte0ES98AiA==}
|
||||||
|
engines: {node: '>= 10'}
|
||||||
|
cpu: [arm64]
|
||||||
|
os: [linux]
|
||||||
|
libc: [glibc]
|
||||||
|
|
||||||
|
'@napi-rs/canvas-linux-arm64-musl@1.0.2':
|
||||||
|
resolution: {integrity: sha512-qwROoDIC9upfvDoRLuPn2aNg9CGW1x0Ygr4k2Or+8paA9d0qBLwk87U+g8KQpoOviKoPoiwl97kvBYuYD7qZoA==}
|
||||||
|
engines: {node: '>= 10'}
|
||||||
|
cpu: [arm64]
|
||||||
|
os: [linux]
|
||||||
|
libc: [musl]
|
||||||
|
|
||||||
|
'@napi-rs/canvas-linux-riscv64-gnu@1.0.2':
|
||||||
|
resolution: {integrity: sha512-fXRjnPihdnbO6qy1QQOgxAonb68A0TCEG7rj1x7v7rxNElsE8EVIKIEUTvyDtU+sthYSbX+8e7g3oZiLGnOmxw==}
|
||||||
|
engines: {node: '>= 10'}
|
||||||
|
cpu: [riscv64]
|
||||||
|
os: [linux]
|
||||||
|
libc: [glibc]
|
||||||
|
|
||||||
|
'@napi-rs/canvas-linux-x64-gnu@1.0.2':
|
||||||
|
resolution: {integrity: sha512-nPR97DXhbWIAy7yazF3jc06kEPMqYMLmPzFOVNlwKPfIoSChnI+x7dc0hTLaihz3jxrjL6j4BbA7earxfx4X3g==}
|
||||||
|
engines: {node: '>= 10'}
|
||||||
|
cpu: [x64]
|
||||||
|
os: [linux]
|
||||||
|
libc: [glibc]
|
||||||
|
|
||||||
|
'@napi-rs/canvas-linux-x64-musl@1.0.2':
|
||||||
|
resolution: {integrity: sha512-l7zZY5+jL5qnBZtDz7CoBtY6p7EkHu422g/0zWwrOrzIwWyWxZFRfZZORY1UG7YApymPLx+UbOkN206xXn/c1Q==}
|
||||||
|
engines: {node: '>= 10'}
|
||||||
|
cpu: [x64]
|
||||||
|
os: [linux]
|
||||||
|
libc: [musl]
|
||||||
|
|
||||||
|
'@napi-rs/canvas-win32-arm64-msvc@1.0.2':
|
||||||
|
resolution: {integrity: sha512-yE0koHCFF4PIbMc2o2SEALhnipz7WBISh5glLvQiomtIoCcW0np3H4Lw93ceJAfJttTTeIIWFbwH84F7EVzjMQ==}
|
||||||
|
engines: {node: '>= 10'}
|
||||||
|
cpu: [arm64]
|
||||||
|
os: [win32]
|
||||||
|
|
||||||
|
'@napi-rs/canvas-win32-x64-msvc@1.0.2':
|
||||||
|
resolution: {integrity: sha512-okU8/t2foV6C31n0GtvEMbfD5rOFc70+/6xUNME9Guld29sgSOIGUEDScAWFlcP3k5TYQRl9TNkwJEEjh15w8A==}
|
||||||
|
engines: {node: '>= 10'}
|
||||||
|
cpu: [x64]
|
||||||
|
os: [win32]
|
||||||
|
|
||||||
|
'@napi-rs/canvas@1.0.2':
|
||||||
|
resolution: {integrity: sha512-EYEqlMYaCbpZDz+IgDH5xp9MTd3ui4dmGqbQYryhMLnSRxrhHKq5KQWHHKxFUcEP4Hp8/BWgvqXocX4j7iSbOQ==}
|
||||||
|
engines: {node: '>= 10'}
|
||||||
|
|
||||||
'@napi-rs/wasm-runtime@1.1.4':
|
'@napi-rs/wasm-runtime@1.1.4':
|
||||||
resolution: {integrity: sha512-3NQNNgA1YSlJb/kMH1ildASP9HW7/7kYnRI2szWJaofaS1hWmbGI4H+d3+22aGzXXN9IJ+n+GiFVcGipJP18ow==}
|
resolution: {integrity: sha512-3NQNNgA1YSlJb/kMH1ildASP9HW7/7kYnRI2szWJaofaS1hWmbGI4H+d3+22aGzXXN9IJ+n+GiFVcGipJP18ow==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
@@ -546,6 +630,9 @@ packages:
|
|||||||
'@types/node@24.12.4':
|
'@types/node@24.12.4':
|
||||||
resolution: {integrity: sha512-GUUEShf+PBCGW2KaXwcIt3Yk+e3pkKwWKb9GSyM9WQVE+ep2jzmHdGsHzu4wgcZy5fN9FBdVzjpBQsYlpfpgLA==}
|
resolution: {integrity: sha512-GUUEShf+PBCGW2KaXwcIt3Yk+e3pkKwWKb9GSyM9WQVE+ep2jzmHdGsHzu4wgcZy5fN9FBdVzjpBQsYlpfpgLA==}
|
||||||
|
|
||||||
|
'@types/node@25.9.5':
|
||||||
|
resolution: {integrity: sha512-OScDchr2fwuUmWdf4kZ9h7PcJiYDVInhJizG/biAq3cAvqwYktuy/TYGGdZNMtNTFUP7rnb0NU4TUdm82kt4Rg==}
|
||||||
|
|
||||||
'@types/react-dom@19.2.3':
|
'@types/react-dom@19.2.3':
|
||||||
resolution: {integrity: sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==}
|
resolution: {integrity: sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
@@ -691,6 +778,9 @@ packages:
|
|||||||
bl@4.1.0:
|
bl@4.1.0:
|
||||||
resolution: {integrity: sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==}
|
resolution: {integrity: sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==}
|
||||||
|
|
||||||
|
bmp-js@0.1.0:
|
||||||
|
resolution: {integrity: sha512-vHdS19CnY3hwiNdkaqk93DvjVLfbEcI8mys4UjuWrlX1haDmroo8o4xCzh4wD6DGV6HxRCyauwhHRqMTfERtjw==}
|
||||||
|
|
||||||
brace-expansion@5.0.6:
|
brace-expansion@5.0.6:
|
||||||
resolution: {integrity: sha512-kLpxurY4Z4r9sgMsyG0Z9uzsBlgiU/EFKhj/h91/8yHu0edo7XuixOIH3VcJ8kkxs6/jPzoI6U9Vj3WqbMQ94g==}
|
resolution: {integrity: sha512-kLpxurY4Z4r9sgMsyG0Z9uzsBlgiU/EFKhj/h91/8yHu0edo7XuixOIH3VcJ8kkxs6/jPzoI6U9Vj3WqbMQ94g==}
|
||||||
engines: {node: 18 || 20 || >=22}
|
engines: {node: 18 || 20 || >=22}
|
||||||
@@ -724,6 +814,9 @@ packages:
|
|||||||
resolution: {integrity: sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ==}
|
resolution: {integrity: sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ==}
|
||||||
engines: {node: '>=18'}
|
engines: {node: '>=18'}
|
||||||
|
|
||||||
|
core-util-is@1.0.3:
|
||||||
|
resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==}
|
||||||
|
|
||||||
cross-spawn@7.0.6:
|
cross-spawn@7.0.6:
|
||||||
resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==}
|
resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==}
|
||||||
engines: {node: '>= 8'}
|
engines: {node: '>= 8'}
|
||||||
@@ -766,6 +859,10 @@ packages:
|
|||||||
resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==}
|
resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==}
|
||||||
engines: {node: '>=8'}
|
engines: {node: '>=8'}
|
||||||
|
|
||||||
|
docx@9.7.1:
|
||||||
|
resolution: {integrity: sha512-ilXFf9Moz47ABjFpDiA5s1w9lpb4EFSp7+5iiJSbfyYDM+bpZdAgLlSr7fW4aXhVe/E+F6QCv0EvRVFEd5CsWg==}
|
||||||
|
engines: {node: '>=10'}
|
||||||
|
|
||||||
electron-to-chromium@1.5.353:
|
electron-to-chromium@1.5.353:
|
||||||
resolution: {integrity: sha512-kOrWphBi8TOZyiJZqsgqIle0lw+tzmnQK83pV9dZUd01Nm2POECSyFQMAuarzZdYqQW7FH9RaYOuaRo3h+bQ3w==}
|
resolution: {integrity: sha512-kOrWphBi8TOZyiJZqsgqIle0lw+tzmnQK83pV9dZUd01Nm2POECSyFQMAuarzZdYqQW7FH9RaYOuaRo3h+bQ3w==}
|
||||||
|
|
||||||
@@ -929,6 +1026,9 @@ packages:
|
|||||||
guid-typescript@1.0.9:
|
guid-typescript@1.0.9:
|
||||||
resolution: {integrity: sha512-Y8T4vYhEfwJOTbouREvG+3XDsjr8E3kIr7uf+JZ0BYloFsttiHU0WfvANVsR7TxNUJa/WpCnw/Ino/p+DeBhBQ==}
|
resolution: {integrity: sha512-Y8T4vYhEfwJOTbouREvG+3XDsjr8E3kIr7uf+JZ0BYloFsttiHU0WfvANVsR7TxNUJa/WpCnw/Ino/p+DeBhBQ==}
|
||||||
|
|
||||||
|
hash.js@1.1.7:
|
||||||
|
resolution: {integrity: sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==}
|
||||||
|
|
||||||
hermes-estree@0.25.1:
|
hermes-estree@0.25.1:
|
||||||
resolution: {integrity: sha512-0wUoCcLp+5Ev5pDW2OriHC2MJCbwLwuRx+gAqMTOkGKJJiBCLjtrvy4PWUGn6MIVefecRpzoOZ/UV6iGdOr+Cw==}
|
resolution: {integrity: sha512-0wUoCcLp+5Ev5pDW2OriHC2MJCbwLwuRx+gAqMTOkGKJJiBCLjtrvy4PWUGn6MIVefecRpzoOZ/UV6iGdOr+Cw==}
|
||||||
|
|
||||||
@@ -951,6 +1051,9 @@ packages:
|
|||||||
resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==}
|
resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==}
|
||||||
engines: {node: '>=0.10.0'}
|
engines: {node: '>=0.10.0'}
|
||||||
|
|
||||||
|
idb-keyval@6.3.0:
|
||||||
|
resolution: {integrity: sha512-um+2dgAWmYsu615EXpWVwSmapJhON0G43t3Ka/EVaohzPQXSMqKEqeDK/oIW3Ow+BXaF2PvSc+oBTFp793A5Ow==}
|
||||||
|
|
||||||
ieee754@1.2.1:
|
ieee754@1.2.1:
|
||||||
resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==}
|
resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==}
|
||||||
|
|
||||||
@@ -962,6 +1065,9 @@ packages:
|
|||||||
resolution: {integrity: sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==}
|
resolution: {integrity: sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==}
|
||||||
engines: {node: '>= 4'}
|
engines: {node: '>= 4'}
|
||||||
|
|
||||||
|
immediate@3.0.6:
|
||||||
|
resolution: {integrity: sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==}
|
||||||
|
|
||||||
imurmurhash@0.1.4:
|
imurmurhash@0.1.4:
|
||||||
resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==}
|
resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==}
|
||||||
engines: {node: '>=0.8.19'}
|
engines: {node: '>=0.8.19'}
|
||||||
@@ -989,6 +1095,12 @@ packages:
|
|||||||
is-potential-custom-element-name@1.0.1:
|
is-potential-custom-element-name@1.0.1:
|
||||||
resolution: {integrity: sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==}
|
resolution: {integrity: sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==}
|
||||||
|
|
||||||
|
is-url@1.2.4:
|
||||||
|
resolution: {integrity: sha512-ITvGim8FhRiYe4IQ5uHSkj7pVaPDrCTkNd3yq3cV7iZAcJdHTUMPMEHcqSOy9xZ9qFenQCvi+2wjH9a1nXqHww==}
|
||||||
|
|
||||||
|
isarray@1.0.0:
|
||||||
|
resolution: {integrity: sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==}
|
||||||
|
|
||||||
isexe@2.0.0:
|
isexe@2.0.0:
|
||||||
resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==}
|
resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==}
|
||||||
|
|
||||||
@@ -1027,6 +1139,9 @@ packages:
|
|||||||
engines: {node: '>=6'}
|
engines: {node: '>=6'}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
|
|
||||||
|
jszip@3.10.1:
|
||||||
|
resolution: {integrity: sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g==}
|
||||||
|
|
||||||
keyv@4.5.4:
|
keyv@4.5.4:
|
||||||
resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==}
|
resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==}
|
||||||
|
|
||||||
@@ -1034,6 +1149,9 @@ packages:
|
|||||||
resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==}
|
resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==}
|
||||||
engines: {node: '>= 0.8.0'}
|
engines: {node: '>= 0.8.0'}
|
||||||
|
|
||||||
|
lie@3.3.0:
|
||||||
|
resolution: {integrity: sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==}
|
||||||
|
|
||||||
lightningcss-android-arm64@1.32.0:
|
lightningcss-android-arm64@1.32.0:
|
||||||
resolution: {integrity: sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg==}
|
resolution: {integrity: sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg==}
|
||||||
engines: {node: '>= 12.0.0'}
|
engines: {node: '>= 12.0.0'}
|
||||||
@@ -1131,6 +1249,9 @@ packages:
|
|||||||
resolution: {integrity: sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==}
|
resolution: {integrity: sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==}
|
||||||
engines: {node: '>=10'}
|
engines: {node: '>=10'}
|
||||||
|
|
||||||
|
minimalistic-assert@1.0.1:
|
||||||
|
resolution: {integrity: sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==}
|
||||||
|
|
||||||
minimatch@10.2.5:
|
minimatch@10.2.5:
|
||||||
resolution: {integrity: sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==}
|
resolution: {integrity: sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==}
|
||||||
engines: {node: 18 || 20 || >=22}
|
engines: {node: 18 || 20 || >=22}
|
||||||
@@ -1149,6 +1270,11 @@ packages:
|
|||||||
engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
|
engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
|
|
||||||
|
nanoid@5.1.16:
|
||||||
|
resolution: {integrity: sha512-kVrnsrJqMR8+oLJnGEmSWw9BivK5mt7H3FZatVRjrc5wGqFYuBxX1yG7+A7Gi5AefkX6t/oCkizcQgpu0cY1dQ==}
|
||||||
|
engines: {node: ^18 || >=20}
|
||||||
|
hasBin: true
|
||||||
|
|
||||||
napi-build-utils@2.0.0:
|
napi-build-utils@2.0.0:
|
||||||
resolution: {integrity: sha512-GEbrYkbfF7MoNaoh2iGG84Mnf/WZfB0GdGEsM8wz7Expx/LlWf5U8t9nvJKXSp3qr5IsEbK04cBGhol/KwOsWA==}
|
resolution: {integrity: sha512-GEbrYkbfF7MoNaoh2iGG84Mnf/WZfB0GdGEsM8wz7Expx/LlWf5U8t9nvJKXSp3qr5IsEbK04cBGhol/KwOsWA==}
|
||||||
|
|
||||||
@@ -1165,6 +1291,15 @@ packages:
|
|||||||
node-addon-api@7.1.1:
|
node-addon-api@7.1.1:
|
||||||
resolution: {integrity: sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==}
|
resolution: {integrity: sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==}
|
||||||
|
|
||||||
|
node-fetch@2.7.0:
|
||||||
|
resolution: {integrity: sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==}
|
||||||
|
engines: {node: 4.x || >=6.0.0}
|
||||||
|
peerDependencies:
|
||||||
|
encoding: ^0.1.0
|
||||||
|
peerDependenciesMeta:
|
||||||
|
encoding:
|
||||||
|
optional: true
|
||||||
|
|
||||||
node-releases@2.0.44:
|
node-releases@2.0.44:
|
||||||
resolution: {integrity: sha512-5WUyunoPMsvvEhS8AxHtRzP+oA8UCkJ7YRxatWKjngndhDGLiqEVAQKWjFAiAiuL8zMRGzGSJxFnLetoa43qGQ==}
|
resolution: {integrity: sha512-5WUyunoPMsvvEhS8AxHtRzP+oA8UCkJ7YRxatWKjngndhDGLiqEVAQKWjFAiAiuL8zMRGzGSJxFnLetoa43qGQ==}
|
||||||
|
|
||||||
@@ -1183,6 +1318,10 @@ packages:
|
|||||||
onnxruntime-web@1.21.0:
|
onnxruntime-web@1.21.0:
|
||||||
resolution: {integrity: sha512-adzOe+7uI7lKz6pQNbAsLMQd2Fq5Jhmoxd8LZjJr8m3KvbFyiYyRxRiC57/XXD+jb18voppjeGAjoZmskXG+7A==}
|
resolution: {integrity: sha512-adzOe+7uI7lKz6pQNbAsLMQd2Fq5Jhmoxd8LZjJr8m3KvbFyiYyRxRiC57/XXD+jb18voppjeGAjoZmskXG+7A==}
|
||||||
|
|
||||||
|
opencollective-postinstall@2.0.3:
|
||||||
|
resolution: {integrity: sha512-8AV/sCtuzUeTo8gQK5qDZzARrulB3egtLzFgteqB2tcT4Mw7B8Kt7JcDHmltjz6FOAHsvTevk70gZEbhM4ZS9Q==}
|
||||||
|
hasBin: true
|
||||||
|
|
||||||
optionator@0.9.4:
|
optionator@0.9.4:
|
||||||
resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==}
|
resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==}
|
||||||
engines: {node: '>= 0.8.0'}
|
engines: {node: '>= 0.8.0'}
|
||||||
@@ -1215,6 +1354,10 @@ packages:
|
|||||||
pdf-lib@1.17.1:
|
pdf-lib@1.17.1:
|
||||||
resolution: {integrity: sha512-V/mpyJAoTsN4cnP31vc0wfNA1+p20evqqnap0KLoRUN0Yk/p3wN52DOEsL4oBFcLdb76hlpKPtzJIgo67j/XLw==}
|
resolution: {integrity: sha512-V/mpyJAoTsN4cnP31vc0wfNA1+p20evqqnap0KLoRUN0Yk/p3wN52DOEsL4oBFcLdb76hlpKPtzJIgo67j/XLw==}
|
||||||
|
|
||||||
|
pdfjs-dist@6.1.200:
|
||||||
|
resolution: {integrity: sha512-o8MolyzirkkLrcdsae/HEOiIcXWI7DS5zGpvqW8xTC2YUsW30rltFw2bDGvw/fskUdEMrQm2br68jzDS5BH2vw==}
|
||||||
|
engines: {node: '>=22.13.0 || >=24'}
|
||||||
|
|
||||||
picocolors@1.1.1:
|
picocolors@1.1.1:
|
||||||
resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==}
|
resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==}
|
||||||
|
|
||||||
@@ -1254,6 +1397,9 @@ packages:
|
|||||||
engines: {node: '>=14'}
|
engines: {node: '>=14'}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
|
|
||||||
|
process-nextick-args@2.0.1:
|
||||||
|
resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==}
|
||||||
|
|
||||||
protobufjs@7.6.2:
|
protobufjs@7.6.2:
|
||||||
resolution: {integrity: sha512-N9EiLovGEQOJSPF26Ij7qUGvahfEnq0eeYZ02aigIedkmz1qZSwjnP9SBITHJuF/6MYbIW4HDN8zdYjsjqJKXQ==}
|
resolution: {integrity: sha512-N9EiLovGEQOJSPF26Ij7qUGvahfEnq0eeYZ02aigIedkmz1qZSwjnP9SBITHJuF/6MYbIW4HDN8zdYjsjqJKXQ==}
|
||||||
engines: {node: '>=12.0.0'}
|
engines: {node: '>=12.0.0'}
|
||||||
@@ -1295,10 +1441,16 @@ packages:
|
|||||||
resolution: {integrity: sha512-sfWGGfavi0xr8Pg0sVsyHMAOziVYKgPLNrS7ig+ivMNb3wbCBw3KxtflsGBAwD3gYQlE/AEZsTLgToRrSCjb0Q==}
|
resolution: {integrity: sha512-sfWGGfavi0xr8Pg0sVsyHMAOziVYKgPLNrS7ig+ivMNb3wbCBw3KxtflsGBAwD3gYQlE/AEZsTLgToRrSCjb0Q==}
|
||||||
engines: {node: '>=0.10.0'}
|
engines: {node: '>=0.10.0'}
|
||||||
|
|
||||||
|
readable-stream@2.3.8:
|
||||||
|
resolution: {integrity: sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==}
|
||||||
|
|
||||||
readable-stream@3.6.2:
|
readable-stream@3.6.2:
|
||||||
resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==}
|
resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==}
|
||||||
engines: {node: '>= 6'}
|
engines: {node: '>= 6'}
|
||||||
|
|
||||||
|
regenerator-runtime@0.13.11:
|
||||||
|
resolution: {integrity: sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==}
|
||||||
|
|
||||||
rolldown@1.0.0:
|
rolldown@1.0.0:
|
||||||
resolution: {integrity: sha512-yD986aXDESFGS95spT1LAv0jssywP4npMEjmMHyN2/5+eE8qQJUype2AaKkRiLgBgyD0LFlubwAht7VmY8rGoA==}
|
resolution: {integrity: sha512-yD986aXDESFGS95spT1LAv0jssywP4npMEjmMHyN2/5+eE8qQJUype2AaKkRiLgBgyD0LFlubwAht7VmY8rGoA==}
|
||||||
engines: {node: ^20.19.0 || >=22.12.0}
|
engines: {node: ^20.19.0 || >=22.12.0}
|
||||||
@@ -1307,12 +1459,19 @@ packages:
|
|||||||
rrweb-cssom@0.8.0:
|
rrweb-cssom@0.8.0:
|
||||||
resolution: {integrity: sha512-guoltQEx+9aMf2gDZ0s62EcV8lsXR+0w8915TC3ITdn2YueuNjdAYh/levpU9nFaoChh9RUS5ZdQMrKfVEN9tw==}
|
resolution: {integrity: sha512-guoltQEx+9aMf2gDZ0s62EcV8lsXR+0w8915TC3ITdn2YueuNjdAYh/levpU9nFaoChh9RUS5ZdQMrKfVEN9tw==}
|
||||||
|
|
||||||
|
safe-buffer@5.1.2:
|
||||||
|
resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==}
|
||||||
|
|
||||||
safe-buffer@5.2.1:
|
safe-buffer@5.2.1:
|
||||||
resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==}
|
resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==}
|
||||||
|
|
||||||
safer-buffer@2.1.2:
|
safer-buffer@2.1.2:
|
||||||
resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==}
|
resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==}
|
||||||
|
|
||||||
|
sax@1.6.0:
|
||||||
|
resolution: {integrity: sha512-6R3J5M4AcbtLUdZmRv2SygeVaM7IhrLXu9BmnOGmmACak8fiUtOsYNWUS4uK7upbmHIBbLBeFeI//477BKLBzA==}
|
||||||
|
engines: {node: '>=11.0.0'}
|
||||||
|
|
||||||
saxes@6.0.0:
|
saxes@6.0.0:
|
||||||
resolution: {integrity: sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==}
|
resolution: {integrity: sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==}
|
||||||
engines: {node: '>=v12.22.7'}
|
engines: {node: '>=v12.22.7'}
|
||||||
@@ -1332,6 +1491,9 @@ packages:
|
|||||||
set-cookie-parser@2.7.2:
|
set-cookie-parser@2.7.2:
|
||||||
resolution: {integrity: sha512-oeM1lpU/UvhTxw+g3cIfxXHyJRc/uidd3yK1P242gzHds0udQBYzs3y8j4gCCW+ZJ7ad0yctld8RYO+bdurlvw==}
|
resolution: {integrity: sha512-oeM1lpU/UvhTxw+g3cIfxXHyJRc/uidd3yK1P242gzHds0udQBYzs3y8j4gCCW+ZJ7ad0yctld8RYO+bdurlvw==}
|
||||||
|
|
||||||
|
setimmediate@1.0.5:
|
||||||
|
resolution: {integrity: sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==}
|
||||||
|
|
||||||
shebang-command@2.0.0:
|
shebang-command@2.0.0:
|
||||||
resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==}
|
resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==}
|
||||||
engines: {node: '>=8'}
|
engines: {node: '>=8'}
|
||||||
@@ -1359,6 +1521,9 @@ packages:
|
|||||||
std-env@4.1.0:
|
std-env@4.1.0:
|
||||||
resolution: {integrity: sha512-Rq7ybcX2RuC55r9oaPVEW7/xu3tj8u4GeBYHBWCychFtzMIr86A7e3PPEBPT37sHStKX3+TiX/Fr/ACmJLVlLQ==}
|
resolution: {integrity: sha512-Rq7ybcX2RuC55r9oaPVEW7/xu3tj8u4GeBYHBWCychFtzMIr86A7e3PPEBPT37sHStKX3+TiX/Fr/ACmJLVlLQ==}
|
||||||
|
|
||||||
|
string_decoder@1.1.1:
|
||||||
|
resolution: {integrity: sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==}
|
||||||
|
|
||||||
string_decoder@1.3.0:
|
string_decoder@1.3.0:
|
||||||
resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==}
|
resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==}
|
||||||
|
|
||||||
@@ -1387,6 +1552,12 @@ packages:
|
|||||||
resolution: {integrity: sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==}
|
resolution: {integrity: sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==}
|
||||||
engines: {node: '>=6'}
|
engines: {node: '>=6'}
|
||||||
|
|
||||||
|
tesseract.js-core@7.0.0:
|
||||||
|
resolution: {integrity: sha512-WnNH518NzmbSq9zgTPeoF8c+xmilS8rFIl1YKbk/ptuuc7p6cLNELNuPAzcmsYw450ca6bLa8j3t0VAtq435Vw==}
|
||||||
|
|
||||||
|
tesseract.js@7.0.0:
|
||||||
|
resolution: {integrity: sha512-exPBkd+z+wM1BuMkx/Bjv43OeLBxhL5kKWsz/9JY+DXcXdiBjiAch0V49QR3oAJqCaL5qURE0vx9Eo+G5YE7mA==}
|
||||||
|
|
||||||
tinybench@2.9.0:
|
tinybench@2.9.0:
|
||||||
resolution: {integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==}
|
resolution: {integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==}
|
||||||
|
|
||||||
@@ -1413,6 +1584,9 @@ packages:
|
|||||||
resolution: {integrity: sha512-FVDYdxtnj0G6Qm/DhNPSb8Ju59ULcup3tuJxkFb5K8Bv2pUXILbf0xZWU8PX8Ov19OXljbUyveOFwRMwkXzO+A==}
|
resolution: {integrity: sha512-FVDYdxtnj0G6Qm/DhNPSb8Ju59ULcup3tuJxkFb5K8Bv2pUXILbf0xZWU8PX8Ov19OXljbUyveOFwRMwkXzO+A==}
|
||||||
engines: {node: '>=16'}
|
engines: {node: '>=16'}
|
||||||
|
|
||||||
|
tr46@0.0.3:
|
||||||
|
resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==}
|
||||||
|
|
||||||
tr46@5.1.1:
|
tr46@5.1.1:
|
||||||
resolution: {integrity: sha512-hdF5ZgjTqgAntKkklYw0R03MG2x/bSzTtkxmIRw/sTNV8YXsCJ1tfLAX23lhxhHJlEf3CRCOCGGWw3vI3GaSPw==}
|
resolution: {integrity: sha512-hdF5ZgjTqgAntKkklYw0R03MG2x/bSzTtkxmIRw/sTNV8YXsCJ1tfLAX23lhxhHJlEf3CRCOCGGWw3vI3GaSPw==}
|
||||||
engines: {node: '>=18'}
|
engines: {node: '>=18'}
|
||||||
@@ -1455,6 +1629,9 @@ packages:
|
|||||||
undici-types@7.16.0:
|
undici-types@7.16.0:
|
||||||
resolution: {integrity: sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==}
|
resolution: {integrity: sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==}
|
||||||
|
|
||||||
|
undici-types@7.24.6:
|
||||||
|
resolution: {integrity: sha512-WRNW+sJgj5OBN4/0JpHFqtqzhpbnV0GuB+OozA9gCL7a993SmU+1JBZCzLNxYsbMfIeDL+lTsphD5jN5N+n0zg==}
|
||||||
|
|
||||||
update-browserslist-db@1.2.3:
|
update-browserslist-db@1.2.3:
|
||||||
resolution: {integrity: sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==}
|
resolution: {integrity: sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
@@ -1555,6 +1732,12 @@ packages:
|
|||||||
resolution: {integrity: sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA==}
|
resolution: {integrity: sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA==}
|
||||||
engines: {node: '>=18'}
|
engines: {node: '>=18'}
|
||||||
|
|
||||||
|
wasm-feature-detect@1.8.0:
|
||||||
|
resolution: {integrity: sha512-zksaLKM2fVlnB5jQQDqKXXwYHLQUVH9es+5TOOHwGOVJOCeRBCiPjwSg+3tN2AdTCzjgli4jijCH290kXb/zWQ==}
|
||||||
|
|
||||||
|
webidl-conversions@3.0.1:
|
||||||
|
resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==}
|
||||||
|
|
||||||
webidl-conversions@7.0.0:
|
webidl-conversions@7.0.0:
|
||||||
resolution: {integrity: sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==}
|
resolution: {integrity: sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==}
|
||||||
engines: {node: '>=12'}
|
engines: {node: '>=12'}
|
||||||
@@ -1572,6 +1755,9 @@ packages:
|
|||||||
resolution: {integrity: sha512-De72GdQZzNTUBBChsXueQUnPKDkg/5A5zp7pFDuQAj5UFoENpiACU0wlCvzpAGnTkj++ihpKwKyYewn/XNUbKw==}
|
resolution: {integrity: sha512-De72GdQZzNTUBBChsXueQUnPKDkg/5A5zp7pFDuQAj5UFoENpiACU0wlCvzpAGnTkj++ihpKwKyYewn/XNUbKw==}
|
||||||
engines: {node: '>=18'}
|
engines: {node: '>=18'}
|
||||||
|
|
||||||
|
whatwg-url@5.0.0:
|
||||||
|
resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==}
|
||||||
|
|
||||||
which@2.0.2:
|
which@2.0.2:
|
||||||
resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==}
|
resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==}
|
||||||
engines: {node: '>= 8'}
|
engines: {node: '>= 8'}
|
||||||
@@ -1601,10 +1787,17 @@ packages:
|
|||||||
utf-8-validate:
|
utf-8-validate:
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
|
xml-js@1.6.11:
|
||||||
|
resolution: {integrity: sha512-7rVi2KMfwfWFl+GpPg6m80IVMWXLRjO+PxTq7V2CDhoGak0wzYzFgUY2m4XJ47OGdXd8eLE8EmwfAmdjw7lC1g==}
|
||||||
|
hasBin: true
|
||||||
|
|
||||||
xml-name-validator@5.0.0:
|
xml-name-validator@5.0.0:
|
||||||
resolution: {integrity: sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg==}
|
resolution: {integrity: sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg==}
|
||||||
engines: {node: '>=18'}
|
engines: {node: '>=18'}
|
||||||
|
|
||||||
|
xml@1.0.1:
|
||||||
|
resolution: {integrity: sha512-huCv9IH9Tcf95zuYCsQraZtWnJvBtLVE0QHMOs8bWyZAFZNDcYjsPq1nEx8jKA9y+Beo9v+7OBPRisQTjinQMw==}
|
||||||
|
|
||||||
xmlchars@2.2.0:
|
xmlchars@2.2.0:
|
||||||
resolution: {integrity: sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==}
|
resolution: {integrity: sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==}
|
||||||
|
|
||||||
@@ -1615,6 +1808,9 @@ packages:
|
|||||||
resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==}
|
resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==}
|
||||||
engines: {node: '>=10'}
|
engines: {node: '>=10'}
|
||||||
|
|
||||||
|
zlibjs@0.3.1:
|
||||||
|
resolution: {integrity: sha512-+J9RrgTKOmlxFSDHo0pI1xM6BLVUv+o0ZT9ANtCxGkjIVCCUdx9alUF8Gm+dGLKbkkkidWIHFDZHDMpfITt4+w==}
|
||||||
|
|
||||||
zod-validation-error@4.0.2:
|
zod-validation-error@4.0.2:
|
||||||
resolution: {integrity: sha512-Q6/nZLe6jxuU80qb/4uJ4t5v2VEZ44lzQjPDhYJNztRQ4wyWc6VF3D3Kb/fAuPetZQnhS3hnajCf9CsWesghLQ==}
|
resolution: {integrity: sha512-Q6/nZLe6jxuU80qb/4uJ4t5v2VEZ44lzQjPDhYJNztRQ4wyWc6VF3D3Kb/fAuPetZQnhS3hnajCf9CsWesghLQ==}
|
||||||
engines: {node: '>=18.0.0'}
|
engines: {node: '>=18.0.0'}
|
||||||
@@ -1860,6 +2056,54 @@ snapshots:
|
|||||||
'@jridgewell/resolve-uri': 3.1.2
|
'@jridgewell/resolve-uri': 3.1.2
|
||||||
'@jridgewell/sourcemap-codec': 1.5.5
|
'@jridgewell/sourcemap-codec': 1.5.5
|
||||||
|
|
||||||
|
'@napi-rs/canvas-android-arm64@1.0.2':
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
'@napi-rs/canvas-darwin-arm64@1.0.2':
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
'@napi-rs/canvas-darwin-x64@1.0.2':
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
'@napi-rs/canvas-linux-arm-gnueabihf@1.0.2':
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
'@napi-rs/canvas-linux-arm64-gnu@1.0.2':
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
'@napi-rs/canvas-linux-arm64-musl@1.0.2':
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
'@napi-rs/canvas-linux-riscv64-gnu@1.0.2':
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
'@napi-rs/canvas-linux-x64-gnu@1.0.2':
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
'@napi-rs/canvas-linux-x64-musl@1.0.2':
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
'@napi-rs/canvas-win32-arm64-msvc@1.0.2':
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
'@napi-rs/canvas-win32-x64-msvc@1.0.2':
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
'@napi-rs/canvas@1.0.2':
|
||||||
|
optionalDependencies:
|
||||||
|
'@napi-rs/canvas-android-arm64': 1.0.2
|
||||||
|
'@napi-rs/canvas-darwin-arm64': 1.0.2
|
||||||
|
'@napi-rs/canvas-darwin-x64': 1.0.2
|
||||||
|
'@napi-rs/canvas-linux-arm-gnueabihf': 1.0.2
|
||||||
|
'@napi-rs/canvas-linux-arm64-gnu': 1.0.2
|
||||||
|
'@napi-rs/canvas-linux-arm64-musl': 1.0.2
|
||||||
|
'@napi-rs/canvas-linux-riscv64-gnu': 1.0.2
|
||||||
|
'@napi-rs/canvas-linux-x64-gnu': 1.0.2
|
||||||
|
'@napi-rs/canvas-linux-x64-musl': 1.0.2
|
||||||
|
'@napi-rs/canvas-win32-arm64-msvc': 1.0.2
|
||||||
|
'@napi-rs/canvas-win32-x64-msvc': 1.0.2
|
||||||
|
optional: true
|
||||||
|
|
||||||
'@napi-rs/wasm-runtime@1.1.4(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)':
|
'@napi-rs/wasm-runtime@1.1.4(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@emnapi/core': 1.10.0
|
'@emnapi/core': 1.10.0
|
||||||
@@ -2050,6 +2294,10 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
undici-types: 7.16.0
|
undici-types: 7.16.0
|
||||||
|
|
||||||
|
'@types/node@25.9.5':
|
||||||
|
dependencies:
|
||||||
|
undici-types: 7.24.6
|
||||||
|
|
||||||
'@types/react-dom@19.2.3(@types/react@19.2.14)':
|
'@types/react-dom@19.2.3(@types/react@19.2.14)':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@types/react': 19.2.14
|
'@types/react': 19.2.14
|
||||||
@@ -2227,6 +2475,8 @@ snapshots:
|
|||||||
readable-stream: 3.6.2
|
readable-stream: 3.6.2
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
|
bmp-js@0.1.0: {}
|
||||||
|
|
||||||
brace-expansion@5.0.6:
|
brace-expansion@5.0.6:
|
||||||
dependencies:
|
dependencies:
|
||||||
balanced-match: 4.0.4
|
balanced-match: 4.0.4
|
||||||
@@ -2262,6 +2512,8 @@ snapshots:
|
|||||||
|
|
||||||
cookie@1.1.1: {}
|
cookie@1.1.1: {}
|
||||||
|
|
||||||
|
core-util-is@1.0.3: {}
|
||||||
|
|
||||||
cross-spawn@7.0.6:
|
cross-spawn@7.0.6:
|
||||||
dependencies:
|
dependencies:
|
||||||
path-key: 3.1.1
|
path-key: 3.1.1
|
||||||
@@ -2301,6 +2553,15 @@ snapshots:
|
|||||||
|
|
||||||
detect-libc@2.1.2: {}
|
detect-libc@2.1.2: {}
|
||||||
|
|
||||||
|
docx@9.7.1:
|
||||||
|
dependencies:
|
||||||
|
'@types/node': 25.9.5
|
||||||
|
hash.js: 1.1.7
|
||||||
|
jszip: 3.10.1
|
||||||
|
nanoid: 5.1.16
|
||||||
|
xml: 1.0.1
|
||||||
|
xml-js: 1.6.11
|
||||||
|
|
||||||
electron-to-chromium@1.5.353: {}
|
electron-to-chromium@1.5.353: {}
|
||||||
|
|
||||||
end-of-stream@1.4.5:
|
end-of-stream@1.4.5:
|
||||||
@@ -2473,6 +2734,11 @@ snapshots:
|
|||||||
|
|
||||||
guid-typescript@1.0.9: {}
|
guid-typescript@1.0.9: {}
|
||||||
|
|
||||||
|
hash.js@1.1.7:
|
||||||
|
dependencies:
|
||||||
|
inherits: 2.0.4
|
||||||
|
minimalistic-assert: 1.0.1
|
||||||
|
|
||||||
hermes-estree@0.25.1: {}
|
hermes-estree@0.25.1: {}
|
||||||
|
|
||||||
hermes-parser@0.25.1:
|
hermes-parser@0.25.1:
|
||||||
@@ -2505,6 +2771,8 @@ snapshots:
|
|||||||
safer-buffer: 2.1.2
|
safer-buffer: 2.1.2
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
|
idb-keyval@6.3.0: {}
|
||||||
|
|
||||||
ieee754@1.2.1:
|
ieee754@1.2.1:
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
@@ -2512,10 +2780,11 @@ snapshots:
|
|||||||
|
|
||||||
ignore@7.0.5: {}
|
ignore@7.0.5: {}
|
||||||
|
|
||||||
|
immediate@3.0.6: {}
|
||||||
|
|
||||||
imurmurhash@0.1.4: {}
|
imurmurhash@0.1.4: {}
|
||||||
|
|
||||||
inherits@2.0.4:
|
inherits@2.0.4: {}
|
||||||
optional: true
|
|
||||||
|
|
||||||
ini@1.3.8:
|
ini@1.3.8:
|
||||||
optional: true
|
optional: true
|
||||||
@@ -2533,6 +2802,10 @@ snapshots:
|
|||||||
is-potential-custom-element-name@1.0.1:
|
is-potential-custom-element-name@1.0.1:
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
|
is-url@1.2.4: {}
|
||||||
|
|
||||||
|
isarray@1.0.0: {}
|
||||||
|
|
||||||
isexe@2.0.0: {}
|
isexe@2.0.0: {}
|
||||||
|
|
||||||
jiti@2.7.0: {}
|
jiti@2.7.0: {}
|
||||||
@@ -2579,6 +2852,13 @@ snapshots:
|
|||||||
|
|
||||||
json5@2.2.3: {}
|
json5@2.2.3: {}
|
||||||
|
|
||||||
|
jszip@3.10.1:
|
||||||
|
dependencies:
|
||||||
|
lie: 3.3.0
|
||||||
|
pako: 1.0.11
|
||||||
|
readable-stream: 2.3.8
|
||||||
|
setimmediate: 1.0.5
|
||||||
|
|
||||||
keyv@4.5.4:
|
keyv@4.5.4:
|
||||||
dependencies:
|
dependencies:
|
||||||
json-buffer: 3.0.1
|
json-buffer: 3.0.1
|
||||||
@@ -2588,6 +2868,10 @@ snapshots:
|
|||||||
prelude-ls: 1.2.1
|
prelude-ls: 1.2.1
|
||||||
type-check: 0.4.0
|
type-check: 0.4.0
|
||||||
|
|
||||||
|
lie@3.3.0:
|
||||||
|
dependencies:
|
||||||
|
immediate: 3.0.6
|
||||||
|
|
||||||
lightningcss-android-arm64@1.32.0:
|
lightningcss-android-arm64@1.32.0:
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
@@ -2659,6 +2943,8 @@ snapshots:
|
|||||||
mimic-response@3.1.0:
|
mimic-response@3.1.0:
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
|
minimalistic-assert@1.0.1: {}
|
||||||
|
|
||||||
minimatch@10.2.5:
|
minimatch@10.2.5:
|
||||||
dependencies:
|
dependencies:
|
||||||
brace-expansion: 5.0.6
|
brace-expansion: 5.0.6
|
||||||
@@ -2673,6 +2959,8 @@ snapshots:
|
|||||||
|
|
||||||
nanoid@3.3.12: {}
|
nanoid@3.3.12: {}
|
||||||
|
|
||||||
|
nanoid@5.1.16: {}
|
||||||
|
|
||||||
napi-build-utils@2.0.0:
|
napi-build-utils@2.0.0:
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
@@ -2691,6 +2979,10 @@ snapshots:
|
|||||||
node-addon-api@7.1.1:
|
node-addon-api@7.1.1:
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
|
node-fetch@2.7.0:
|
||||||
|
dependencies:
|
||||||
|
whatwg-url: 5.0.0
|
||||||
|
|
||||||
node-releases@2.0.44: {}
|
node-releases@2.0.44: {}
|
||||||
|
|
||||||
nwsapi@2.2.23:
|
nwsapi@2.2.23:
|
||||||
@@ -2714,6 +3006,8 @@ snapshots:
|
|||||||
platform: 1.3.6
|
platform: 1.3.6
|
||||||
protobufjs: 7.6.2
|
protobufjs: 7.6.2
|
||||||
|
|
||||||
|
opencollective-postinstall@2.0.3: {}
|
||||||
|
|
||||||
optionator@0.9.4:
|
optionator@0.9.4:
|
||||||
dependencies:
|
dependencies:
|
||||||
deep-is: 0.1.4
|
deep-is: 0.1.4
|
||||||
@@ -2751,6 +3045,10 @@ snapshots:
|
|||||||
pako: 1.0.11
|
pako: 1.0.11
|
||||||
tslib: 1.14.1
|
tslib: 1.14.1
|
||||||
|
|
||||||
|
pdfjs-dist@6.1.200:
|
||||||
|
optionalDependencies:
|
||||||
|
'@napi-rs/canvas': 1.0.2
|
||||||
|
|
||||||
picocolors@1.1.1: {}
|
picocolors@1.1.1: {}
|
||||||
|
|
||||||
picomatch@4.0.4: {}
|
picomatch@4.0.4: {}
|
||||||
@@ -2791,6 +3089,8 @@ snapshots:
|
|||||||
|
|
||||||
prettier@3.8.3: {}
|
prettier@3.8.3: {}
|
||||||
|
|
||||||
|
process-nextick-args@2.0.1: {}
|
||||||
|
|
||||||
protobufjs@7.6.2:
|
protobufjs@7.6.2:
|
||||||
dependencies:
|
dependencies:
|
||||||
'@protobufjs/aspromise': 1.1.2
|
'@protobufjs/aspromise': 1.1.2
|
||||||
@@ -2843,6 +3143,16 @@ snapshots:
|
|||||||
|
|
||||||
react@19.2.6: {}
|
react@19.2.6: {}
|
||||||
|
|
||||||
|
readable-stream@2.3.8:
|
||||||
|
dependencies:
|
||||||
|
core-util-is: 1.0.3
|
||||||
|
inherits: 2.0.4
|
||||||
|
isarray: 1.0.0
|
||||||
|
process-nextick-args: 2.0.1
|
||||||
|
safe-buffer: 5.1.2
|
||||||
|
string_decoder: 1.1.1
|
||||||
|
util-deprecate: 1.0.2
|
||||||
|
|
||||||
readable-stream@3.6.2:
|
readable-stream@3.6.2:
|
||||||
dependencies:
|
dependencies:
|
||||||
inherits: 2.0.4
|
inherits: 2.0.4
|
||||||
@@ -2850,6 +3160,8 @@ snapshots:
|
|||||||
util-deprecate: 1.0.2
|
util-deprecate: 1.0.2
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
|
regenerator-runtime@0.13.11: {}
|
||||||
|
|
||||||
rolldown@1.0.0:
|
rolldown@1.0.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
'@oxc-project/types': 0.129.0
|
'@oxc-project/types': 0.129.0
|
||||||
@@ -2874,12 +3186,16 @@ snapshots:
|
|||||||
rrweb-cssom@0.8.0:
|
rrweb-cssom@0.8.0:
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
|
safe-buffer@5.1.2: {}
|
||||||
|
|
||||||
safe-buffer@5.2.1:
|
safe-buffer@5.2.1:
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
safer-buffer@2.1.2:
|
safer-buffer@2.1.2:
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
|
sax@1.6.0: {}
|
||||||
|
|
||||||
saxes@6.0.0:
|
saxes@6.0.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
xmlchars: 2.2.0
|
xmlchars: 2.2.0
|
||||||
@@ -2893,6 +3209,8 @@ snapshots:
|
|||||||
|
|
||||||
set-cookie-parser@2.7.2: {}
|
set-cookie-parser@2.7.2: {}
|
||||||
|
|
||||||
|
setimmediate@1.0.5: {}
|
||||||
|
|
||||||
shebang-command@2.0.0:
|
shebang-command@2.0.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
shebang-regex: 3.0.0
|
shebang-regex: 3.0.0
|
||||||
@@ -2917,6 +3235,10 @@ snapshots:
|
|||||||
|
|
||||||
std-env@4.1.0: {}
|
std-env@4.1.0: {}
|
||||||
|
|
||||||
|
string_decoder@1.1.1:
|
||||||
|
dependencies:
|
||||||
|
safe-buffer: 5.1.2
|
||||||
|
|
||||||
string_decoder@1.3.0:
|
string_decoder@1.3.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
safe-buffer: 5.2.1
|
safe-buffer: 5.2.1
|
||||||
@@ -2951,6 +3273,22 @@ snapshots:
|
|||||||
readable-stream: 3.6.2
|
readable-stream: 3.6.2
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
|
tesseract.js-core@7.0.0: {}
|
||||||
|
|
||||||
|
tesseract.js@7.0.0:
|
||||||
|
dependencies:
|
||||||
|
bmp-js: 0.1.0
|
||||||
|
idb-keyval: 6.3.0
|
||||||
|
is-url: 1.2.4
|
||||||
|
node-fetch: 2.7.0
|
||||||
|
opencollective-postinstall: 2.0.3
|
||||||
|
regenerator-runtime: 0.13.11
|
||||||
|
tesseract.js-core: 7.0.0
|
||||||
|
wasm-feature-detect: 1.8.0
|
||||||
|
zlibjs: 0.3.1
|
||||||
|
transitivePeerDependencies:
|
||||||
|
- encoding
|
||||||
|
|
||||||
tinybench@2.9.0: {}
|
tinybench@2.9.0: {}
|
||||||
|
|
||||||
tinyexec@1.1.2: {}
|
tinyexec@1.1.2: {}
|
||||||
@@ -2975,6 +3313,8 @@ snapshots:
|
|||||||
tldts: 6.1.86
|
tldts: 6.1.86
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
|
tr46@0.0.3: {}
|
||||||
|
|
||||||
tr46@5.1.1:
|
tr46@5.1.1:
|
||||||
dependencies:
|
dependencies:
|
||||||
punycode: 2.3.1
|
punycode: 2.3.1
|
||||||
@@ -3017,6 +3357,8 @@ snapshots:
|
|||||||
|
|
||||||
undici-types@7.16.0: {}
|
undici-types@7.16.0: {}
|
||||||
|
|
||||||
|
undici-types@7.24.6: {}
|
||||||
|
|
||||||
update-browserslist-db@1.2.3(browserslist@4.28.2):
|
update-browserslist-db@1.2.3(browserslist@4.28.2):
|
||||||
dependencies:
|
dependencies:
|
||||||
browserslist: 4.28.2
|
browserslist: 4.28.2
|
||||||
@@ -3027,8 +3369,7 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
punycode: 2.3.1
|
punycode: 2.3.1
|
||||||
|
|
||||||
util-deprecate@1.0.2:
|
util-deprecate@1.0.2: {}
|
||||||
optional: true
|
|
||||||
|
|
||||||
vite@8.0.12(@types/node@24.12.4)(jiti@2.7.0):
|
vite@8.0.12(@types/node@24.12.4)(jiti@2.7.0):
|
||||||
dependencies:
|
dependencies:
|
||||||
@@ -3075,6 +3416,10 @@ snapshots:
|
|||||||
xml-name-validator: 5.0.0
|
xml-name-validator: 5.0.0
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
|
wasm-feature-detect@1.8.0: {}
|
||||||
|
|
||||||
|
webidl-conversions@3.0.1: {}
|
||||||
|
|
||||||
webidl-conversions@7.0.0:
|
webidl-conversions@7.0.0:
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
@@ -3092,6 +3437,11 @@ snapshots:
|
|||||||
webidl-conversions: 7.0.0
|
webidl-conversions: 7.0.0
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
|
whatwg-url@5.0.0:
|
||||||
|
dependencies:
|
||||||
|
tr46: 0.0.3
|
||||||
|
webidl-conversions: 3.0.1
|
||||||
|
|
||||||
which@2.0.2:
|
which@2.0.2:
|
||||||
dependencies:
|
dependencies:
|
||||||
isexe: 2.0.0
|
isexe: 2.0.0
|
||||||
@@ -3109,9 +3459,15 @@ snapshots:
|
|||||||
ws@8.21.0:
|
ws@8.21.0:
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
|
xml-js@1.6.11:
|
||||||
|
dependencies:
|
||||||
|
sax: 1.6.0
|
||||||
|
|
||||||
xml-name-validator@5.0.0:
|
xml-name-validator@5.0.0:
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
|
xml@1.0.1: {}
|
||||||
|
|
||||||
xmlchars@2.2.0:
|
xmlchars@2.2.0:
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
@@ -3119,6 +3475,8 @@ snapshots:
|
|||||||
|
|
||||||
yocto-queue@0.1.0: {}
|
yocto-queue@0.1.0: {}
|
||||||
|
|
||||||
|
zlibjs@0.3.1: {}
|
||||||
|
|
||||||
zod-validation-error@4.0.2(zod@4.4.3):
|
zod-validation-error@4.0.2(zod@4.4.3):
|
||||||
dependencies:
|
dependencies:
|
||||||
zod: 4.4.3
|
zod: 4.4.3
|
||||||
|
|||||||
@@ -28,6 +28,8 @@ import { passwordGeneratorPlugin } from "../../tools/password-generator";
|
|||||||
import { fileChecksumVerifierPlugin } from "../../tools/file-checksum-verifier";
|
import { fileChecksumVerifierPlugin } from "../../tools/file-checksum-verifier";
|
||||||
import { svgViewerPlugin } from "../../tools/svg-viewer";
|
import { svgViewerPlugin } from "../../tools/svg-viewer";
|
||||||
import { backgroundRemoverPlugin } from "../../tools/background-remover";
|
import { backgroundRemoverPlugin } from "../../tools/background-remover";
|
||||||
|
import { imageToPdfPlugin } from "../../tools/image-to-pdf";
|
||||||
|
import { pdfToDocxOcrPlugin } from "../../tools/pdf-to-docx-ocr";
|
||||||
|
|
||||||
function erasePlugin<TOptions>(plugin: PlimiPlugin<TOptions>): UnknownPlimiPlugin {
|
function erasePlugin<TOptions>(plugin: PlimiPlugin<TOptions>): UnknownPlimiPlugin {
|
||||||
return plugin as unknown as UnknownPlimiPlugin;
|
return plugin as unknown as UnknownPlimiPlugin;
|
||||||
@@ -54,6 +56,8 @@ export const pluginRegistry: UnknownPlimiPlugin[] = [
|
|||||||
erasePlugin(pdfMergerPlugin),
|
erasePlugin(pdfMergerPlugin),
|
||||||
erasePlugin(pdfSplitterPlugin),
|
erasePlugin(pdfSplitterPlugin),
|
||||||
erasePlugin(pdfWatermarkPlugin),
|
erasePlugin(pdfWatermarkPlugin),
|
||||||
|
erasePlugin(imageToPdfPlugin),
|
||||||
|
erasePlugin(pdfToDocxOcrPlugin),
|
||||||
erasePlugin(imageRedactorPlugin),
|
erasePlugin(imageRedactorPlugin),
|
||||||
erasePlugin(exifScrubberPlugin),
|
erasePlugin(exifScrubberPlugin),
|
||||||
erasePlugin(jwtDecoderPlugin),
|
erasePlugin(jwtDecoderPlugin),
|
||||||
|
|||||||
71
src/tools/image-to-pdf/index.ts
Normal file
71
src/tools/image-to-pdf/index.ts
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
import type { PlimiPlugin } from "../../core/plugins/plugin-types";
|
||||||
|
import { runImageToPdf } from "./run";
|
||||||
|
|
||||||
|
export interface ImageToPdfOptions {
|
||||||
|
pageSize: "fit" | "a4" | "letter";
|
||||||
|
orientation: "auto" | "portrait" | "landscape";
|
||||||
|
margin: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const imageToPdfPlugin: PlimiPlugin<ImageToPdfOptions> = {
|
||||||
|
manifest: {
|
||||||
|
id: "image-to-pdf",
|
||||||
|
name: "Images to PDF",
|
||||||
|
description:
|
||||||
|
"Turn one or more JPG, PNG, or WebP images into a single PDF without uploading them.",
|
||||||
|
category: "pdf",
|
||||||
|
version: "1.0.0",
|
||||||
|
tags: ["image", "pdf", "jpg", "png", "webp", "convert"],
|
||||||
|
input: {
|
||||||
|
type: "files",
|
||||||
|
label: "Images, in page order",
|
||||||
|
description: "Each image becomes one page. Select files in the order you want them to appear.",
|
||||||
|
accept: ["image/jpeg", "image/png", "image/webp"],
|
||||||
|
multiple: true,
|
||||||
|
maxSizeMb: 30,
|
||||||
|
maxFiles: 100,
|
||||||
|
},
|
||||||
|
output: { type: "files" },
|
||||||
|
offlineReady: true,
|
||||||
|
},
|
||||||
|
|
||||||
|
optionsSchema: {
|
||||||
|
fields: [
|
||||||
|
{
|
||||||
|
type: "select",
|
||||||
|
key: "pageSize",
|
||||||
|
label: "Page size",
|
||||||
|
defaultValue: "fit",
|
||||||
|
options: [
|
||||||
|
{ label: "Fit each image", value: "fit" },
|
||||||
|
{ label: "A4", value: "a4" },
|
||||||
|
{ label: "US Letter", value: "letter" },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: "select",
|
||||||
|
key: "orientation",
|
||||||
|
label: "Orientation",
|
||||||
|
defaultValue: "auto",
|
||||||
|
options: [
|
||||||
|
{ label: "Automatic", value: "auto" },
|
||||||
|
{ label: "Portrait", value: "portrait" },
|
||||||
|
{ label: "Landscape", value: "landscape" },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: "number",
|
||||||
|
key: "margin",
|
||||||
|
label: "Margin (mm)",
|
||||||
|
defaultValue: 10,
|
||||||
|
min: 0,
|
||||||
|
max: 40,
|
||||||
|
step: 1,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
|
||||||
|
capabilities: { cancelable: true },
|
||||||
|
permissions: { network: "none", fileSystem: "read-write" },
|
||||||
|
run: runImageToPdf,
|
||||||
|
};
|
||||||
47
src/tools/image-to-pdf/run.test.ts
Normal file
47
src/tools/image-to-pdf/run.test.ts
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
import { describe, expect, it, vi } from "vitest";
|
||||||
|
import { PDFDocument } from "pdf-lib";
|
||||||
|
import type { ToolContext } from "../../core/plugins/plugin-types";
|
||||||
|
import { imageToPdfPlugin, type ImageToPdfOptions } from "./index";
|
||||||
|
import { runImageToPdf } from "./run";
|
||||||
|
|
||||||
|
const context: ToolContext = {
|
||||||
|
signal: new AbortController().signal,
|
||||||
|
reportProgress: vi.fn(),
|
||||||
|
logger: { info: vi.fn(), warn: vi.fn(), error: vi.fn() },
|
||||||
|
};
|
||||||
|
|
||||||
|
const options: ImageToPdfOptions = {
|
||||||
|
pageSize: "fit",
|
||||||
|
orientation: "auto",
|
||||||
|
margin: 10,
|
||||||
|
};
|
||||||
|
|
||||||
|
const onePixelPng = Uint8Array.from(atob(
|
||||||
|
"iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNk+A8AAQUBAScY42YAAAAASUVORK5CYII="
|
||||||
|
), (char) => char.charCodeAt(0));
|
||||||
|
|
||||||
|
describe("Images to PDF", () => {
|
||||||
|
it("has a local PDF plugin manifest", () => {
|
||||||
|
expect(imageToPdfPlugin.manifest.id).toBe("image-to-pdf");
|
||||||
|
expect(imageToPdfPlugin.manifest.category).toBe("pdf");
|
||||||
|
expect(imageToPdfPlugin.permissions?.network).toBe("none");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("requires at least one image", async () => {
|
||||||
|
await expect(runImageToPdf({ files: [] }, options, context)).rejects.toThrow(
|
||||||
|
"Add at least one image."
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("creates one PDF page per image", async () => {
|
||||||
|
const files = ["first.png", "second.png"].map(
|
||||||
|
(name) => new File([onePixelPng], name, { type: "image/png" })
|
||||||
|
);
|
||||||
|
const result = await runImageToPdf({ files }, options, context);
|
||||||
|
expect(result.type).toBe("files");
|
||||||
|
if (result.type !== "files") throw new Error("Unexpected result");
|
||||||
|
expect(result.files[0].name).toBe("images.pdf");
|
||||||
|
const pdf = await PDFDocument.load(await result.files[0].blob.arrayBuffer());
|
||||||
|
expect(pdf.getPageCount()).toBe(2);
|
||||||
|
});
|
||||||
|
});
|
||||||
113
src/tools/image-to-pdf/run.ts
Normal file
113
src/tools/image-to-pdf/run.ts
Normal file
@@ -0,0 +1,113 @@
|
|||||||
|
import { PDFDocument } from "pdf-lib";
|
||||||
|
import type { ToolInput } from "../../core/io/input-types";
|
||||||
|
import type { ToolResult } from "../../core/io/output-types";
|
||||||
|
import type { ToolContext } from "../../core/plugins/plugin-types";
|
||||||
|
import type { ImageToPdfOptions } from "./index";
|
||||||
|
|
||||||
|
const MM_TO_POINTS = 72 / 25.4;
|
||||||
|
const PAGE_SIZES = {
|
||||||
|
a4: [595.28, 841.89],
|
||||||
|
letter: [612, 792],
|
||||||
|
} as const;
|
||||||
|
|
||||||
|
function abortIfNeeded(signal: AbortSignal) {
|
||||||
|
if (signal.aborted) throw new DOMException("Operation cancelled", "AbortError");
|
||||||
|
}
|
||||||
|
|
||||||
|
async function convertWebpToPng(file: File): Promise<Uint8Array> {
|
||||||
|
const bitmap = await createImageBitmap(file);
|
||||||
|
try {
|
||||||
|
const canvas = document.createElement("canvas");
|
||||||
|
canvas.width = bitmap.width;
|
||||||
|
canvas.height = bitmap.height;
|
||||||
|
const context = canvas.getContext("2d");
|
||||||
|
if (!context) throw new Error("Your browser could not prepare this WebP image.");
|
||||||
|
context.drawImage(bitmap, 0, 0);
|
||||||
|
const blob = await new Promise<Blob>((resolve, reject) =>
|
||||||
|
canvas.toBlob(
|
||||||
|
(value) => (value ? resolve(value) : reject(new Error("Could not convert WebP image."))),
|
||||||
|
"image/png"
|
||||||
|
)
|
||||||
|
);
|
||||||
|
return new Uint8Array(await blob.arrayBuffer());
|
||||||
|
} finally {
|
||||||
|
bitmap.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function runImageToPdf(
|
||||||
|
input: ToolInput,
|
||||||
|
options: ImageToPdfOptions,
|
||||||
|
context: ToolContext
|
||||||
|
): Promise<ToolResult> {
|
||||||
|
const files = input.files ?? [];
|
||||||
|
if (files.length === 0) throw new Error("Add at least one image.");
|
||||||
|
|
||||||
|
const pdf = await PDFDocument.create();
|
||||||
|
const margin = Math.max(0, Math.min(40, Number(options.margin) || 0)) * MM_TO_POINTS;
|
||||||
|
|
||||||
|
for (let index = 0; index < files.length; index += 1) {
|
||||||
|
abortIfNeeded(context.signal);
|
||||||
|
const file = files[index];
|
||||||
|
context.reportProgress({
|
||||||
|
percentage: (index / files.length) * 95,
|
||||||
|
message: `Adding ${file.name} (${index + 1}/${files.length})...`,
|
||||||
|
});
|
||||||
|
|
||||||
|
let image;
|
||||||
|
if (file.type === "image/jpeg") {
|
||||||
|
image = await pdf.embedJpg(new Uint8Array(await file.arrayBuffer()));
|
||||||
|
} else if (file.type === "image/png") {
|
||||||
|
image = await pdf.embedPng(new Uint8Array(await file.arrayBuffer()));
|
||||||
|
} else if (file.type === "image/webp") {
|
||||||
|
image = await pdf.embedPng(await convertWebpToPng(file));
|
||||||
|
} else {
|
||||||
|
throw new Error(`${file.name} is not a supported JPG, PNG, or WebP image.`);
|
||||||
|
}
|
||||||
|
|
||||||
|
let pageWidth: number;
|
||||||
|
let pageHeight: number;
|
||||||
|
if (options.pageSize === "fit") {
|
||||||
|
pageWidth = image.width + margin * 2;
|
||||||
|
pageHeight = image.height + margin * 2;
|
||||||
|
} else {
|
||||||
|
[pageWidth, pageHeight] = PAGE_SIZES[options.pageSize];
|
||||||
|
const landscape =
|
||||||
|
options.orientation === "landscape" ||
|
||||||
|
(options.orientation === "auto" && image.width > image.height);
|
||||||
|
if (landscape) [pageWidth, pageHeight] = [pageHeight, pageWidth];
|
||||||
|
}
|
||||||
|
|
||||||
|
const usableWidth = Math.max(1, pageWidth - margin * 2);
|
||||||
|
const usableHeight = Math.max(1, pageHeight - margin * 2);
|
||||||
|
const scale = Math.min(usableWidth / image.width, usableHeight / image.height);
|
||||||
|
const width = image.width * scale;
|
||||||
|
const height = image.height * scale;
|
||||||
|
const page = pdf.addPage([pageWidth, pageHeight]);
|
||||||
|
page.drawImage(image, {
|
||||||
|
x: (pageWidth - width) / 2,
|
||||||
|
y: (pageHeight - height) / 2,
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
abortIfNeeded(context.signal);
|
||||||
|
context.reportProgress({ percentage: 98, message: "Finishing PDF..." });
|
||||||
|
const bytes = await pdf.save();
|
||||||
|
const blob = new Blob([bytes as unknown as BlobPart], { type: "application/pdf" });
|
||||||
|
context.reportProgress({ percentage: 100, message: "PDF ready." });
|
||||||
|
|
||||||
|
return {
|
||||||
|
type: "files",
|
||||||
|
files: [{
|
||||||
|
name: files.length === 1
|
||||||
|
? `${files[0].name.replace(/\.[^.]+$/, "")}.pdf`
|
||||||
|
: "images.pdf",
|
||||||
|
mimeType: "application/pdf",
|
||||||
|
blob,
|
||||||
|
sizeBefore: files.reduce((total, file) => total + file.size, 0),
|
||||||
|
sizeAfter: blob.size,
|
||||||
|
}],
|
||||||
|
};
|
||||||
|
}
|
||||||
76
src/tools/pdf-to-docx-ocr/index.ts
Normal file
76
src/tools/pdf-to-docx-ocr/index.ts
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
import type { PlimiPlugin } from "../../core/plugins/plugin-types";
|
||||||
|
import { runPdfToDocxOcr } from "./run";
|
||||||
|
|
||||||
|
export interface PdfToDocxOcrOptions {
|
||||||
|
language: "eng" | "fra" | "deu" | "spa" | "ita" | "por" | "nld";
|
||||||
|
quality: "standard" | "high";
|
||||||
|
pageBreaks: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
const LANGUAGE_NAMES: Record<PdfToDocxOcrOptions["language"], string> = {
|
||||||
|
eng: "English",
|
||||||
|
fra: "French",
|
||||||
|
deu: "German",
|
||||||
|
spa: "Spanish",
|
||||||
|
ita: "Italian",
|
||||||
|
por: "Portuguese",
|
||||||
|
nld: "Dutch",
|
||||||
|
};
|
||||||
|
|
||||||
|
export const pdfToDocxOcrPlugin: PlimiPlugin<PdfToDocxOcrOptions> = {
|
||||||
|
manifest: {
|
||||||
|
id: "pdf-to-docx-ocr",
|
||||||
|
name: "PDF to DOCX with OCR",
|
||||||
|
description:
|
||||||
|
"Extract text from scanned or digital PDFs and create an editable Word document entirely on your device.",
|
||||||
|
category: "pdf",
|
||||||
|
version: "1.0.0",
|
||||||
|
tags: ["pdf", "docx", "word", "ocr", "scan", "convert"],
|
||||||
|
input: {
|
||||||
|
type: "files",
|
||||||
|
label: "PDF document",
|
||||||
|
description: "Best for typed documents and clear scans. Handwriting and complex layouts may need cleanup.",
|
||||||
|
accept: ["application/pdf"],
|
||||||
|
multiple: false,
|
||||||
|
maxSizeMb: 100,
|
||||||
|
maxFiles: 1,
|
||||||
|
},
|
||||||
|
output: { type: "files" },
|
||||||
|
offlineReady: false,
|
||||||
|
},
|
||||||
|
|
||||||
|
optionsSchema: {
|
||||||
|
fields: [
|
||||||
|
{
|
||||||
|
type: "select",
|
||||||
|
key: "language",
|
||||||
|
label: "Document language",
|
||||||
|
defaultValue: "eng",
|
||||||
|
options: Object.entries(LANGUAGE_NAMES).map(([value, label]) => ({ value, label })),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: "select",
|
||||||
|
key: "quality",
|
||||||
|
label: "OCR quality",
|
||||||
|
defaultValue: "standard",
|
||||||
|
options: [
|
||||||
|
{ label: "Standard (faster)", value: "standard" },
|
||||||
|
{ label: "High (clearer small text)", value: "high" },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: "boolean",
|
||||||
|
key: "pageBreaks",
|
||||||
|
label: "Keep PDF page breaks",
|
||||||
|
defaultValue: true,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
|
||||||
|
capabilities: { cancelable: true, wasm: true },
|
||||||
|
permissions: { network: "optional", fileSystem: "read-write" },
|
||||||
|
getRunWarning: (_input, options) =>
|
||||||
|
`The ${LANGUAGE_NAMES[options.language]} OCR model may be downloaded to your browser and cached. ` +
|
||||||
|
"Your PDF is never uploaded; page rendering, OCR, and DOCX creation all happen locally.",
|
||||||
|
run: runPdfToDocxOcr,
|
||||||
|
};
|
||||||
37
src/tools/pdf-to-docx-ocr/run.test.ts
Normal file
37
src/tools/pdf-to-docx-ocr/run.test.ts
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
import { describe, expect, it, vi } from "vitest";
|
||||||
|
import type { ToolContext } from "../../core/plugins/plugin-types";
|
||||||
|
import { pdfToDocxOcrPlugin, type PdfToDocxOcrOptions } from "./index";
|
||||||
|
import { runPdfToDocxOcr } from "./run";
|
||||||
|
|
||||||
|
const context: ToolContext = {
|
||||||
|
signal: new AbortController().signal,
|
||||||
|
reportProgress: vi.fn(),
|
||||||
|
logger: { info: vi.fn(), warn: vi.fn(), error: vi.fn() },
|
||||||
|
};
|
||||||
|
|
||||||
|
const options: PdfToDocxOcrOptions = {
|
||||||
|
language: "eng",
|
||||||
|
quality: "standard",
|
||||||
|
pageBreaks: true,
|
||||||
|
};
|
||||||
|
|
||||||
|
describe("PDF to DOCX with OCR", () => {
|
||||||
|
it("declares local processing with optional model access", () => {
|
||||||
|
expect(pdfToDocxOcrPlugin.manifest.id).toBe("pdf-to-docx-ocr");
|
||||||
|
expect(pdfToDocxOcrPlugin.capabilities?.wasm).toBe(true);
|
||||||
|
expect(pdfToDocxOcrPlugin.permissions?.network).toBe("optional");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("requires a PDF", async () => {
|
||||||
|
await expect(runPdfToDocxOcr({ files: [] }, options, context)).rejects.toThrow(
|
||||||
|
"Add a PDF document."
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("rejects a non-PDF before starting OCR", async () => {
|
||||||
|
const file = new File(["hello"], "notes.txt", { type: "text/plain" });
|
||||||
|
await expect(runPdfToDocxOcr({ files: [file] }, options, context)).rejects.toThrow(
|
||||||
|
"The selected file is not a PDF."
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
110
src/tools/pdf-to-docx-ocr/run.ts
Normal file
110
src/tools/pdf-to-docx-ocr/run.ts
Normal file
@@ -0,0 +1,110 @@
|
|||||||
|
import type { ToolInput } from "../../core/io/input-types";
|
||||||
|
import type { ToolResult } from "../../core/io/output-types";
|
||||||
|
import type { ToolContext } from "../../core/plugins/plugin-types";
|
||||||
|
import type { PdfToDocxOcrOptions } from "./index";
|
||||||
|
|
||||||
|
function abortIfNeeded(signal: AbortSignal) {
|
||||||
|
if (signal.aborted) throw new DOMException("Operation cancelled", "AbortError");
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function runPdfToDocxOcr(
|
||||||
|
input: ToolInput,
|
||||||
|
options: PdfToDocxOcrOptions,
|
||||||
|
context: ToolContext
|
||||||
|
): Promise<ToolResult> {
|
||||||
|
const file = input.files?.[0];
|
||||||
|
if (!file) throw new Error("Add a PDF document.");
|
||||||
|
if (file.type && file.type !== "application/pdf") throw new Error("The selected file is not a PDF.");
|
||||||
|
|
||||||
|
abortIfNeeded(context.signal);
|
||||||
|
context.reportProgress({ percentage: 1, message: "Opening PDF locally..." });
|
||||||
|
|
||||||
|
const [pdfjs, { createWorker }] = await Promise.all([
|
||||||
|
import("pdfjs-dist"),
|
||||||
|
import("tesseract.js"),
|
||||||
|
]);
|
||||||
|
pdfjs.GlobalWorkerOptions.workerSrc = new URL(
|
||||||
|
"pdfjs-dist/build/pdf.worker.min.mjs",
|
||||||
|
import.meta.url
|
||||||
|
).toString();
|
||||||
|
|
||||||
|
const loadingTask = pdfjs.getDocument({ data: new Uint8Array(await file.arrayBuffer()) });
|
||||||
|
const pdf = await loadingTask.promise;
|
||||||
|
const pageTexts: string[] = [];
|
||||||
|
const scale = options.quality === "high" ? 2.5 : 1.75;
|
||||||
|
|
||||||
|
const worker = await createWorker(options.language, undefined, {
|
||||||
|
logger: (message) => {
|
||||||
|
if (message.status === "recognizing text" && typeof message.progress === "number") {
|
||||||
|
const completedPages = pageTexts.length;
|
||||||
|
context.reportProgress({
|
||||||
|
percentage: 8 + ((completedPages + message.progress) / pdf.numPages) * 88,
|
||||||
|
message: `Recognizing page ${completedPages + 1} of ${pdf.numPages}...`,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const cancelWorker = () => void worker.terminate();
|
||||||
|
context.signal.addEventListener("abort", cancelWorker, { once: true });
|
||||||
|
|
||||||
|
try {
|
||||||
|
for (let pageNumber = 1; pageNumber <= pdf.numPages; pageNumber += 1) {
|
||||||
|
abortIfNeeded(context.signal);
|
||||||
|
context.reportProgress({
|
||||||
|
percentage: 5 + ((pageNumber - 1) / pdf.numPages) * 88,
|
||||||
|
message: `Rendering page ${pageNumber} of ${pdf.numPages} locally...`,
|
||||||
|
});
|
||||||
|
|
||||||
|
const page = await pdf.getPage(pageNumber);
|
||||||
|
const viewport = page.getViewport({ scale });
|
||||||
|
const canvas = document.createElement("canvas");
|
||||||
|
canvas.width = Math.ceil(viewport.width);
|
||||||
|
canvas.height = Math.ceil(viewport.height);
|
||||||
|
const canvasContext = canvas.getContext("2d", { alpha: false });
|
||||||
|
if (!canvasContext) throw new Error("Your browser could not render this PDF page.");
|
||||||
|
await page.render({ canvas, canvasContext, viewport }).promise;
|
||||||
|
abortIfNeeded(context.signal);
|
||||||
|
|
||||||
|
const result = await worker.recognize(canvas);
|
||||||
|
pageTexts.push(result.data.text.trim());
|
||||||
|
page.cleanup();
|
||||||
|
canvas.width = 1;
|
||||||
|
canvas.height = 1;
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
context.signal.removeEventListener("abort", cancelWorker);
|
||||||
|
await worker.terminate().catch(() => undefined);
|
||||||
|
await loadingTask.destroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
abortIfNeeded(context.signal);
|
||||||
|
context.reportProgress({ percentage: 97, message: "Building editable DOCX..." });
|
||||||
|
const { Document, Packer, Paragraph } = await import("docx");
|
||||||
|
const children: Array<InstanceType<typeof Paragraph>> = [];
|
||||||
|
pageTexts.forEach((text, pageIndex) => {
|
||||||
|
const lines = text.split(/\r?\n/);
|
||||||
|
lines.forEach((line, lineIndex) => {
|
||||||
|
children.push(new Paragraph({
|
||||||
|
text: line,
|
||||||
|
pageBreakBefore: options.pageBreaks && pageIndex > 0 && lineIndex === 0,
|
||||||
|
spacing: { after: line.trim() ? 120 : 0 },
|
||||||
|
}));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
const docxDocument = new Document({ sections: [{ children }] });
|
||||||
|
const blob = await Packer.toBlob(docxDocument);
|
||||||
|
context.reportProgress({ percentage: 100, message: "DOCX ready." });
|
||||||
|
|
||||||
|
return {
|
||||||
|
type: "files",
|
||||||
|
files: [{
|
||||||
|
name: `${file.name.replace(/\.pdf$/i, "")}_ocr.docx`,
|
||||||
|
mimeType: "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
|
||||||
|
blob,
|
||||||
|
sizeBefore: file.size,
|
||||||
|
sizeAfter: blob.size,
|
||||||
|
}],
|
||||||
|
};
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user