Compare commits
30
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
12fff5b4a7 | ||
|
|
ffd1abbdb3 | ||
|
|
79bc62a5d2 | ||
|
|
1c43bd363a | ||
|
|
4f404a1ccf | ||
|
|
2ae413c5ea | ||
|
|
36358fc139 | ||
|
|
d39a7ddda7 | ||
|
|
789eaa263f | ||
|
|
4575d7178b | ||
|
|
3cdf363eab | ||
|
|
d990d4181d | ||
|
|
a46dc141d0 | ||
|
|
6fee27739c | ||
|
|
1cc562a6b1 | ||
|
|
d90e51233d | ||
|
|
1cd3e2846e | ||
|
|
03da0e7d68 | ||
|
|
685b562d3d | ||
|
|
080faf9353 | ||
|
|
d486bb4939 | ||
|
|
41f9929fd2 | ||
|
|
0b0db1793e | ||
|
|
f3cf747cfe | ||
|
|
e3982ed4c5 | ||
|
|
5c7d675960 | ||
|
|
7fc6ec5fe1 | ||
|
|
7722001463 | ||
|
|
43d4b46b31 | ||
|
|
eee17d4d19 |
@@ -59,8 +59,8 @@ def find_duplicate_keys(file_path, keys=None, prefix=""):
|
||||
return duplicates
|
||||
|
||||
|
||||
# Maximum size for TOML files (e.g., 570 KB)
|
||||
MAX_FILE_SIZE = 570 * 1024
|
||||
# Maximum size for TOML files (e.g., 1 MB)
|
||||
MAX_FILE_SIZE = 1000 * 1024
|
||||
|
||||
|
||||
def parse_toml_file(file_path):
|
||||
|
||||
@@ -97,9 +97,9 @@ cffi==2.0.0 \
|
||||
--hash=sha256:fc7de24befaeae77ba923797c7c87834c73648a05a4bde34b3b7e5588973a453 \
|
||||
--hash=sha256:fe562eb1a64e67dd297ccc4f5addea2501664954f2692b69a76449ec7913ecbf
|
||||
# via weasyprint
|
||||
cfgv==3.4.0 \
|
||||
--hash=sha256:b7265b1f29fd3316bfcd2b330d63d024f2bfd8bcb8b0272f8e19a504856c48f9 \
|
||||
--hash=sha256:e52591d4c5f5dead8e0f673fb16db7949d2cfb3f7da4582893288f0ded8fe560
|
||||
cfgv==3.5.0 \
|
||||
--hash=sha256:a8dc6b26ad22ff227d2634a65cb388215ce6cc96bbcc5cfde7641ae87e8dacc0 \
|
||||
--hash=sha256:d5b1034354820651caa73ede66a6294d6e95c1b00acc5e9b098e917404669132
|
||||
# via pre-commit
|
||||
cssselect2==0.8.0 \
|
||||
--hash=sha256:46fc70ebc41ced7a32cd42d58b1884d72ade23d21e5a4eaaf022401c13f0e76e \
|
||||
@@ -109,259 +109,269 @@ distlib==0.4.0 \
|
||||
--hash=sha256:9659f7d87e46584a30b5780e43ac7a2143098441670ff0a49d5f9034c54a6c16 \
|
||||
--hash=sha256:feec40075be03a04501a973d81f633735b4b69f98b05450592310c0f401a4e0d
|
||||
# via virtualenv
|
||||
filelock==3.20.0 \
|
||||
--hash=sha256:339b4732ffda5cd79b13f4e2711a31b0365ce445d95d243bb996273d072546a2 \
|
||||
--hash=sha256:711e943b4ec6be42e1d4e6690b48dc175c822967466bb31c0c293f34334c13f4
|
||||
filelock==3.20.3 \
|
||||
--hash=sha256:18c57ee915c7ec61cff0ecf7f0f869936c7c30191bb0cf406f1341778d0834e1 \
|
||||
--hash=sha256:4b0dda527ee31078689fc205ec4f1c1bf7d56cf88b6dc9426c4f230e46c2dce1
|
||||
# via virtualenv
|
||||
fonttools==4.60.1 \
|
||||
--hash=sha256:022beaea4b73a70295b688f817ddc24ed3e3418b5036ffcd5658141184ef0d0c \
|
||||
--hash=sha256:026290e4ec76583881763fac284aca67365e0be9f13a7fb137257096114cb3bc \
|
||||
--hash=sha256:0b0835ed15dd5b40d726bb61c846a688f5b4ce2208ec68779bc81860adb5851a \
|
||||
--hash=sha256:0eae96373e4b7c9e45d099d7a523444e3554360927225c1cdae221a58a45b856 \
|
||||
--hash=sha256:122e1a8ada290423c493491d002f622b1992b1ab0b488c68e31c413390dc7eb2 \
|
||||
--hash=sha256:1410155d0e764a4615774e5c2c6fc516259fe3eca5882f034eb9bfdbee056259 \
|
||||
--hash=sha256:145daa14bf24824b677b9357c5e44fd8895c2a8f53596e1b9ea3496081dc692c \
|
||||
--hash=sha256:1525796c3ffe27bb6268ed2a1bb0dcf214d561dfaf04728abf01489eb5339dce \
|
||||
--hash=sha256:154cb6ee417e417bf5f7c42fe25858c9140c26f647c7347c06f0cc2d47eff003 \
|
||||
--hash=sha256:2299df884c11162617a66b7c316957d74a18e3758c0274762d2cc87df7bc0272 \
|
||||
--hash=sha256:2409d5fb7b55fd70f715e6d34e7a6e4f7511b8ad29a49d6df225ee76da76dd77 \
|
||||
--hash=sha256:268ecda8ca6cb5c4f044b1fb9b3b376e8cd1b361cef275082429dc4174907038 \
|
||||
--hash=sha256:282dafa55f9659e8999110bd8ed422ebe1c8aecd0dc396550b038e6c9a08b8ea \
|
||||
--hash=sha256:2ee06fc57512144d8b0445194c2da9f190f61ad51e230f14836286470c99f854 \
|
||||
--hash=sha256:3630e86c484263eaac71d117085d509cbcf7b18f677906824e4bace598fb70d2 \
|
||||
--hash=sha256:398447f3d8c0c786cbf1209711e79080a40761eb44b27cdafffb48f52bcec258 \
|
||||
--hash=sha256:4ba4bd646e86de16160f0fb72e31c3b9b7d0721c3e5b26b9fa2fc931dfdb2652 \
|
||||
--hash=sha256:5664fd1a9ea7f244487ac8f10340c4e37664675e8667d6fee420766e0fb3cf08 \
|
||||
--hash=sha256:583b7f8e3c49486e4d489ad1deacfb8d5be54a8ef34d6df824f6a171f8511d99 \
|
||||
--hash=sha256:596ecaca36367027d525b3b426d8a8208169d09edcf8c7506aceb3a38bfb55c7 \
|
||||
--hash=sha256:5c1015318e4fec75dd4943ad5f6a206d9727adf97410d58b7e32ab644a807914 \
|
||||
--hash=sha256:66929e2ea2810c6533a5184f938502cfdaea4bc3efb7130d8cc02e1c1b4108d6 \
|
||||
--hash=sha256:6ec722ee589e89a89f5b7574f5c45604030aa6ae24cb2c751e2707193b466fed \
|
||||
--hash=sha256:6f68576bb4bbf6060c7ab047b1574a1ebe5c50a17de62830079967b211059ebb \
|
||||
--hash=sha256:7473a8ed9ed09aeaa191301244a5a9dbe46fe0bf54f9d6cd21d83044c3321217 \
|
||||
--hash=sha256:7b0c6d57ab00dae9529f3faf187f2254ea0aa1e04215cf2f1a8ec277c96661bc \
|
||||
--hash=sha256:7b4c32e232a71f63a5d00259ca3d88345ce2a43295bb049d21061f338124246f \
|
||||
--hash=sha256:8177ec9676ea6e1793c8a084a90b65a9f778771998eb919d05db6d4b1c0b114c \
|
||||
--hash=sha256:839565cbf14645952d933853e8ade66a463684ed6ed6c9345d0faf1f0e868877 \
|
||||
--hash=sha256:875cb7764708b3132637f6c5fb385b16eeba0f7ac9fa45a69d35e09b47045801 \
|
||||
--hash=sha256:8a44788d9d91df72d1a5eac49b31aeb887a5f4aab761b4cffc4196c74907ea85 \
|
||||
--hash=sha256:8b4eb332f9501cb1cd3d4d099374a1e1306783ff95489a1026bde9eb02ccc34a \
|
||||
--hash=sha256:906306ac7afe2156fcf0042173d6ebbb05416af70f6b370967b47f8f00103bbb \
|
||||
--hash=sha256:992775c9fbe2cf794786fa0ffca7f09f564ba3499b8fe9f2f80bd7197db60383 \
|
||||
--hash=sha256:996a4d1834524adbb423385d5a629b868ef9d774670856c63c9a0408a3063401 \
|
||||
--hash=sha256:9a52f254ce051e196b8fe2af4634c2d2f02c981756c6464dc192f1b6050b4e28 \
|
||||
--hash=sha256:9d0ced62b59e0430b3690dbc5373df1c2aa7585e9a8ce38eff87f0fd993c5b01 \
|
||||
--hash=sha256:a140761c4ff63d0cb9256ac752f230460ee225ccef4ad8f68affc723c88e2036 \
|
||||
--hash=sha256:a184b2ea57b13680ab6d5fbde99ccef152c95c06746cb7718c583abd8f945ccc \
|
||||
--hash=sha256:a3db56f153bd4c5c2b619ab02c5db5192e222150ce5a1bc10f16164714bc39ac \
|
||||
--hash=sha256:a46b2f450bc79e06ef3b6394f0c68660529ed51692606ad7f953fc2e448bc903 \
|
||||
--hash=sha256:a884aef09d45ba1206712c7dbda5829562d3fea7726935d3289d343232ecb0d3 \
|
||||
--hash=sha256:b2cf105cee600d2de04ca3cfa1f74f1127f8455b71dbad02b9da6ec266e116d6 \
|
||||
--hash=sha256:b33a7884fabd72bdf5f910d0cf46be50dce86a0362a65cfc746a4168c67eb96c \
|
||||
--hash=sha256:b42d86938e8dda1cd9a1a87a6d82f1818eaf933348429653559a458d027446da \
|
||||
--hash=sha256:b6379e7546ba4ae4b18f8ae2b9bc5960936007a1c0e30b342f662577e8bc3299 \
|
||||
--hash=sha256:c7420a2696a44650120cdd269a5d2e56a477e2bfa9d95e86229059beb1c19e15 \
|
||||
--hash=sha256:c8651e0d4b3bdeda6602b85fdc2abbefc1b41e573ecb37b6779c4ca50753a199 \
|
||||
--hash=sha256:d066ea419f719ed87bc2c99a4a4bfd77c2e5949cb724588b9dd58f3fd90b92bf \
|
||||
--hash=sha256:e6c58beb17380f7c2ea181ea11e7db8c0ceb474c9dd45f48e71e2cb577d146a1 \
|
||||
--hash=sha256:e852d9dda9f93ad3651ae1e3bb770eac544ec93c3807888798eccddf84596537 \
|
||||
--hash=sha256:ec3681a0cb34c255d76dd9d865a55f260164adb9fa02628415cdc2d43ee2c05d \
|
||||
--hash=sha256:ee0c0b3b35b34f782afc673d503167157094a16f442ace7c6c5e0ca80b08f50c \
|
||||
--hash=sha256:eedacb5c5d22b7097482fa834bda0dafa3d914a4e829ec83cdea2a01f8c813c4 \
|
||||
--hash=sha256:ef00af0439ebfee806b25f24c8f92109157ff3fac5731dc7867957812e87b8d9 \
|
||||
--hash=sha256:f0e8817c7d1a0c2eedebf57ef9a9896f3ea23324769a9a2061a80fe8852705ed \
|
||||
--hash=sha256:f3d5be054c461d6a2268831f04091dc82753176f6ea06dc6047a5e168265a987 \
|
||||
--hash=sha256:f4b5c37a5f40e4d733d3bbaaef082149bee5a5ea3156a785ff64d949bd1353fa
|
||||
fonttools==4.61.1 \
|
||||
--hash=sha256:0de30bfe7745c0d1ffa2b0b7048fb7123ad0d71107e10ee090fa0b16b9452e87 \
|
||||
--hash=sha256:10d88e55330e092940584774ee5e8a6971b01fc2f4d3466a1d6c158230880796 \
|
||||
--hash=sha256:11f35ad7805edba3aac1a3710d104592df59f4b957e30108ae0ba6c10b11dd75 \
|
||||
--hash=sha256:15acc09befd16a0fb8a8f62bc147e1a82817542d72184acca9ce6e0aeda9fa6d \
|
||||
--hash=sha256:17d2bf5d541add43822bcf0c43d7d847b160c9bb01d15d5007d84e2217aaa371 \
|
||||
--hash=sha256:2180f14c141d2f0f3da43f3a81bc8aa4684860f6b0e6f9e165a4831f24e6a23b \
|
||||
--hash=sha256:21e7c8d76f62ab13c9472ccf74515ca5b9a761d1bde3265152a6dc58700d895b \
|
||||
--hash=sha256:41a7170d042e8c0024703ed13b71893519a1a6d6e18e933e3ec7507a2c26a4b2 \
|
||||
--hash=sha256:41ed4b5ec103bd306bb68f81dc166e77409e5209443e5773cb4ed837bcc9b0d3 \
|
||||
--hash=sha256:497c31ce314219888c0e2fce5ad9178ca83fe5230b01a5006726cdf3ac9f24d9 \
|
||||
--hash=sha256:4c1b526c8d3f615a7b1867f38a9410849c8f4aef078535742198e942fba0e9bd \
|
||||
--hash=sha256:4d7092bb38c53bbc78e9255a59158b150bcdc115a1e3b3ce0b5f267dc35dd63c \
|
||||
--hash=sha256:4f5686e1fe5fce75d82d93c47a438a25bf0d1319d2843a926f741140b2b16e0c \
|
||||
--hash=sha256:58b0ee0ab5b1fc9921eccfe11d1435added19d6494dde14e323f25ad2bc30c56 \
|
||||
--hash=sha256:5ce02f38a754f207f2f06557523cd39a06438ba3aafc0639c477ac409fc64e37 \
|
||||
--hash=sha256:5fade934607a523614726119164ff621e8c30e8fa1ffffbbd358662056ba69f0 \
|
||||
--hash=sha256:5fe9fd43882620017add5eabb781ebfbc6998ee49b35bd7f8f79af1f9f99a958 \
|
||||
--hash=sha256:64102ca87e84261419c3747a0d20f396eb024bdbeb04c2bfb37e2891f5fadcb5 \
|
||||
--hash=sha256:664c5a68ec406f6b1547946683008576ef8b38275608e1cee6c061828171c118 \
|
||||
--hash=sha256:6675329885c44657f826ef01d9e4fb33b9158e9d93c537d84ad8399539bc6f69 \
|
||||
--hash=sha256:75c1a6dfac6abd407634420c93864a1e274ebc1c7531346d9254c0d8f6ca00f9 \
|
||||
--hash=sha256:75da8f28eff26defba42c52986de97b22106cb8f26515b7c22443ebc9c2d3261 \
|
||||
--hash=sha256:77efb033d8d7ff233385f30c62c7c79271c8885d5c9657d967ede124671bbdfb \
|
||||
--hash=sha256:78a7d3ab09dc47ac1a363a493e6112d8cabed7ba7caad5f54dbe2f08676d1b47 \
|
||||
--hash=sha256:7c7db70d57e5e1089a274cbb2b1fd635c9a24de809a231b154965d415d6c6d24 \
|
||||
--hash=sha256:8c56c488ab471628ff3bfa80964372fc13504ece601e0d97a78ee74126b2045c \
|
||||
--hash=sha256:91669ccac46bbc1d09e9273546181919064e8df73488ea087dcac3e2968df9ba \
|
||||
--hash=sha256:9b666a475a65f4e839d3d10473fad6d47e0a9db14a2f4a224029c5bfde58ad2c \
|
||||
--hash=sha256:9cfef3ab326780c04d6646f68d4b4742aae222e8b8ea1d627c74e38afcbc9d91 \
|
||||
--hash=sha256:a13fc8aeb24bad755eea8f7f9d409438eb94e82cf86b08fe77a03fbc8f6a96b1 \
|
||||
--hash=sha256:a75c301f96db737e1c5ed5fd7d77d9c34466de16095a266509e13da09751bd19 \
|
||||
--hash=sha256:a76d4cb80f41ba94a6691264be76435e5f72f2cb3cab0b092a6212855f71c2f6 \
|
||||
--hash=sha256:aed04cabe26f30c1647ef0e8fbb207516fd40fe9472e9439695f5c6998e60ac5 \
|
||||
--hash=sha256:b148b56f5de675ee16d45e769e69f87623a4944f7443850bf9a9376e628a89d2 \
|
||||
--hash=sha256:b501c862d4901792adaec7c25b1ecc749e2662543f68bb194c42ba18d6eec98d \
|
||||
--hash=sha256:b846a1fcf8beadeb9ea4f44ec5bdde393e2f1569e17d700bfc49cd69bde75881 \
|
||||
--hash=sha256:b931ae8f62db78861b0ff1ac017851764602288575d65b8e8ff1963fed419063 \
|
||||
--hash=sha256:c33ab3ca9d3ccd581d58e989d67554e42d8d4ded94ab3ade3508455fe70e65f7 \
|
||||
--hash=sha256:c6604b735bb12fef8e0efd5578c9fb5d3d8532d5001ea13a19cddf295673ee09 \
|
||||
--hash=sha256:d8db08051fc9e7d8bc622f2112511b8107d8f27cd89e2f64ec45e9825e8288da \
|
||||
--hash=sha256:d9203500f7c63545b4ce3799319fe4d9feb1a1b89b28d3cb5abd11b9dd64147e \
|
||||
--hash=sha256:dc492779501fa723b04d0ab1f5be046797fee17d27700476edc7ee9ae535a61e \
|
||||
--hash=sha256:e6bcdf33aec38d16508ce61fd81838f24c83c90a1d1b8c68982857038673d6b8 \
|
||||
--hash=sha256:e76ce097e3c57c4bcb67c5aa24a0ecdbd9f74ea9219997a707a4061fbe2707aa \
|
||||
--hash=sha256:eff1ac3cc66c2ac7cda1e64b4e2f3ffef474b7335f92fc3833fc632d595fcee6 \
|
||||
--hash=sha256:f3cb4a569029b9f291f88aafc927dd53683757e640081ca8c412781ea144565e \
|
||||
--hash=sha256:f79b168428351d11e10c5aeb61a74e1851ec221081299f4cf56036a95431c43a \
|
||||
--hash=sha256:fa646ecec9528bef693415c79a86e733c70a4965dd938e9a226b0fc64c9d2e6c \
|
||||
--hash=sha256:fe2efccb324948a11dd09d22136fe2ac8a97d6c1347cf0b58a911dcd529f66b7 \
|
||||
--hash=sha256:fff4f534200a04b4a36e7ae3cb74493afe807b517a09e99cb4faa89a34ed6ecd
|
||||
# via weasyprint
|
||||
identify==2.6.15 \
|
||||
--hash=sha256:1181ef7608e00704db228516541eb83a88a9f94433a8c80bb9b5bd54b1d81757 \
|
||||
--hash=sha256:e4f4864b96c6557ef2a1e1c951771838f4edc9df3a72ec7118b338801b11c7bf
|
||||
identify==2.6.16 \
|
||||
--hash=sha256:391ee4d77741d994189522896270b787aed8670389bfd60f326d677d64a6dfb0 \
|
||||
--hash=sha256:846857203b5511bbe94d5a352a48ef2359532bc8f6727b5544077a0dcfb24980
|
||||
# via pre-commit
|
||||
nodeenv==1.9.1 \
|
||||
--hash=sha256:6ec12890a2dab7946721edbfbcd91f3319c6ccc9aec47be7c7e6b7011ee6645f \
|
||||
--hash=sha256:ba11c9782d29c27c70ffbdda2d7415098754709be8a7056d79a737cd901155c9
|
||||
nodeenv==1.10.0 \
|
||||
--hash=sha256:5bb13e3eed2923615535339b3c620e76779af4cb4c6a90deccc9e36b274d3827 \
|
||||
--hash=sha256:996c191ad80897d076bdfba80a41994c2b47c68e224c542b48feba42ba00f8bb
|
||||
# via pre-commit
|
||||
numpy==2.2.6 \
|
||||
--hash=sha256:038613e9fb8c72b0a41f025a7e4c3f0b7a1b5d768ece4796b674c8f3fe13efff \
|
||||
--hash=sha256:0678000bb9ac1475cd454c6b8c799206af8107e310843532b04d49649c717a47 \
|
||||
--hash=sha256:0811bb762109d9708cca4d0b13c4f67146e3c3b7cf8d34018c722adb2d957c84 \
|
||||
--hash=sha256:0b605b275d7bd0c640cad4e5d30fa701a8d59302e127e5f79138ad62762c3e3d \
|
||||
--hash=sha256:0bca768cd85ae743b2affdc762d617eddf3bcf8724435498a1e80132d04879e6 \
|
||||
--hash=sha256:1bc23a79bfabc5d056d106f9befb8d50c31ced2fbc70eedb8155aec74a45798f \
|
||||
--hash=sha256:287cc3162b6f01463ccd86be154f284d0893d2b3ed7292439ea97eafa8170e0b \
|
||||
--hash=sha256:37c0ca431f82cd5fa716eca9506aefcabc247fb27ba69c5062a6d3ade8cf8f49 \
|
||||
--hash=sha256:37e990a01ae6ec7fe7fa1c26c55ecb672dd98b19c3d0e1d1f326fa13cb38d163 \
|
||||
--hash=sha256:389d771b1623ec92636b0786bc4ae56abafad4a4c513d36a55dce14bd9ce8571 \
|
||||
--hash=sha256:3d70692235e759f260c3d837193090014aebdf026dfd167834bcba43e30c2a42 \
|
||||
--hash=sha256:41c5a21f4a04fa86436124d388f6ed60a9343a6f767fced1a8a71c3fbca038ff \
|
||||
--hash=sha256:481b49095335f8eed42e39e8041327c05b0f6f4780488f61286ed3c01368d491 \
|
||||
--hash=sha256:4eeaae00d789f66c7a25ac5f34b71a7035bb474e679f410e5e1a94deb24cf2d4 \
|
||||
--hash=sha256:55a4d33fa519660d69614a9fad433be87e5252f4b03850642f88993f7b2ca566 \
|
||||
--hash=sha256:5a6429d4be8ca66d889b7cf70f536a397dc45ba6faeb5f8c5427935d9592e9cf \
|
||||
--hash=sha256:5bd4fc3ac8926b3819797a7c0e2631eb889b4118a9898c84f585a54d475b7e40 \
|
||||
--hash=sha256:5beb72339d9d4fa36522fc63802f469b13cdbe4fdab4a288f0c441b74272ebfd \
|
||||
--hash=sha256:6031dd6dfecc0cf9f668681a37648373bddd6421fff6c66ec1624eed0180ee06 \
|
||||
--hash=sha256:71594f7c51a18e728451bb50cc60a3ce4e6538822731b2933209a1f3614e9282 \
|
||||
--hash=sha256:74d4531beb257d2c3f4b261bfb0fc09e0f9ebb8842d82a7b4209415896adc680 \
|
||||
--hash=sha256:7befc596a7dc9da8a337f79802ee8adb30a552a94f792b9c9d18c840055907db \
|
||||
--hash=sha256:894b3a42502226a1cac872f840030665f33326fc3dac8e57c607905773cdcde3 \
|
||||
--hash=sha256:8e41fd67c52b86603a91c1a505ebaef50b3314de0213461c7a6e99c9a3beff90 \
|
||||
--hash=sha256:8e9ace4a37db23421249ed236fdcdd457d671e25146786dfc96835cd951aa7c1 \
|
||||
--hash=sha256:8fc377d995680230e83241d8a96def29f204b5782f371c532579b4f20607a289 \
|
||||
--hash=sha256:9551a499bf125c1d4f9e250377c1ee2eddd02e01eac6644c080162c0c51778ab \
|
||||
--hash=sha256:b0544343a702fa80c95ad5d3d608ea3599dd54d4632df855e4c8d24eb6ecfa1c \
|
||||
--hash=sha256:b093dd74e50a8cba3e873868d9e93a85b78e0daf2e98c6797566ad8044e8363d \
|
||||
--hash=sha256:b412caa66f72040e6d268491a59f2c43bf03eb6c96dd8f0307829feb7fa2b6fb \
|
||||
--hash=sha256:b4f13750ce79751586ae2eb824ba7e1e8dba64784086c98cdbbcc6a42112ce0d \
|
||||
--hash=sha256:b64d8d4d17135e00c8e346e0a738deb17e754230d7e0810ac5012750bbd85a5a \
|
||||
--hash=sha256:ba10f8411898fc418a521833e014a77d3ca01c15b0c6cdcce6a0d2897e6dbbdf \
|
||||
--hash=sha256:bd48227a919f1bafbdda0583705e547892342c26fb127219d60a5c36882609d1 \
|
||||
--hash=sha256:c1f9540be57940698ed329904db803cf7a402f3fc200bfe599334c9bd84a40b2 \
|
||||
--hash=sha256:c820a93b0255bc360f53eca31a0e676fd1101f673dda8da93454a12e23fc5f7a \
|
||||
--hash=sha256:ce47521a4754c8f4593837384bd3424880629f718d87c5d44f8ed763edd63543 \
|
||||
--hash=sha256:d042d24c90c41b54fd506da306759e06e568864df8ec17ccc17e9e884634fd00 \
|
||||
--hash=sha256:de749064336d37e340f640b05f24e9e3dd678c57318c7289d222a8a2f543e90c \
|
||||
--hash=sha256:e1dda9c7e08dc141e0247a5b8f49cf05984955246a327d4c48bda16821947b2f \
|
||||
--hash=sha256:e29554e2bef54a90aa5cc07da6ce955accb83f21ab5de01a62c8478897b264fd \
|
||||
--hash=sha256:e3143e4451880bed956e706a3220b4e5cf6172ef05fcc397f6f36a550b1dd868 \
|
||||
--hash=sha256:e8213002e427c69c45a52bbd94163084025f533a55a59d6f9c5b820774ef3303 \
|
||||
--hash=sha256:efd28d4e9cd7d7a8d39074a4d44c63eda73401580c5c76acda2ce969e0a38e83 \
|
||||
--hash=sha256:f0fd6321b839904e15c46e0d257fdd101dd7f530fe03fd6359c1ea63738703f3 \
|
||||
--hash=sha256:f1372f041402e37e5e633e586f62aa53de2eac8d98cbfb822806ce4bbefcb74d \
|
||||
--hash=sha256:f2618db89be1b4e05f7a1a847a9c1c0abd63e63a1607d892dd54668dd92faf87 \
|
||||
--hash=sha256:f447e6acb680fd307f40d3da4852208af94afdfab89cf850986c3ca00562f4fa \
|
||||
--hash=sha256:f92729c95468a2f4f15e9bb94c432a9229d0d50de67304399627a943201baa2f \
|
||||
--hash=sha256:f9f1adb22318e121c5c69a09142811a201ef17ab257a1e66ca3025065b7f53ae \
|
||||
--hash=sha256:fc0c5673685c508a142ca65209b4e79ed6740a4ed6b2267dbba90f34b0b3cfda \
|
||||
--hash=sha256:fc7b73d02efb0e18c000e9ad8b83480dfcd5dfd11065997ed4c6747470ae8915 \
|
||||
--hash=sha256:fd83c01228a688733f1ded5201c678f0c53ecc1006ffbc404db9f7a899ac6249 \
|
||||
--hash=sha256:fe27749d33bb772c80dcd84ae7e8df2adc920ae8297400dabec45f0dedb3f6de \
|
||||
--hash=sha256:fee4236c876c4e8369388054d02d0e9bb84821feb1a64dd59e137e6511a551f8
|
||||
numpy==2.4.1 \
|
||||
--hash=sha256:0093e85df2960d7e4049664b26afc58b03236e967fb942354deef3208857a04c \
|
||||
--hash=sha256:09aa8a87e45b55a1c2c205d42e2808849ece5c484b2aab11fecabec3841cafba \
|
||||
--hash=sha256:0cce2a669e3c8ba02ee563c7835f92c153cf02edff1ae05e1823f1dde21b16a5 \
|
||||
--hash=sha256:0e6e8f9d9ecf95399982019c01223dc130542960a12edfa8edd1122dfa66a8a8 \
|
||||
--hash=sha256:0f118ce6b972080ba0758c6087c3617b5ba243d806268623dc34216d69099ba0 \
|
||||
--hash=sha256:178de8f87948163d98a4c9ab5bee4ce6519ca918926ec8df195af582de28544d \
|
||||
--hash=sha256:18e14c4d09d55eef39a6ab5b08406e84bc6869c1e34eef45564804f90b7e0574 \
|
||||
--hash=sha256:2023ef86243690c2791fd6353e5b4848eedaa88ca8a2d129f462049f6d484696 \
|
||||
--hash=sha256:20d4649c773f66cc2fc36f663e091f57c3b7655f936a4c681b4250855d1da8f5 \
|
||||
--hash=sha256:2302dc0224c1cbc49bb94f7064f3f923a971bfae45c33870dcbff63a2a550505 \
|
||||
--hash=sha256:26f0bcd9c79a00e339565b303badc74d3ea2bd6d52191eeca5f95936cad107d0 \
|
||||
--hash=sha256:297c72b1b98100c2e8f873d5d35fb551fce7040ade83d67dd51d38c8d42a2162 \
|
||||
--hash=sha256:2f44de05659b67d20499cbc96d49f2650769afcb398b79b324bb6e297bfe3844 \
|
||||
--hash=sha256:2ffd257026eb1b34352e749d7cc1678b5eeec3e329ad8c9965a797e08ccba205 \
|
||||
--hash=sha256:382ad67d99ef49024f11d1ce5dcb5ad8432446e4246a4b014418ba3a1175a1f4 \
|
||||
--hash=sha256:3869ea1ee1a1edc16c29bbe3a2f2a4e515cc3a44d43903ad41e0cacdbaf733dc \
|
||||
--hash=sha256:3d1a100e48cb266090a031397863ff8a30050ceefd798f686ff92c67a486753d \
|
||||
--hash=sha256:423797bdab2eeefbe608d7c1ec7b2b4fd3c58d51460f1ee26c7500a1d9c9ee93 \
|
||||
--hash=sha256:42d7dd5fa36d16d52a84f821eb96031836fd405ee6955dd732f2023724d0aa01 \
|
||||
--hash=sha256:49e792ec351315e16da54b543db06ca8a86985ab682602d90c60ef4ff4db2a9c \
|
||||
--hash=sha256:4e53170557d37ae404bf8d542ca5b7c629d6efa1117dac6a83e394142ea0a43f \
|
||||
--hash=sha256:4f1b68ff47680c2925f8063402a693ede215f0257f02596b1318ecdfb1d79e33 \
|
||||
--hash=sha256:4f9c360ecef085e5841c539a9a12b883dff005fbd7ce46722f5e9cef52634d82 \
|
||||
--hash=sha256:529050522e983e00a6c1c6b67411083630de8b57f65e853d7b03d9281b8694d2 \
|
||||
--hash=sha256:52b5f61bdb323b566b528899cc7db2ba5d1015bda7ea811a8bcf3c89c331fa42 \
|
||||
--hash=sha256:538bf4ec353709c765ff75ae616c34d3c3dca1a68312727e8f2676ea644f8509 \
|
||||
--hash=sha256:5adf01965456a664fc727ed69cc71848f28d063217c63e1a0e200a118d5eec9a \
|
||||
--hash=sha256:5b55aa56165b17aaf15520beb9cbd33c9039810e0d9643dd4379e44294c7303e \
|
||||
--hash=sha256:5d558123217a83b2d1ba316b986e9248a1ed1971ad495963d555ccd75dcb1556 \
|
||||
--hash=sha256:5de60946f14ebe15e713a6f22850c2372fa72f4ff9a432ab44aa90edcadaa65a \
|
||||
--hash=sha256:62fea415f83ad8fdb6c20840578e5fbaf5ddd65e0ec6c3c47eda0f69da172510 \
|
||||
--hash=sha256:6436cffb4f2bf26c974344439439c95e152c9a527013f26b3577be6c2ca64295 \
|
||||
--hash=sha256:6461de5113088b399d655d45c3897fa188766415d0f568f175ab071c8873bd73 \
|
||||
--hash=sha256:69e7419c9012c4aaf695109564e3387f1259f001b4326dfa55907b098af082d3 \
|
||||
--hash=sha256:71abbea030f2cfc3092a0ff9f8c8fdefdc5e0bf7d9d9c99663538bb0ecdac0b9 \
|
||||
--hash=sha256:7211b95ca365519d3596a1d8688a95874cc94219d417504d9ecb2df99fa7bfa8 \
|
||||
--hash=sha256:727c6c3275ddefa0dc078524a85e064c057b4f4e71ca5ca29a19163c607be745 \
|
||||
--hash=sha256:79e9e06c4c2379db47f3f6fc7a8652e7498251789bf8ff5bd43bf478ef314ca2 \
|
||||
--hash=sha256:7ad270f438cbdd402c364980317fb6b117d9ec5e226fff5b4148dd9aa9fc6e02 \
|
||||
--hash=sha256:7d5d7999df434a038d75a748275cd6c0094b0ecdb0837342b332a82defc4dc4d \
|
||||
--hash=sha256:8097529164c0f3e32bb89412a0905d9100bf434d9692d9fc275e18dcf53c9344 \
|
||||
--hash=sha256:82c55962006156aeef1629b953fd359064aa47e4d82cfc8e67f0918f7da3344f \
|
||||
--hash=sha256:8361ea4220d763e54cff2fbe7d8c93526b744f7cd9ddab47afeff7e14e8503be \
|
||||
--hash=sha256:899d2c18024984814ac7e83f8f49d8e8180e2fbe1b2e252f2e7f1d06bea92425 \
|
||||
--hash=sha256:8ad35f20be147a204e28b6a0575fbf3540c5e5f802634d4258d55b1ff5facce1 \
|
||||
--hash=sha256:8f085da926c0d491ffff3096f91078cc97ea67e7e6b65e490bc8dcda65663be2 \
|
||||
--hash=sha256:9171a42fcad32dcf3fa86f0a4faa5e9f8facefdb276f54b8b390d90447cff4e2 \
|
||||
--hash=sha256:92a0e65272fd60bfa0d9278e0484c2f52fe03b97aedc02b357f33fe752c52ffb \
|
||||
--hash=sha256:941c2a93313d030f219f3a71fd3d91a728b82979a5e8034eb2e60d394a2b83f9 \
|
||||
--hash=sha256:98b35775e03ab7f868908b524fc0a84d38932d8daf7b7e1c3c3a1b6c7a2c9f15 \
|
||||
--hash=sha256:a1ceafc5042451a858231588a104093474c6a5c57dcc724841f5c888d237d690 \
|
||||
--hash=sha256:a73044b752f5d34d4232f25f18160a1cc418ea4507f5f11e299d8ac36875f8a0 \
|
||||
--hash=sha256:a7870e8c5fc11aef57d6fea4b4085e537a3a60ad2cdd14322ed531fdca68d261 \
|
||||
--hash=sha256:a92f227dbcdc9e4c3e193add1a189a9909947d4f8504c576f4a732fd0b54240a \
|
||||
--hash=sha256:ac08c63cb7779b85e9d5318e6c3518b424bc1f364ac4cb2c6136f12e5ff2dccc \
|
||||
--hash=sha256:b6bcf39112e956594b3331316d90c90c90fb961e39696bda97b89462f5f3943f \
|
||||
--hash=sha256:c0faba4a331195bfa96f93dd9dfaa10b2c7aa8cda3a02b7fd635e588fe821bf5 \
|
||||
--hash=sha256:ce9ce141a505053b3c7bce3216071f3bf5c182b8b28930f14cd24d43932cd2df \
|
||||
--hash=sha256:cf6470d91d34bf669f61d515499859fa7a4c2f7c36434afb70e82df7217933f9 \
|
||||
--hash=sha256:d3703409aac693fa82c0aee023a1ae06a6e9d065dba10f5e8e80f642f1e9d0a2 \
|
||||
--hash=sha256:d3e3087f53e2b4428766b54932644d148613c5a595150533ae7f00dab2f319a8 \
|
||||
--hash=sha256:d3f8f0df9f4b8be57b3bf74a1d087fec68f927a2fab68231fdb442bf2c12e426 \
|
||||
--hash=sha256:d797454e37570cfd61143b73b8debd623c3c0952959adb817dd310a483d58a1b \
|
||||
--hash=sha256:e1a27bb1b2dee45a2a53f5ca6ff2d1a7f135287883a1689e930d44d1ff296c87 \
|
||||
--hash=sha256:e3bd2cb07841166420d2fa7146c96ce00cb3410664cbc1a6be028e456c4ee220 \
|
||||
--hash=sha256:e7b6b5e28bbd47b7532698e5db2fe1db693d84b58c254e4389d99a27bb9b8f6b \
|
||||
--hash=sha256:e867df947d427cdd7a60e3e271729090b0f0df80f5f10ab7dd436f40811699c3 \
|
||||
--hash=sha256:ea66d2b41ca4a1630aae5507ee0a71647d3124d1741980138aa8f28f44dac36e \
|
||||
--hash=sha256:edee228f76ee2dab4579fad6f51f6a305de09d444280109e0f75df247ff21501 \
|
||||
--hash=sha256:f0a90aba7d521e6954670550e561a4cb925713bd944445dbe9e729b71f6cabee \
|
||||
--hash=sha256:f93bc6892fe7b0663e5ffa83b61aab510aacffd58c16e012bb9352d489d90cb7 \
|
||||
--hash=sha256:fb1461c99de4d040666ca0444057b06541e5642f800b71c56e6ea92d6a853a0c
|
||||
# via opencv-python-headless
|
||||
opencv-python-headless==4.12.0.88 \
|
||||
--hash=sha256:1e58d664809b3350c1123484dd441e1667cd7bed3086db1b9ea1b6f6cb20b50e \
|
||||
--hash=sha256:236c8df54a90f4d02076e6f9c1cc763d794542e886c576a6fee46ec8ff75a7a9 \
|
||||
--hash=sha256:365bb2e486b50feffc2d07a405b953a8f3e8eaa63865bc650034e5c71e7a5154 \
|
||||
--hash=sha256:86b413bdd6c6bf497832e346cd5371995de148e579b9774f8eba686dee3f5528 \
|
||||
--hash=sha256:aeb4b13ecb8b4a0beb2668ea07928160ea7c2cd2d9b5ef571bbee6bafe9cc8d0 \
|
||||
--hash=sha256:cfdc017ddf2e59b6c2f53bc12d74b6b0be7ded4ec59083ea70763921af2b6c09 \
|
||||
--hash=sha256:fde2cf5c51e4def5f2132d78e0c08f9c14783cd67356922182c6845b9af87dbd
|
||||
opencv-python-headless==4.13.0.90 \
|
||||
--hash=sha256:0e0c8c9f620802fddc4fa7f471a1d263c7b0dca16cd9e7e2f996bb8bd2128c0c \
|
||||
--hash=sha256:12a28674f215542c9bf93338de1b5bffd76996d32da9acb9e739fdb9c8bbd738 \
|
||||
--hash=sha256:32255203040dc98803be96362e13f9e4bce20146898222d2e5c242f80de50da5 \
|
||||
--hash=sha256:96060fc57a1abb1144b0b8129e2ff3bfcdd0ccd8e8bd05bd85256ff4ed587d3b \
|
||||
--hash=sha256:dbc1f4625e5af3a80ebdbd84380227c0f445228588f2521b11af47710caca1ba \
|
||||
--hash=sha256:e13790342591557050157713af17a7435ac1b50c65282715093c9297fa045d8f \
|
||||
--hash=sha256:eba38bc255d0b7d1969c5bcc90a060ca2b61a3403b613872c750bfa5dfe9e03b \
|
||||
--hash=sha256:f46b17ea0aa7e4124ca6ad71143f89233ae9557f61d2326bcdb34329a1ddf9bd
|
||||
# via -r .github/scripts/requirements_dev.in
|
||||
pdf2image==1.17.0 \
|
||||
--hash=sha256:eaa959bc116b420dd7ec415fcae49b98100dda3dd18cd2fdfa86d09f112f6d57 \
|
||||
--hash=sha256:ecdd58d7afb810dffe21ef2b1bbc057ef434dabbac6c33778a38a3f7744a27e2
|
||||
# via -r .github/scripts/requirements_dev.in
|
||||
pillow==12.0.0 \
|
||||
--hash=sha256:0869154a2d0546545cde61d1789a6524319fc1897d9ee31218eae7a60ccc5643 \
|
||||
--hash=sha256:09f2d0abef9e4e2f349305a4f8cc784a8a6c2f58a8c4892eea13b10a943bd26e \
|
||||
--hash=sha256:0b817e7035ea7f6b942c13aa03bb554fc44fea70838ea21f8eb31c638326584e \
|
||||
--hash=sha256:0fd00cac9c03256c8b2ff58f162ebcd2587ad3e1f2e397eab718c47e24d231cc \
|
||||
--hash=sha256:110486b79f2d112cf6add83b28b627e369219388f64ef2f960fef9ebaf54c642 \
|
||||
--hash=sha256:1979f4566bb96c1e50a62d9831e2ea2d1211761e5662afc545fa766f996632f6 \
|
||||
--hash=sha256:1ac11e8ea4f611c3c0147424eae514028b5e9077dd99ab91e1bd7bc33ff145e1 \
|
||||
--hash=sha256:1b1b133e6e16105f524a8dec491e0586d072948ce15c9b914e41cdadd209052b \
|
||||
--hash=sha256:1ee80a59f6ce048ae13cda1abf7fbd2a34ab9ee7d401c46be3ca685d1999a399 \
|
||||
--hash=sha256:21f241bdd5080a15bc86d3466a9f6074a9c2c2b314100dd896ac81ee6db2f1ba \
|
||||
--hash=sha256:266cd5f2b63ff316d5a1bba46268e603c9caf5606d44f38c2873c380950576ad \
|
||||
--hash=sha256:26d9f7d2b604cd23aba3e9faf795787456ac25634d82cd060556998e39c6fa47 \
|
||||
--hash=sha256:27f95b12453d165099c84f8a8bfdfd46b9e4bda9e0e4b65f0635430027f55739 \
|
||||
--hash=sha256:2c54c1a783d6d60595d3514f0efe9b37c8808746a66920315bfd34a938d7994b \
|
||||
--hash=sha256:2fa5f0b6716fc88f11380b88b31fe591a06c6315e955c096c35715788b339e3f \
|
||||
--hash=sha256:32ed80ea8a90ee3e6fa08c21e2e091bba6eda8eccc83dbc34c95169507a91f10 \
|
||||
--hash=sha256:3830c769decf88f1289680a59d4f4c46c72573446352e2befec9a8512104fa52 \
|
||||
--hash=sha256:38df9b4bfd3db902c9c2bd369bcacaf9d935b2fff73709429d95cc41554f7b3d \
|
||||
--hash=sha256:3adfb466bbc544b926d50fe8f4a4e6abd8c6bffd28a26177594e6e9b2b76572b \
|
||||
--hash=sha256:3e42edad50b6909089750e65c91aa09aaf1e0a71310d383f11321b27c224ed8a \
|
||||
--hash=sha256:4078242472387600b2ce8d93ade8899c12bf33fa89e55ec89fe126e9d6d5d9e9 \
|
||||
--hash=sha256:455247ac8a4cfb7b9bc45b7e432d10421aea9fc2e74d285ba4072688a74c2e9d \
|
||||
--hash=sha256:4cc6b3b2efff105c6a1656cfe59da4fdde2cda9af1c5e0b58529b24525d0a098 \
|
||||
--hash=sha256:4cf7fed4b4580601c4345ceb5d4cbf5a980d030fd5ad07c4d2ec589f95f09905 \
|
||||
--hash=sha256:5193fde9a5f23c331ea26d0cf171fbf67e3f247585f50c08b3e205c7aeb4589b \
|
||||
--hash=sha256:5269cc1caeedb67e6f7269a42014f381f45e2e7cd42d834ede3c703a1d915fe3 \
|
||||
--hash=sha256:53561a4ddc36facb432fae7a9d8afbfaf94795414f5cdc5fc52f28c1dca90371 \
|
||||
--hash=sha256:55f818bd74fe2f11d4d7cbc65880a843c4075e0ac7226bc1a23261dbea531953 \
|
||||
--hash=sha256:58eea5ebe51504057dd95c5b77d21700b77615ab0243d8152793dc00eb4faf01 \
|
||||
--hash=sha256:5d5c411a8eaa2299322b647cd932586b1427367fd3184ffbb8f7a219ea2041ca \
|
||||
--hash=sha256:6846bd2d116ff42cba6b646edf5bf61d37e5cbd256425fa089fee4ff5c07a99e \
|
||||
--hash=sha256:6ace95230bfb7cd79ef66caa064bbe2f2a1e63d93471c3a2e1f1348d9f22d6b7 \
|
||||
--hash=sha256:6e51b71417049ad6ab14c49608b4a24d8fb3fe605e5dfabfe523b58064dc3d27 \
|
||||
--hash=sha256:71db6b4c1653045dacc1585c1b0d184004f0d7e694c7b34ac165ca70c0838082 \
|
||||
--hash=sha256:7438839e9e053ef79f7112c881cef684013855016f928b168b81ed5835f3e75e \
|
||||
--hash=sha256:759de84a33be3b178a64c8ba28ad5c135900359e85fb662bc6e403ad4407791d \
|
||||
--hash=sha256:792a2c0be4dcc18af9d4a2dfd8a11a17d5e25274a1062b0ec1c2d79c76f3e7f8 \
|
||||
--hash=sha256:7d87ef5795da03d742bf49439f9ca4d027cde49c82c5371ba52464aee266699a \
|
||||
--hash=sha256:7dfb439562f234f7d57b1ac6bc8fe7f838a4bd49c79230e0f6a1da93e82f1fad \
|
||||
--hash=sha256:7fa22993bac7b77b78cae22bad1e2a987ddf0d9015c63358032f84a53f23cdc3 \
|
||||
--hash=sha256:805ebf596939e48dbb2e4922a1d3852cfc25c38160751ce02da93058b48d252a \
|
||||
--hash=sha256:82240051c6ca513c616f7f9da06e871f61bfd7805f566275841af15015b8f98d \
|
||||
--hash=sha256:87d4f8125c9988bfbed67af47dd7a953e2fc7b0cc1e7800ec6d2080d490bb353 \
|
||||
--hash=sha256:8d8ca2b210ada074d57fcee40c30446c9562e542fc46aedc19baf758a93532ee \
|
||||
--hash=sha256:8dc232e39d409036af549c86f24aed8273a40ffa459981146829a324e0848b4b \
|
||||
--hash=sha256:90387104ee8400a7b4598253b4c406f8958f59fcf983a6cea2b50d59f7d63d0b \
|
||||
--hash=sha256:905b0365b210c73afb0ebe9101a32572152dfd1c144c7e28968a331b9217b94a \
|
||||
--hash=sha256:99353a06902c2e43b43e8ff74ee65a7d90307d82370604746738a1e0661ccca7 \
|
||||
--hash=sha256:99a7f72fb6249302aa62245680754862a44179b545ded638cf1fef59befb57ef \
|
||||
--hash=sha256:9f0b04c6b8584c2c193babcccc908b38ed29524b29dd464bc8801bf10d746a3a \
|
||||
--hash=sha256:9fe611163f6303d1619bbcb653540a4d60f9e55e622d60a3108be0d5b441017a \
|
||||
--hash=sha256:a3475b96f5908b3b16c47533daaa87380c491357d197564e0ba34ae75c0f3257 \
|
||||
--hash=sha256:a6597ff2b61d121172f5844b53f21467f7082f5fb385a9a29c01414463f93b07 \
|
||||
--hash=sha256:a7921c5a6d31b3d756ec980f2f47c0cfdbce0fc48c22a39347a895f41f4a6ea4 \
|
||||
--hash=sha256:aa5129de4e174daccbc59d0a3b6d20eaf24417d59851c07ebb37aeb02947987c \
|
||||
--hash=sha256:aeaefa96c768fc66818730b952a862235d68825c178f1b3ffd4efd7ad2edcb7c \
|
||||
--hash=sha256:afbefa430092f71a9593a99ab6a4e7538bc9eabbf7bf94f91510d3503943edc4 \
|
||||
--hash=sha256:aff9e4d82d082ff9513bdd6acd4f5bd359f5b2c870907d2b0a9c5e10d40c88fe \
|
||||
--hash=sha256:b22bd8c974942477156be55a768f7aa37c46904c175be4e158b6a86e3a6b7ca8 \
|
||||
--hash=sha256:b290fd8aa38422444d4b50d579de197557f182ef1068b75f5aa8558638b8d0a5 \
|
||||
--hash=sha256:b2e4b27a6e15b04832fe9bf292b94b5ca156016bbc1ea9c2c20098a0320d6cf6 \
|
||||
--hash=sha256:b583dc9070312190192631373c6c8ed277254aa6e6084b74bdd0a6d3b221608e \
|
||||
--hash=sha256:b87843e225e74576437fd5b6a4c2205d422754f84a06942cfaf1dc32243e45a8 \
|
||||
--hash=sha256:bc91a56697869546d1b8f0a3ff35224557ae7f881050e99f615e0119bf934b4e \
|
||||
--hash=sha256:bd87e140e45399c818fac4247880b9ce719e4783d767e030a883a970be632275 \
|
||||
--hash=sha256:bde737cff1a975b70652b62d626f7785e0480918dece11e8fef3c0cf057351c3 \
|
||||
--hash=sha256:bdee52571a343d721fb2eb3b090a82d959ff37fc631e3f70422e0c2e029f3e76 \
|
||||
--hash=sha256:bee2a6db3a7242ea309aa7ee8e2780726fed67ff4e5b40169f2c940e7eb09227 \
|
||||
--hash=sha256:beeae3f27f62308f1ddbcfb0690bf44b10732f2ef43758f169d5e9303165d3f9 \
|
||||
--hash=sha256:c50f36a62a22d350c96e49ad02d0da41dbd17ddc2e29750dbdba4323f85eb4a5 \
|
||||
--hash=sha256:c607c90ba67533e1b2355b821fef6764d1dd2cbe26b8c1005ae84f7aea25ff79 \
|
||||
--hash=sha256:c7b2a63fd6d5246349f3d3f37b14430d73ee7e8173154461785e43036ffa96ca \
|
||||
--hash=sha256:c828a1ae702fc712978bda0320ba1b9893d99be0badf2647f693cc01cf0f04fa \
|
||||
--hash=sha256:c85de1136429c524e55cfa4e033b4a7940ac5c8ee4d9401cc2d1bf48154bbc7b \
|
||||
--hash=sha256:c98fa880d695de164b4135a52fd2e9cd7b7c90a9d8ac5e9e443a24a95ef9248e \
|
||||
--hash=sha256:cae81479f77420d217def5f54b5b9d279804d17e982e0f2fa19b1d1e14ab5197 \
|
||||
--hash=sha256:d034140032870024e6b9892c692fe2968493790dd57208b2c37e3fb35f6df3ab \
|
||||
--hash=sha256:d120c38a42c234dc9a8c5de7ceaaf899cf33561956acb4941653f8bdc657aa79 \
|
||||
--hash=sha256:d4827615da15cd59784ce39d3388275ec093ae3ee8d7f0c089b76fa87af756c2 \
|
||||
--hash=sha256:d49e2314c373f4c2b39446fb1a45ed333c850e09d0c59ac79b72eb3b95397363 \
|
||||
--hash=sha256:d52610d51e265a51518692045e372a4c363056130d922a7351429ac9f27e70b0 \
|
||||
--hash=sha256:d64317d2587c70324b79861babb9c09f71fbb780bad212018874b2c013d8600e \
|
||||
--hash=sha256:d77153e14b709fd8b8af6f66a3afbb9ed6e9fc5ccf0b6b7e1ced7b036a228782 \
|
||||
--hash=sha256:d7e091d464ac59d2c7ad8e7e08105eaf9dafbc3883fd7265ffccc2baad6ac925 \
|
||||
--hash=sha256:dd333073e0cacdc3089525c7df7d39b211bcdf31fc2824e49d01c6b6187b07d0 \
|
||||
--hash=sha256:e5d8efac84c9afcb40914ab49ba063d94f5dbdf5066db4482c66a992f47a3a3b \
|
||||
--hash=sha256:f135c702ac42262573fe9714dfe99c944b4ba307af5eb507abef1667e2cbbced \
|
||||
--hash=sha256:f13711b1a5ba512d647a0e4ba79280d3a9a045aaf7e0cc6fbe96b91d4cdf6b0c \
|
||||
--hash=sha256:f4f1231b7dec408e8670264ce63e9c71409d9583dd21d32c163e25213ee2a344 \
|
||||
--hash=sha256:fa3ed2a29a9e9d2d488b4da81dcb54720ac3104a20bf0bd273f1e4648aff5af9 \
|
||||
--hash=sha256:fb3096c30df99fd01c7bf8e544f392103d0795b9f98ba71a8054bcbf56b255f1
|
||||
pillow==12.1.0 \
|
||||
--hash=sha256:00162e9ca6d22b7c3ee8e61faa3c3253cd19b6a37f126cad04f2f88b306f557d \
|
||||
--hash=sha256:079af2fb0c599c2ec144ba2c02766d1b55498e373b3ac64687e43849fbbef5bc \
|
||||
--hash=sha256:0b022eaaf709541b391ee069f0022ee5b36c709df71986e3f7be312e46f42c84 \
|
||||
--hash=sha256:0c27407a2d1b96774cbc4a7594129cc027339fd800cd081e44497722ea1179de \
|
||||
--hash=sha256:0ddedfaa8b5f0b4ffbc2fa87b556dc59f6bb4ecb14a53b33f9189713ae8053c0 \
|
||||
--hash=sha256:0deedf2ea233722476b3a81e8cdfbad786f7adbed5d848469fa59fe52396e4ef \
|
||||
--hash=sha256:0ed07dca4a8464bada6139ab38f5382f83e5f111698caf3191cb8dbf27d908b4 \
|
||||
--hash=sha256:0fde7ec5538ab5095cc02df38ee99b0443ff0e1c847a045554cf5f9af1f4aa82 \
|
||||
--hash=sha256:15c794d74303828eaa957ff8070846d0efe8c630901a1c753fdc63850e19ecd9 \
|
||||
--hash=sha256:1a949604f73eb07a8adab38c4fe50791f9919344398bdc8ac6b307f755fc7030 \
|
||||
--hash=sha256:1f345e7bc9d7f368887c712aa5054558bad44d2a301ddf9248599f4161abc7c0 \
|
||||
--hash=sha256:1fcc52d86ce7a34fd17cb04e87cfdb164648a3662a6f20565910a99653d66c18 \
|
||||
--hash=sha256:21e686a21078b0f9cb8c8a961d99e6a4ddb88e0fc5ea6e130172ddddc2e5221a \
|
||||
--hash=sha256:2415373395a831f53933c23ce051021e79c8cd7979822d8cc478547a3f4da8ef \
|
||||
--hash=sha256:277518bf4fe74aa91489e1b20577473b19ee70fb97c374aa50830b279f25841b \
|
||||
--hash=sha256:27b9baecb428899db6c0de572d6d305cfaf38ca1596b5c0542a5182e3e74e8c6 \
|
||||
--hash=sha256:29a4cef9cb672363926f0470afc516dbf7305a14d8c54f7abbb5c199cd8f8179 \
|
||||
--hash=sha256:3413c2ae377550f5487991d444428f1a8ae92784aac79caa8b1e3b89b175f77e \
|
||||
--hash=sha256:351889afef0f485b84078ea40fe33727a0492b9af3904661b0abbafee0355b72 \
|
||||
--hash=sha256:3ffaa2f0659e2f740473bcf03c702c39a8d4b2b7ffc629052028764324842c64 \
|
||||
--hash=sha256:40a8e3b9e8773876d6e30daed22f016509e3987bab61b3b7fe309d7019a87451 \
|
||||
--hash=sha256:414b9a78e14ffeb98128863314e62c3f24b8a86081066625700b7985b3f529bd \
|
||||
--hash=sha256:43aca0a55ce1eefc0aefa6253661cb54571857b1a7b2964bd8a1e3ef4b729924 \
|
||||
--hash=sha256:43b4899cfd091a9693a1278c4982f3e50f7fb7cff5153b05174b4afc9593b616 \
|
||||
--hash=sha256:461f9dfdafa394c59cd6d818bdfdbab4028b83b02caadaff0ffd433faf4c9a7a \
|
||||
--hash=sha256:4f9f6a650743f0ddee5593ac9e954ba1bdbc5e150bc066586d4f26127853ab94 \
|
||||
--hash=sha256:53d8b764726d3af1a138dd353116f774e3862ec7e3794e0c8781e30db0f35dfc \
|
||||
--hash=sha256:565c986f4b45c020f5421a4cea13ef294dde9509a8577f29b2fc5edc7587fff8 \
|
||||
--hash=sha256:5c5ae0a06e9ea030ab786b0251b32c7e4ce10e58d983c0d5c56029455180b5b9 \
|
||||
--hash=sha256:5cb7bc1966d031aec37ddb9dcf15c2da5b2e9f7cc3ca7c54473a20a927e1eb91 \
|
||||
--hash=sha256:5da841d81b1a05ef940a8567da92decaa15bc4d7dedb540a8c219ad83d91808a \
|
||||
--hash=sha256:5fee4c04aad8932da9f8f710af2c1a15a83582cfb884152a9caa79d4efcdbf9c \
|
||||
--hash=sha256:609e89d9f90b581c8d16358c9087df76024cf058fa693dd3e1e1620823f39670 \
|
||||
--hash=sha256:6258f3260986990ba2fa8a874f8b6e808cf5abb51a94015ca3dc3c68aa4f30ea \
|
||||
--hash=sha256:64efdf00c09e31efd754448a383ea241f55a994fd079866b92d2bbff598aad91 \
|
||||
--hash=sha256:65b80c1ee7e14a87d6a068dd3b0aea268ffcabfe0498d38661b00c5b4b22e74c \
|
||||
--hash=sha256:6741e6f3074a35e47c77b23a4e4f2d90db3ed905cb1c5e6e0d49bff2045632bc \
|
||||
--hash=sha256:681088909d7e8fa9e31b9799aaa59ba5234c58e5e4f1951b4c4d1082a2e980e0 \
|
||||
--hash=sha256:6b7a9d1db5dad90e2991645874f708e87d9a3c370c243c2d7684d28f7e133e6b \
|
||||
--hash=sha256:7315f9137087c4e0ee73a761b163fc9aa3b19f5f606a7fc08d83fd3e4379af65 \
|
||||
--hash=sha256:742aea052cf5ab5034a53c3846165bc3ce88d7c38e954120db0ab867ca242661 \
|
||||
--hash=sha256:75af0b4c229ac519b155028fa1be632d812a519abba9b46b20e50c6caa184f19 \
|
||||
--hash=sha256:7b5dd7cbae20285cdb597b10eb5a2c13aa9de6cde9bb64a3c1317427b1db1ae1 \
|
||||
--hash=sha256:7d6daa89a00b58c37cb1747ec9fb7ac3bc5ffd5949f5888657dfddde6d1312e0 \
|
||||
--hash=sha256:800429ac32c9b72909c671aaf17ecd13110f823ddb7db4dfef412a5587c2c24e \
|
||||
--hash=sha256:806f3987ffe10e867bab0ddad45df1148a2b98221798457fa097ad85d6e8bc75 \
|
||||
--hash=sha256:808b99604f7873c800c4840f55ff389936ef1948e4e87645eaf3fccbc8477ac4 \
|
||||
--hash=sha256:80941e6d573197a0c28f394753de529bb436b1ca990ed6e765cf42426abc39f8 \
|
||||
--hash=sha256:84cabc7095dd535ca934d57e9ce2a72ffd216e435a84acb06b2277b1de2689bd \
|
||||
--hash=sha256:8637e29d13f478bc4f153d8daa9ffb16455f0a6cb287da1b432fdad2bfbd66c7 \
|
||||
--hash=sha256:896866d2d436563fa2a43a9d72f417874f16b5545955c54a64941e87c1376c61 \
|
||||
--hash=sha256:8e178e3e99d3c0ea8fc64b88447f7cac8ccf058af422a6cedc690d0eadd98c51 \
|
||||
--hash=sha256:907bfa8a9cb790748a9aa4513e37c88c59660da3bcfffbd24a7d9e6abf224551 \
|
||||
--hash=sha256:9212d6b86917a2300669511ed094a9406888362e085f2431a7da985a6b124f45 \
|
||||
--hash=sha256:92a7fe4225365c5e3a8e598982269c6d6698d3e783b3b1ae979e7819f9cd55c1 \
|
||||
--hash=sha256:935b9d1aed48fcfb3f838caac506f38e29621b44ccc4f8a64d575cb1b2a88644 \
|
||||
--hash=sha256:97e9993d5ed946aba26baf9c1e8cf18adbab584b99f452ee72f7ee8acb882796 \
|
||||
--hash=sha256:983976c2ab753166dc66d36af6e8ec15bb511e4a25856e2227e5f7e00a160587 \
|
||||
--hash=sha256:9f5fefaca968e700ad1a4a9de98bf0869a94e397fe3524c4c9450c1445252304 \
|
||||
--hash=sha256:a332ac4ccb84b6dde65dbace8431f3af08874bf9770719d32a635c4ef411b18b \
|
||||
--hash=sha256:a40905599d8079e09f25027423aed94f2823adaf2868940de991e53a449e14a8 \
|
||||
--hash=sha256:a6dfc2af5b082b635af6e08e0d1f9f1c4e04d17d4e2ca0ef96131e85eda6eb17 \
|
||||
--hash=sha256:a786bf667724d84aa29b5db1c61b7bfdde380202aaca12c3461afd6b71743171 \
|
||||
--hash=sha256:a83e0850cb8f5ac975291ebfc4170ba481f41a28065277f7f735c202cd8e0af3 \
|
||||
--hash=sha256:aa0c9cc0b82b14766a99fbe6084409972266e82f459821cd26997a488a7261a7 \
|
||||
--hash=sha256:b17fbdbe01c196e7e159aacb889e091f28e61020a8abeac07b68079b6e626988 \
|
||||
--hash=sha256:b63e13dd27da389ed9475b3d28510f0f954bca0041e8e551b2a4eb1eab56a39a \
|
||||
--hash=sha256:b6e53e82ec2db0717eabb276aa56cf4e500c9a7cec2c2e189b55c24f65a3e8c0 \
|
||||
--hash=sha256:bb0984b30e973f7e2884362b7d23d0a348c7143ee559f38ef3eaab640144204c \
|
||||
--hash=sha256:bc11908616c8a283cf7d664f77411a5ed2a02009b0097ff8abbba5e79128ccf2 \
|
||||
--hash=sha256:bdec5e43377761c5dbca620efb69a77f6855c5a379e32ac5b158f54c84212b14 \
|
||||
--hash=sha256:bef9768cab184e7ae6e559c032e95ba8d07b3023c289f79a2bd36e8bf85605a5 \
|
||||
--hash=sha256:c990547452ee2800d8506c4150280757f88532f3de2a58e3022e9b179107862a \
|
||||
--hash=sha256:ca94b6aac0d7af2a10ba08c0f888b3d5114439b6b3ef39968378723622fed377 \
|
||||
--hash=sha256:cad302dc10fac357d3467a74a9561c90609768a6f73a1923b0fd851b6486f8b0 \
|
||||
--hash=sha256:d0a7735df32ccbcc98b98a1ac785cc4b19b580be1bdf0aeb5c03223220ea09d5 \
|
||||
--hash=sha256:d70347c8a5b7ccd803ec0c85c8709f036e6348f1e6a5bf048ecd9c64d3550b8b \
|
||||
--hash=sha256:d70534cea9e7966169ad29a903b99fc507e932069a881d0965a1a84bb57f6c6d \
|
||||
--hash=sha256:db44d5c160a90df2d24a24760bbd37607d53da0b34fb546c4c232af7192298ac \
|
||||
--hash=sha256:e115c15e3bc727b1ca3e641a909f77f8ca72a64fff150f666fcc85e57701c26c \
|
||||
--hash=sha256:e2479c7f02f9d505682dc47df8c0ea1fc5e264c4d1629a5d63fe3e2334b89554 \
|
||||
--hash=sha256:e5dcbe95016e88437ecf33544ba5db21ef1b8dd6e1b434a2cb2a3d605299e643 \
|
||||
--hash=sha256:e6bdb408f7c9dd2a5ff2b14a3b0bb6d4deb29fb9961e6eb3ae2031ae9a5cec13 \
|
||||
--hash=sha256:e75d3dba8fc1ddfec0cd752108f93b83b4f8d6ab40e524a95d35f016b9683b09 \
|
||||
--hash=sha256:efdc140e7b63b8f739d09a99033aa430accce485ff78e6d311973a67b6bf3208 \
|
||||
--hash=sha256:f10c98f49227ed8383d28174ee95155a675c4ed7f85e2e573b04414f7e371bda \
|
||||
--hash=sha256:f188028b5af6b8fb2e9a76ac0f841a575bd1bd396e46ef0840d9b88a48fdbcea \
|
||||
--hash=sha256:f188d580bd870cda1e15183790d1cc2fa78f666e76077d103edf048eed9c356e \
|
||||
--hash=sha256:f45bd71d1fa5e5749587613037b172e0b3b23159d1c00ef2fc920da6f470e6f0 \
|
||||
--hash=sha256:f61333d817698bdcdd0f9d7793e365ac3d2a21c1f1eb02b32ad6aefb8d8ea831 \
|
||||
--hash=sha256:fb125d860738a09d363a88daa0f59c4533529a90e564785e20fe875b200b6dbd
|
||||
# via
|
||||
# -r .github/scripts/requirements_dev.in
|
||||
# pdf2image
|
||||
# weasyprint
|
||||
platformdirs==4.5.0 \
|
||||
--hash=sha256:70ddccdd7c99fc5942e9fc25636a8b34d04c24b335100223152c2803e4063312 \
|
||||
--hash=sha256:e578a81bb873cbb89a41fcc904c7ef523cc18284b7e3b3ccf06aca1403b7ebd3
|
||||
platformdirs==4.5.1 \
|
||||
--hash=sha256:61d5cdcc6065745cdd94f0f878977f8de9437be93de97c1c12f853c9c0cdcbda \
|
||||
--hash=sha256:d03afa3963c806a9bed9d5125c8f4cb2fdaf74a55ab60e5d59b3fde758104d31
|
||||
# via virtualenv
|
||||
pre-commit==4.3.0 \
|
||||
--hash=sha256:2b0747ad7e6e967169136edffee14c16e148a778a54e4f967921aa1ebf2308d8 \
|
||||
--hash=sha256:499fe450cc9d42e9d58e606262795ecb64dd05438943c62b66f6a8673da30b16
|
||||
pre-commit==4.5.1 \
|
||||
--hash=sha256:3b3afd891e97337708c1674210f8eba659b52a38ea5f822ff142d10786221f77 \
|
||||
--hash=sha256:eb545fcff725875197837263e977ea257a402056661f09dae08e4b149b030a61
|
||||
# via -r .github/scripts/requirements_dev.in
|
||||
pycparser==2.23 \
|
||||
--hash=sha256:78816d4f24add8f10a06d6f05b4d424ad9e96cfebf68a4ddc99c65c0720d00c2 \
|
||||
--hash=sha256:e5c6e8d3fbad53479cab09ac03729e0a9faf2bee3db8208a550daf5af81a5934
|
||||
pycparser==3.0 \
|
||||
--hash=sha256:600f49d217304a5902ac3c37e1281c9fe94e4d0489de643a9504c5cdfdfc6b29 \
|
||||
--hash=sha256:b727414169a36b7d524c1c3e31839a521725078d7b2ff038656844266160a992
|
||||
# via cffi
|
||||
pydyf==0.11.0 \
|
||||
--hash=sha256:0aaf9e2ebbe786ec7a78ec3fbffa4cdcecde53fd6f563221d53c6bc1328848a3 \
|
||||
--hash=sha256:394dddf619cca9d0c55715e3c55ea121a9bf9cbc780cdc1201a2427917b86b64
|
||||
pydyf==0.12.1 \
|
||||
--hash=sha256:ea25b4e1fe7911195cb57067560daaa266639184e8335365cc3ee5214e7eaadc \
|
||||
--hash=sha256:fbd7e759541ac725c29c506612003de393249b94310ea78ae44cb1d04b220095
|
||||
# via weasyprint
|
||||
pyphen==0.17.2 \
|
||||
--hash=sha256:3a07fb017cb2341e1d9ff31b8634efb1ae4dc4b130468c7c39dd3d32e7c3affd \
|
||||
@@ -442,9 +452,9 @@ pyyaml==6.0.3 \
|
||||
--hash=sha256:fa160448684b4e94d80416c0fa4aac48967a969efe22931448d853ada8baf926 \
|
||||
--hash=sha256:fc09d0aa354569bc501d4e787133afc08552722d3ab34836a80547331bb5d4a0
|
||||
# via pre-commit
|
||||
tinycss2==1.4.0 \
|
||||
--hash=sha256:10c0972f6fc0fbee87c3edb76549357415e94548c1ae10ebccdea16fb404a9b7 \
|
||||
--hash=sha256:3a49cf47b7675da0b15d0c6e1df8df4ebd96e9394bb905a5775adb0d884c5289
|
||||
tinycss2==1.5.1 \
|
||||
--hash=sha256:3415ba0f5839c062696996998176c4a3751d18b7edaaeeb658c9ce21ec150661 \
|
||||
--hash=sha256:d339d2b616ba90ccce58da8495a78f46e55d4d25f9fd71dfd526f07e7d53f957
|
||||
# via
|
||||
# cssselect2
|
||||
# weasyprint
|
||||
@@ -452,17 +462,17 @@ tinyhtml5==2.0.0 \
|
||||
--hash=sha256:086f998833da24c300c414d9fe81d9b368fd04cb9d2596a008421cbc705fcfcc \
|
||||
--hash=sha256:13683277c5b176d070f82d099d977194b7a1e26815b016114f581a74bbfbf47e
|
||||
# via weasyprint
|
||||
unoserver==3.4 \
|
||||
--hash=sha256:3dcf2204013def1d1ddd3671f38b11346bdf349fef9728277462666a8a634419 \
|
||||
--hash=sha256:64c24d33d4f65d680a2d9f676518cb28e7fd6c1f9d9a745c33e4a4cb59afdfcd
|
||||
unoserver==3.6 \
|
||||
--hash=sha256:25c360fa194396a89cb79b4edd2735f8e4f0fd8531e59db3952114585bd7df05 \
|
||||
--hash=sha256:e446bcb3638c51880f002aaeecab1cf74dfa9df81035f027f7ff2e081b6d7015
|
||||
# via -r .github/scripts/requirements_dev.in
|
||||
virtualenv==20.35.4 \
|
||||
--hash=sha256:643d3914d73d3eeb0c552cbb12d7e82adf0e504dbf86a3182f8771a153a1971c \
|
||||
--hash=sha256:c21c9cede36c9753eeade68ba7d523529f228a403463376cf821eaae2b650f1b
|
||||
virtualenv==20.36.1 \
|
||||
--hash=sha256:575a8d6b124ef88f6f51d56d656132389f961062a9177016a50e4f507bbcc19f \
|
||||
--hash=sha256:8befb5c81842c641f8ee658481e42641c68b5eab3521d8e092d18320902466ba
|
||||
# via pre-commit
|
||||
weasyprint==66.0 \
|
||||
--hash=sha256:82b0783b726fcd318e2c977dcdddca76515b30044bc7a830cc4fbe717582a6d0 \
|
||||
--hash=sha256:da71dc87dc129ac9cffdc65e5477e90365ab9dbae45c744014ec1d06303dde40
|
||||
weasyprint==68.0 \
|
||||
--hash=sha256:447f40898b747cb44ac31a5d493d512e7441fd56e13f63744c099383bbf9cda9 \
|
||||
--hash=sha256:c2cb40c71b50837c5971f00171c9e4078e8c9912dd7c217f3e90e068f11e8aa1
|
||||
# via -r .github/scripts/requirements_dev.in
|
||||
webencodings==0.5.1 \
|
||||
--hash=sha256:a0af1213f3c2226497a97e2b3aa01a7e4bee4f403f95be16fc9acd2947514a78 \
|
||||
@@ -471,86 +481,27 @@ webencodings==0.5.1 \
|
||||
# cssselect2
|
||||
# tinycss2
|
||||
# tinyhtml5
|
||||
zopfli==0.2.3.post1 \
|
||||
--hash=sha256:0aa5f90d6298bda02a95bc8dc8c3c19004d5a4e44bda00b67ca7431d857b4b54 \
|
||||
--hash=sha256:0cc20b02a9531559945324c38302fd4ba763311632d0ec8a1a0aa9c10ea363e6 \
|
||||
--hash=sha256:1d8cc06605519e82b16df090e17cb3990d1158861b2872c3117f1168777b81e4 \
|
||||
--hash=sha256:1f990634fd5c5c8ced8edddd8bd45fab565123b4194d6841e01811292650acae \
|
||||
--hash=sha256:2345e713260a350bea0b01a816a469ea356bc2d63d009a0d777691ecbbcf7493 \
|
||||
--hash=sha256:2768c877f76c8a0e7519b1c86c93757f3c01492ddde55751e9988afb7eff64e1 \
|
||||
--hash=sha256:29ea74e72ffa6e291b8c6f2504ce6c146b4fe990c724c1450eb8e4c27fd31431 \
|
||||
--hash=sha256:34a99592f3d9eb6f737616b5bd74b48a589fdb3cb59a01a50d636ea81d6af272 \
|
||||
--hash=sha256:3654bfc927bc478b1c3f3ff5056ed7b20a1a37fa108ca503256d0a699c03bbb1 \
|
||||
--hash=sha256:3657e416ffb8f31d9d3424af12122bb251befae109f2e271d87d825c92fc5b7b \
|
||||
--hash=sha256:37d011e92f7b9622742c905fdbed9920a1d0361df84142807ea2a528419dea7f \
|
||||
--hash=sha256:3827170de28faf144992d3d4dcf8f3998fe3c8a6a6f4a08f1d42c2ec6119d2bb \
|
||||
--hash=sha256:39e576f93576c5c223b41d9c780bbb91fd6db4babf3223d2a4fe7bf568e2b5a8 \
|
||||
--hash=sha256:3a89277ed5f8c0fb2d0b46d669aa0633123aa7381f1f6118c12f15e0fb48f8ca \
|
||||
--hash=sha256:3c163911f8bad94b3e1db0a572e7c28ba681a0c91d0002ea1e4fa9264c21ef17 \
|
||||
--hash=sha256:3f0197b6aa6eb3086ae9e66d6dd86c4d502b6c68b0ec490496348ae8c05ecaef \
|
||||
--hash=sha256:48dba9251060289101343110ab47c0756f66f809bb4d1ddbb6d5c7e7752115c5 \
|
||||
--hash=sha256:4915a41375bdee4db749ecd07d985a0486eb688a6619f713b7bf6fbfd145e960 \
|
||||
--hash=sha256:4c1226a7e2c7105ac31503a9bb97454743f55d88164d6d46bc138051b77f609b \
|
||||
--hash=sha256:4e50ffac74842c1c1018b9b73875a0d0a877c066ab06bf7cccbaa84af97e754f \
|
||||
--hash=sha256:518f1f4ed35dd69ce06b552f84e6d081f07c552b4c661c5312d950a0b764a58a \
|
||||
--hash=sha256:5aad740b4d4fcbaaae4887823925166ffd062db3b248b3f432198fc287381d1a \
|
||||
--hash=sha256:5f272186e03ad55e7af09ab78055535c201b1a0bcc2944edb1768298d9c483a4 \
|
||||
--hash=sha256:5fcfc0dc2761e4fcc15ad5d273b4d58c2e8e059d3214a7390d4d3c8e2aee644e \
|
||||
--hash=sha256:60db20f06c3d4c5934b16cfa62a2cc5c3f0686bffe0071ed7804d3c31ab1a04e \
|
||||
--hash=sha256:615a8ac9dda265e9cc38b2a76c3142e4a9f30fea4a79c85f670850783bc6feb4 \
|
||||
--hash=sha256:6482db9876c68faac2d20a96b566ffbf65ddaadd97b222e4e73641f4f8722fc4 \
|
||||
--hash=sha256:6617fb10f9e4393b331941861d73afb119cd847e88e4974bdbe8068ceef3f73f \
|
||||
--hash=sha256:676919fba7311125244eb0c4393679ac5fe856e5864a15d122bd815205369fa0 \
|
||||
--hash=sha256:6c2d2bc8129707e34c51f9352c4636ca313b52350bbb7e04637c46c1818a2a70 \
|
||||
--hash=sha256:71390dbd3fbf6ebea9a5d85ffed8c26ee1453ee09248e9b88486e30e0397b775 \
|
||||
--hash=sha256:716cdbfc57bfd3d3e31a58e6246e8190e6849b7dbb7c4ce39ef8bbf0edb8f6d5 \
|
||||
--hash=sha256:75a26a2307b10745a83b660c404416e984ee6fca515ec7f0765f69af3ce08072 \
|
||||
--hash=sha256:7be5cc6732eb7b4df17305d8a7b293223f934a31783a874a01164703bc1be6cd \
|
||||
--hash=sha256:7cce242b5df12b2b172489daf19c32e5577dd2fac659eb4b17f6a6efb446fd5c \
|
||||
--hash=sha256:81c341d9bb87a6dbbb0d45d6e272aca80c7c97b4b210f9b6e233bf8b87242f29 \
|
||||
--hash=sha256:89899641d4de97dbad8e0cde690040d078b6aea04066dacaab98e0b5a23573f2 \
|
||||
--hash=sha256:8d5ab297d660b75c159190ce6d73035502310e40fd35170aed7d1a1aea7ddd65 \
|
||||
--hash=sha256:8fbe5bcf10d01aab3513550f284c09fef32f342b36f56bfae2120a9c4d12c130 \
|
||||
--hash=sha256:91a2327a4d7e77471fa4fbb26991c6de4a738c6fc6a33e09bb25f56a870a4b7b \
|
||||
--hash=sha256:95a260cafd56b8fffa679918937401c80bb38e1681c448b988022e4c3610965d \
|
||||
--hash=sha256:96484dc0f48be1c5d7ae9f38ed1ce41e3675fd506b27c11a6607f14b49101e99 \
|
||||
--hash=sha256:9a6aec38a989bad7ddd1ef53f1265699e49e294d08231b5313d61293f3cd6237 \
|
||||
--hash=sha256:9ba214f4f45bec195ee8559651154d3ac2932470b9d91c5715fc29c013349f8c \
|
||||
--hash=sha256:9f4a7ec2770e6af05f5a02733fd3900f30a9cd58e5d6d3727e14c5bcd6e7d587 \
|
||||
--hash=sha256:a1cf720896d2ce998bc8e051d4b4ce0d8bec007aab6243102e8e1d22a0b2fb3f \
|
||||
--hash=sha256:a241a68581d34d67b40c425cce3d1fd211c092f99d9250947824ccba9f491949 \
|
||||
--hash=sha256:a53b18797cdef27e019db595d66c4b077325afe2fd62145953275f53d84ce40c \
|
||||
--hash=sha256:a82fc2dbebe6eb908b9c665e71496f8525c1bc4d2e3a7a7722ef2b128b6227c8 \
|
||||
--hash=sha256:a86eb88e06bd87e1fff31dac878965c26b0c26db59ddcf78bb0379a954b120de \
|
||||
--hash=sha256:aa588b21044f8a74e423d8c8a4c7fc9988501878aacced793467010039c50734 \
|
||||
--hash=sha256:b05296e8bc88c92e2b21e0a9bae4740c1551ee613c1d93a51fd28a7a0b2b6fbb \
|
||||
--hash=sha256:b0ec13f352ea5ae0fc91f98a48540512eed0767d0ec4f7f3cb92d92797983d18 \
|
||||
--hash=sha256:b3df42f52502438ee973042cc551877d24619fa1cd38ef7b7e9ac74200daca8b \
|
||||
--hash=sha256:b78008a69300d929ca2efeffec951b64a312e9a811e265ea4a907ab546d79fa6 \
|
||||
--hash=sha256:b9026a21b6d41eb0e2e63f5bc1242c3fcc43ecb770963cda99a4307863dac12e \
|
||||
--hash=sha256:bbe429fc50686bb2a2608a30843e36fbaa123462a5284f136c7d9e0145220bfd \
|
||||
--hash=sha256:bfa1eb759e07d8b7aa7a310a2bc535e127ee70addf90dc8d4b946b593c3e51a8 \
|
||||
--hash=sha256:c1e0ed5d84ffa2d677cc9582fc01e61dab2e7ef8b8996e055f0a76167b1b94df \
|
||||
--hash=sha256:c4278d1873ce6e803e5d4f8d702fd3026bd67fca744aa98881324d1157ddf748 \
|
||||
--hash=sha256:cac2b37ab21c2b36a10b685b1893ebd6b0f83ae26004838ac817680881576567 \
|
||||
--hash=sha256:cbe6df25807227519debd1a57ab236f5f6bad441500e85b13903e51f93a43214 \
|
||||
--hash=sha256:cd2c002f160502608dcc822ed2441a0f4509c52e86fcfd1a09e937278ed1ca14 \
|
||||
--hash=sha256:e0137dd64a493ba6a4be37405cfd6febe650a98cc1e9dca8f6b8c63b1db11b41 \
|
||||
--hash=sha256:e63d558847166543c2c9789e6f985400a520b7eacc4b99181668b2c3aeadd352 \
|
||||
--hash=sha256:eb45a34f23da4f8bc712b6376ca5396914b0b7c09adbb001dad964eb7f3132f8 \
|
||||
--hash=sha256:ecb7572df5372abce8073df078207d9d1749f20b8b136089916a4a0868d56051 \
|
||||
--hash=sha256:f12000a6accdd4bf0a3fa6eaa1b1c7a7bc80af0a2edf3f89d770d3dcce1d0e22 \
|
||||
--hash=sha256:f7d69c1a7168ad0e9cb864e8663acb232986a0c9c9cb9801f56bf6214f53a54d \
|
||||
--hash=sha256:f815fcc2b2a457977724bad97fb4854022980f51ce7b136925e336b530545ae1 \
|
||||
--hash=sha256:fc39f5c27f962ec8660d8d20c24762431131b5d8c672b44b0a54cf2b5bcde9b9
|
||||
zopfli==0.4.0 \
|
||||
--hash=sha256:03181d48e719fcb6cf8340189c61e8f9883d8bbbdf76bf5212a74457f7d083c1 \
|
||||
--hash=sha256:18b5f1570f64d4988482e4466f10ef5f2a30f687c19ad62a64560f2152dc89eb \
|
||||
--hash=sha256:25e4863b8dc30e5d5309f87c106b0b7d3da4ed0e340b8a52b36d4471e797589f \
|
||||
--hash=sha256:7d66337be6d5613dec55213e9ac28f378c41e2cc04fbad4a10748e4df774ca85 \
|
||||
--hash=sha256:9097e8e1dfdb7f5aea5464e469946857e80502b6d29ba1b232450916bd4a74d1 \
|
||||
--hash=sha256:a8ee992b2549e090cd3f0178bf606dd41a29e0613a04cdf5054224662c72dce6 \
|
||||
--hash=sha256:b72a010d205d00b2855acc2302772067362f9ab5a012e3550662aec60d28e6b3 \
|
||||
--hash=sha256:b8bdb41fbfdc4738b7bdc09ed7c1e951579fae192391a5e694d59bb186cdbec7 \
|
||||
--hash=sha256:c3ba02a9a6ca90481d2b2f68bab038b310d63a1e3b5ae305e95a6599787ed941 \
|
||||
--hash=sha256:d1b98ad47c434ef213444a03ef2f826eeec100144d64f6a57504b9893d3931ce \
|
||||
--hash=sha256:f67d04280065e24cb9a4174cb6b3d1f763687f8cb2963aa135ad8f57c6995f5a \
|
||||
--hash=sha256:f94e4dd7d76b4fe9f5d9229372be20d7f786164eea5152d1af1c34298c3d5975
|
||||
# via fonttools
|
||||
|
||||
# The following packages are considered to be unsafe in a requirements file:
|
||||
pip==25.3 \
|
||||
--hash=sha256:8d0538dbbd7babbd207f261ed969c65de439f6bc9e5dbd3b3b9a77f25d95f343 \
|
||||
--hash=sha256:9655943313a94722b7774661c21049070f6bbb0a1516bf02f7c8d5d9201514cd
|
||||
pip==26.0 \
|
||||
--hash=sha256:3ce220a0a17915972fbf1ab451baae1521c4539e778b28127efa79b974aff0fa \
|
||||
--hash=sha256:98436feffb9e31bc9339cf369fd55d3331b1580b6a6f1173bacacddcf9c34754
|
||||
# via -r .github/scripts/requirements_dev.in
|
||||
setuptools==80.9.0 \
|
||||
--hash=sha256:062d34222ad13e0cc312a4c02d73f059e86a4acbfbdea8f8f76b28c99f306922 \
|
||||
--hash=sha256:f36b47402ecde768dbfafc46e8e4207b4360c654f1f3bb84475f0a28628fb19c
|
||||
setuptools==80.10.2 \
|
||||
--hash=sha256:8b0e9d10c784bf7d262c4e5ec5d4ec94127ce206e8738f29a437945fbc219b70 \
|
||||
--hash=sha256:95b30ddfb717250edb492926c92b5221f7ef3fbcc2b07579bcd4a27da21d0173
|
||||
# via -r .github/scripts/requirements_dev.in
|
||||
|
||||
@@ -12,25 +12,25 @@ distlib==0.4.0 \
|
||||
--hash=sha256:9659f7d87e46584a30b5780e43ac7a2143098441670ff0a49d5f9034c54a6c16 \
|
||||
--hash=sha256:feec40075be03a04501a973d81f633735b4b69f98b05450592310c0f401a4e0d
|
||||
# via virtualenv
|
||||
filelock==3.20.0 \
|
||||
--hash=sha256:339b4732ffda5cd79b13f4e2711a31b0365ce445d95d243bb996273d072546a2 \
|
||||
--hash=sha256:711e943b4ec6be42e1d4e6690b48dc175c822967466bb31c0c293f34334c13f4
|
||||
filelock==3.20.3 \
|
||||
--hash=sha256:18c57ee915c7ec61cff0ecf7f0f869936c7c30191bb0cf406f1341778d0834e1 \
|
||||
--hash=sha256:4b0dda527ee31078689fc205ec4f1c1bf7d56cf88b6dc9426c4f230e46c2dce1
|
||||
# via virtualenv
|
||||
identify==2.6.15 \
|
||||
--hash=sha256:1181ef7608e00704db228516541eb83a88a9f94433a8c80bb9b5bd54b1d81757 \
|
||||
--hash=sha256:e4f4864b96c6557ef2a1e1c951771838f4edc9df3a72ec7118b338801b11c7bf
|
||||
identify==2.6.16 \
|
||||
--hash=sha256:391ee4d77741d994189522896270b787aed8670389bfd60f326d677d64a6dfb0 \
|
||||
--hash=sha256:846857203b5511bbe94d5a352a48ef2359532bc8f6727b5544077a0dcfb24980
|
||||
# via pre-commit
|
||||
nodeenv==1.9.1 \
|
||||
--hash=sha256:6ec12890a2dab7946721edbfbcd91f3319c6ccc9aec47be7c7e6b7011ee6645f \
|
||||
--hash=sha256:ba11c9782d29c27c70ffbdda2d7415098754709be8a7056d79a737cd901155c9
|
||||
nodeenv==1.10.0 \
|
||||
--hash=sha256:5bb13e3eed2923615535339b3c620e76779af4cb4c6a90deccc9e36b274d3827 \
|
||||
--hash=sha256:996c191ad80897d076bdfba80a41994c2b47c68e224c542b48feba42ba00f8bb
|
||||
# via pre-commit
|
||||
platformdirs==4.5.0 \
|
||||
--hash=sha256:70ddccdd7c99fc5942e9fc25636a8b34d04c24b335100223152c2803e4063312 \
|
||||
--hash=sha256:e578a81bb873cbb89a41fcc904c7ef523cc18284b7e3b3ccf06aca1403b7ebd3
|
||||
platformdirs==4.5.1 \
|
||||
--hash=sha256:61d5cdcc6065745cdd94f0f878977f8de9437be93de97c1c12f853c9c0cdcbda \
|
||||
--hash=sha256:d03afa3963c806a9bed9d5125c8f4cb2fdaf74a55ab60e5d59b3fde758104d31
|
||||
# via virtualenv
|
||||
pre-commit==4.5.0 \
|
||||
--hash=sha256:25e2ce09595174d9c97860a95609f9f852c0614ba602de3561e267547f2335e1 \
|
||||
--hash=sha256:dc5a065e932b19fc1d4c653c6939068fe54325af8e741e74e88db4d28a4dd66b
|
||||
pre-commit==4.5.1 \
|
||||
--hash=sha256:3b3afd891e97337708c1674210f8eba659b52a38ea5f822ff142d10786221f77 \
|
||||
--hash=sha256:eb545fcff725875197837263e977ea257a402056661f09dae08e4b149b030a61
|
||||
# via -r .github/scripts/requirements_pre_commit.in
|
||||
pyyaml==6.0.3 \
|
||||
--hash=sha256:00c4bdeba853cc34e7dd471f16b4114f4162dc03e6b7afcc2128711f0eca823c \
|
||||
@@ -107,7 +107,7 @@ pyyaml==6.0.3 \
|
||||
--hash=sha256:fa160448684b4e94d80416c0fa4aac48967a969efe22931448d853ada8baf926 \
|
||||
--hash=sha256:fc09d0aa354569bc501d4e787133afc08552722d3ab34836a80547331bb5d4a0
|
||||
# via pre-commit
|
||||
virtualenv==20.35.4 \
|
||||
--hash=sha256:643d3914d73d3eeb0c552cbb12d7e82adf0e504dbf86a3182f8771a153a1971c \
|
||||
--hash=sha256:c21c9cede36c9753eeade68ba7d523529f228a403463376cf821eaae2b650f1b
|
||||
virtualenv==20.36.1 \
|
||||
--hash=sha256:575a8d6b124ef88f6f51d56d656132389f961062a9177016a50e4f507bbcc19f \
|
||||
--hash=sha256:8befb5c81842c641f8ee658481e42641c68b5eab3521d8e092d18320902466ba
|
||||
# via pre-commit
|
||||
|
||||
@@ -8,7 +8,7 @@ tomli-w==1.2.0 \
|
||||
--hash=sha256:188306098d013b691fcadc011abd66727d3c414c571bb01b1a174ba8c983cf90 \
|
||||
--hash=sha256:2dd14fac5a47c27be9cd4c976af5a12d87fb1f0b4512f81d69cce3b35ae25021
|
||||
# via -r .github/scripts/requirements_sync_readme.in
|
||||
tomlkit==0.13.3 \
|
||||
--hash=sha256:430cf247ee57df2b94ee3fbe588e71d362a941ebb545dec29b53961d61add2a1 \
|
||||
--hash=sha256:c89c649d79ee40629a9fda55f8ace8c6a1b42deb912b2a8fd8d942ddadb606b0
|
||||
tomlkit==0.14.0 \
|
||||
--hash=sha256:592064ed85b40fa213469f81ac584f67a4f2992509a7c3ea2d632208623a3680 \
|
||||
--hash=sha256:cf00efca415dbd57575befb1f6634c4f42d2d87dbba376128adb42c121b87064
|
||||
# via -r .github/scripts/requirements_sync_readme.in
|
||||
|
||||
@@ -130,7 +130,7 @@ jobs:
|
||||
|
||||
- name: Setup Node.js
|
||||
if: matrix.variant.build_frontend == true
|
||||
uses: actions/setup-node@v4
|
||||
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
|
||||
with:
|
||||
node-version: 22
|
||||
cache: "npm"
|
||||
@@ -185,14 +185,14 @@ jobs:
|
||||
sudo apt-get install -y libgtk-3-dev libwebkit2gtk-4.0-dev libwebkit2gtk-4.1-dev libappindicator3-dev librsvg2-dev patchelf libjavascriptcoregtk-4.0-dev libsoup2.4-dev libjavascriptcoregtk-4.1-dev libsoup-3.0-dev
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v4
|
||||
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
|
||||
with:
|
||||
node-version: 22
|
||||
cache: "npm"
|
||||
cache-dependency-path: frontend/package-lock.json
|
||||
|
||||
- name: Setup Rust
|
||||
uses: dtolnay/rust-toolchain@stable
|
||||
uses: dtolnay/rust-toolchain@4be9e76fd7c4901c61fb841f559994984270fce7 # stable
|
||||
with:
|
||||
toolchain: stable
|
||||
targets: ${{ (matrix.platform == 'macos-15' || matrix.platform == 'macos-15-intel') && 'aarch64-apple-darwin,x86_64-apple-darwin' || '' }}
|
||||
@@ -291,7 +291,7 @@ jobs:
|
||||
- name: Setup DigiCert KeyLocker
|
||||
id: digicert-setup
|
||||
if: ${{ matrix.platform == 'windows-latest' && env.SM_API_KEY != '' && (github.event_name == 'release' || github.ref == 'refs/heads/V2-master') }}
|
||||
uses: digicert/ssm-code-signing@v1.1.0
|
||||
uses: digicert/ssm-code-signing@9476ceec3ea1c63298d4403b983e1ccf2556ff4c # v1.1.0
|
||||
env:
|
||||
SM_API_KEY: ${{ secrets.SM_API_KEY }}
|
||||
SM_CLIENT_CERT_FILE_B64: ${{ secrets.SM_CLIENT_CERT_FILE_B64 }}
|
||||
@@ -399,7 +399,7 @@ jobs:
|
||||
echo "Certificate imported successfully."
|
||||
|
||||
- name: Build Tauri app
|
||||
uses: tauri-apps/tauri-action@v0
|
||||
uses: tauri-apps/tauri-action@51a9f1156b33df106d827c3a78f8f894946c5faa # v0.5.25
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
APPLE_CERTIFICATE: ${{ secrets.APPLE_CERTIFICATE }}
|
||||
|
||||
@@ -33,6 +33,11 @@ jobs:
|
||||
outputs:
|
||||
matrix: ${{ steps.set-matrix.outputs.matrix }}
|
||||
steps:
|
||||
- name: Harden the runner (Audit all outbound calls)
|
||||
uses: step-security/harden-runner@20cf305ff2072d973412fa9b1e3a4f227bda3c76 # v2.14.0
|
||||
with:
|
||||
egress-policy: audit
|
||||
|
||||
- name: Determine build matrix
|
||||
id: set-matrix
|
||||
run: |
|
||||
@@ -81,14 +86,14 @@ jobs:
|
||||
sudo apt-get install -y libgtk-3-dev libwebkit2gtk-4.0-dev libwebkit2gtk-4.1-dev libappindicator3-dev librsvg2-dev patchelf libjavascriptcoregtk-4.0-dev libsoup2.4-dev libjavascriptcoregtk-4.1-dev libsoup-3.0-dev
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v4
|
||||
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
|
||||
with:
|
||||
node-version: 22
|
||||
cache: "npm"
|
||||
cache-dependency-path: frontend/package-lock.json
|
||||
|
||||
- name: Setup Rust
|
||||
uses: dtolnay/rust-toolchain@stable
|
||||
uses: dtolnay/rust-toolchain@4be9e76fd7c4901c61fb841f559994984270fce7 # stable
|
||||
with:
|
||||
toolchain: stable
|
||||
targets: ${{ (matrix.platform == 'macos-15' || matrix.platform == 'macos-15-intel') && 'aarch64-apple-darwin,x86_64-apple-darwin' || '' }}
|
||||
@@ -188,7 +193,7 @@ jobs:
|
||||
- name: Setup DigiCert KeyLocker
|
||||
id: digicert-setup
|
||||
if: ${{ matrix.platform == 'windows-latest' && env.SM_API_KEY != '' && github.ref == 'refs/heads/main' }}
|
||||
uses: digicert/ssm-code-signing@v1.1.0
|
||||
uses: digicert/ssm-code-signing@9476ceec3ea1c63298d4403b983e1ccf2556ff4c # v1.1.0
|
||||
env:
|
||||
SM_API_KEY: ${{ secrets.SM_API_KEY }}
|
||||
SM_CLIENT_CERT_FILE_B64: ${{ secrets.SM_CLIENT_CERT_FILE_B64 }}
|
||||
@@ -307,7 +312,7 @@ jobs:
|
||||
ls -la /usr/bin/hd* || echo "No hd* tools found"
|
||||
|
||||
- name: Build Tauri app
|
||||
uses: tauri-apps/tauri-action@v0
|
||||
uses: tauri-apps/tauri-action@51a9f1156b33df106d827c3a78f8f894946c5faa # v0.5.25
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
APPLE_CERTIFICATE: ${{ secrets.APPLE_CERTIFICATE }}
|
||||
@@ -639,6 +644,11 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
if: always()
|
||||
steps:
|
||||
- name: Harden the runner (Audit all outbound calls)
|
||||
uses: step-security/harden-runner@20cf305ff2072d973412fa9b1e3a4f227bda3c76 # v2.14.0
|
||||
with:
|
||||
egress-policy: audit
|
||||
|
||||
- name: Report build results
|
||||
run: |
|
||||
if [ "${{ needs.build.result }}" = "success" ]; then
|
||||
|
||||
@@ -128,6 +128,11 @@ jobs:
|
||||
outputs:
|
||||
frontend: ${{ steps.changes.outputs.frontend }}
|
||||
steps:
|
||||
- name: Harden the runner (Audit all outbound calls)
|
||||
uses: step-security/harden-runner@20cf305ff2072d973412fa9b1e3a4f227bda3c76 # v2.14.0
|
||||
with:
|
||||
egress-policy: audit
|
||||
|
||||
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
|
||||
|
||||
- name: Check for file changes
|
||||
|
||||
@@ -303,22 +303,23 @@ public class EndpointConfiguration {
|
||||
// Adding endpoints to "PageOps" group
|
||||
addEndpointToGroup("PageOps", "remove-pages");
|
||||
addEndpointToGroup("PageOps", "merge-pdfs");
|
||||
addEndpointToGroup("PageOps", "split-pdfs");
|
||||
addEndpointToGroup("PageOps", "pdf-organizer");
|
||||
addEndpointToGroup("PageOps", "split-pages");
|
||||
addEndpointToGroup("PageOps", "rearrange-pages");
|
||||
addEndpointToGroup("PageOps", "rotate-pdf");
|
||||
addEndpointToGroup("PageOps", "multi-page-layout");
|
||||
addEndpointToGroup("PageOps", "booklet-imposition");
|
||||
addEndpointToGroup("PageOps", "scale-pages");
|
||||
addEndpointToGroup("PageOps", "crop");
|
||||
addEndpointToGroup("PageOps", "extract-page");
|
||||
addEndpointToGroup("PageOps", "pdf-to-single-page");
|
||||
addEndpointToGroup("PageOps", "auto-split-pdf");
|
||||
addEndpointToGroup("PageOps", "split-by-size-or-count");
|
||||
addEndpointToGroup("PageOps", "overlay-pdf");
|
||||
addEndpointToGroup("PageOps", "split-pdf-by-sections");
|
||||
addEndpointToGroup("PageOps", "split-pdf-by-chapters");
|
||||
addEndpointToGroup("PageOps", "add-page-numbers");
|
||||
addEndpointToGroup("PageOps", "extract-pages");
|
||||
|
||||
// Adding endpoints to "Convert" group
|
||||
// Adding endpoints to "Convert" group (Frontend has 15 convert endpoints)
|
||||
addEndpointToGroup("Convert", "pdf-to-img");
|
||||
addEndpointToGroup("Convert", "img-to-pdf");
|
||||
addEndpointToGroup("Convert", "pdf-to-pdfa");
|
||||
@@ -334,6 +335,8 @@ public class EndpointConfiguration {
|
||||
addEndpointToGroup("Convert", "pdf-to-csv");
|
||||
addEndpointToGroup("Convert", "pdf-to-markdown");
|
||||
addEndpointToGroup("Convert", "eml-to-pdf");
|
||||
addEndpointToGroup("Convert", "pdf-to-epub");
|
||||
// Backend-only endpoints (not in frontend tool registry)
|
||||
addEndpointToGroup("Convert", "pdf-to-vector");
|
||||
addEndpointToGroup("Convert", "vector-to-pdf");
|
||||
addEndpointToGroup("Convert", "pdf-to-video");
|
||||
@@ -341,6 +344,7 @@ public class EndpointConfiguration {
|
||||
addEndpointToGroup("Convert", "pdf-to-cbz");
|
||||
addEndpointToGroup("Convert", "pdf-to-json");
|
||||
addEndpointToGroup("Convert", "json-to-pdf");
|
||||
addEndpointToGroup("Convert", "pdf-to-rtf");
|
||||
|
||||
// Adding endpoints to "Security" group
|
||||
addEndpointToGroup("Security", "add-password");
|
||||
@@ -351,51 +355,49 @@ public class EndpointConfiguration {
|
||||
addEndpointToGroup("Security", "remove-cert-sign");
|
||||
addEndpointToGroup("Security", "sanitize-pdf");
|
||||
addEndpointToGroup("Security", "auto-redact");
|
||||
addEndpointToGroup("Security", "redact");
|
||||
addEndpointToGroup("Security", "validate-signature");
|
||||
addEndpointToGroup("Security", "add-stamp");
|
||||
addEndpointToGroup("Security", "unlock-pdf-forms");
|
||||
// Backend-only endpoints (not in frontend tool registry endpoints)
|
||||
addEndpointToGroup("Security", "redact");
|
||||
addEndpointToGroup("Security", "verify-pdf");
|
||||
addEndpointToGroup("Security", "stamp");
|
||||
addEndpointToGroup("Security", "sign");
|
||||
|
||||
// Adding endpoints to "Other" group
|
||||
addEndpointToGroup("Other", "ocr-pdf");
|
||||
addEndpointToGroup("Other", "add-image");
|
||||
addEndpointToGroup("Other", "extract-images");
|
||||
addEndpointToGroup("Other", "change-metadata");
|
||||
addEndpointToGroup("Other", "update-metadata");
|
||||
addEndpointToGroup("Other", "flatten");
|
||||
addEndpointToGroup("Other", "unlock-pdf-forms");
|
||||
addEndpointToGroup("Other", REMOVE_BLANKS);
|
||||
addEndpointToGroup("Other", "remove-annotations");
|
||||
addEndpointToGroup("Other", "compare");
|
||||
addEndpointToGroup("Other", "add-page-numbers");
|
||||
addEndpointToGroup("Other", "get-info-on-pdf");
|
||||
addEndpointToGroup("Other", "remove-image-pdf");
|
||||
addEndpointToGroup("Other", "add-attachments");
|
||||
addEndpointToGroup("Other", "replace-invert-pdf");
|
||||
addEndpointToGroup("Other", "edit-table-of-contents");
|
||||
addEndpointToGroup("Other", "text-editor-pdf");
|
||||
// Backend-only endpoints (not in frontend tool registry endpoints)
|
||||
addEndpointToGroup("Other", "add-image");
|
||||
addEndpointToGroup("Other", "compare");
|
||||
addEndpointToGroup("Other", "view-pdf");
|
||||
addEndpointToGroup("Other", "replace-and-invert-color-pdf");
|
||||
addEndpointToGroup("Other", "multi-tool");
|
||||
|
||||
// Adding form-related endpoints to "Other" group
|
||||
addEndpointToGroup("Other", "fields");
|
||||
addEndpointToGroup("Other", "modify-fields");
|
||||
addEndpointToGroup("Other", "delete-fields");
|
||||
addEndpointToGroup("Other", "fill");
|
||||
|
||||
// Adding endpoints to "Advance" group
|
||||
addEndpointToGroup("Advance", "adjust-contrast");
|
||||
addEndpointToGroup("Advance", "compress-pdf");
|
||||
addEndpointToGroup("Advance", "extract-image-scans");
|
||||
addEndpointToGroup("Advance", "repair");
|
||||
addEndpointToGroup("Advance", "auto-rename");
|
||||
addEndpointToGroup("Advance", "pipeline");
|
||||
addEndpointToGroup("Advance", "handleData");
|
||||
addEndpointToGroup("Advance", "scanner-effect");
|
||||
addEndpointToGroup("Advance", "auto-split-pdf");
|
||||
addEndpointToGroup("Advance", "show-javascript");
|
||||
addEndpointToGroup("Advance", "split-by-size-or-count");
|
||||
addEndpointToGroup("Advance", "overlay-pdf");
|
||||
addEndpointToGroup("Advance", "split-pdf-by-sections");
|
||||
addEndpointToGroup("Advance", "edit-table-of-contents");
|
||||
addEndpointToGroup("Advance", "split-pdf-by-chapters");
|
||||
// Backend-only endpoints
|
||||
addEndpointToGroup("Advance", "adjust-contrast");
|
||||
addEndpointToGroup("Advance", "pipeline");
|
||||
|
||||
// CLI
|
||||
addEndpointToGroup("CLI", "compress-pdf");
|
||||
@@ -436,8 +438,8 @@ public class EndpointConfiguration {
|
||||
// Java
|
||||
addEndpointToGroup("Java", "merge-pdfs");
|
||||
addEndpointToGroup("Java", "remove-pages");
|
||||
addEndpointToGroup("Java", "split-pdfs");
|
||||
addEndpointToGroup("Java", "pdf-organizer");
|
||||
addEndpointToGroup("Java", "split-pages");
|
||||
addEndpointToGroup("Java", "rearrange-pages");
|
||||
addEndpointToGroup("Java", "rotate-pdf");
|
||||
addEndpointToGroup("Java", "pdf-to-img");
|
||||
addEndpointToGroup("Java", "img-to-pdf");
|
||||
@@ -445,9 +447,10 @@ public class EndpointConfiguration {
|
||||
addEndpointToGroup("Java", "remove-password");
|
||||
addEndpointToGroup("Java", "change-permissions");
|
||||
addEndpointToGroup("Java", "add-watermark");
|
||||
addEndpointToGroup("Java", "add-stamp");
|
||||
addEndpointToGroup("Java", "add-image");
|
||||
addEndpointToGroup("Java", "extract-images");
|
||||
addEndpointToGroup("Java", "change-metadata");
|
||||
addEndpointToGroup("Java", "update-metadata");
|
||||
addEndpointToGroup("Java", "cert-sign");
|
||||
addEndpointToGroup("Java", "remove-cert-sign");
|
||||
addEndpointToGroup("Java", "multi-page-layout");
|
||||
@@ -459,7 +462,6 @@ public class EndpointConfiguration {
|
||||
addEndpointToGroup("Java", "sanitize-pdf");
|
||||
addEndpointToGroup("Java", "crop");
|
||||
addEndpointToGroup("Java", "get-info-on-pdf");
|
||||
addEndpointToGroup("Java", "extract-page");
|
||||
addEndpointToGroup("Java", "pdf-to-single-page");
|
||||
addEndpointToGroup("Java", "markdown-to-pdf");
|
||||
addEndpointToGroup("Java", "show-javascript");
|
||||
@@ -469,7 +471,9 @@ public class EndpointConfiguration {
|
||||
addEndpointToGroup("Java", "split-by-size-or-count");
|
||||
addEndpointToGroup("Java", "overlay-pdf");
|
||||
addEndpointToGroup("Java", "split-pdf-by-sections");
|
||||
addEndpointToGroup("Java", "split-pdf-by-chapters");
|
||||
addEndpointToGroup("Java", REMOVE_BLANKS);
|
||||
addEndpointToGroup("Java", "remove-annotations");
|
||||
addEndpointToGroup("Java", "pdf-to-text");
|
||||
addEndpointToGroup("Java", "remove-image-pdf");
|
||||
addEndpointToGroup("Java", "pdf-to-markdown");
|
||||
@@ -479,15 +483,24 @@ public class EndpointConfiguration {
|
||||
addEndpointToGroup("Java", "pdf-to-cbz");
|
||||
addEndpointToGroup("Java", "pdf-to-json");
|
||||
addEndpointToGroup("Java", "json-to-pdf");
|
||||
addEndpointToGroup("rar", "pdf-to-cbr");
|
||||
addEndpointToGroup("Java", "pdf-to-video");
|
||||
addEndpointToGroup("Java", "verify-pdf");
|
||||
addEndpointToGroup("Java", "flatten");
|
||||
addEndpointToGroup("Java", "unlock-pdf-forms");
|
||||
addEndpointToGroup("Java", "validate-signature");
|
||||
addEndpointToGroup("Java", "text-editor-pdf");
|
||||
addEndpointToGroup("Java", "edit-table-of-contents");
|
||||
addEndpointToGroup("Java", "pdf-to-epub");
|
||||
addEndpointToGroup("Java", "eml-to-pdf");
|
||||
addEndpointToGroup("Java", "handleData");
|
||||
addEndpointToGroup("rar", "pdf-to-cbr");
|
||||
|
||||
// Javascript
|
||||
addEndpointToGroup("Javascript", "pdf-organizer");
|
||||
addEndpointToGroup("Javascript", "rearrange-pages");
|
||||
addEndpointToGroup("Javascript", "sign");
|
||||
addEndpointToGroup("Javascript", "compare");
|
||||
addEndpointToGroup("Javascript", "adjust-contrast");
|
||||
addEndpointToGroup("Javascript", "text-editor-pdf");
|
||||
|
||||
/* qpdf */
|
||||
addEndpointToGroup("qpdf", "repair");
|
||||
@@ -498,6 +511,7 @@ public class EndpointConfiguration {
|
||||
addEndpointToGroup("Ghostscript", "compress-pdf");
|
||||
addEndpointToGroup("Ghostscript", "crop");
|
||||
addEndpointToGroup("Ghostscript", "replace-invert-pdf");
|
||||
addEndpointToGroup("Ghostscript", "scanner-effect");
|
||||
addEndpointToGroup("Ghostscript", "pdf-to-vector");
|
||||
addEndpointToGroup("Ghostscript", "vector-to-pdf");
|
||||
|
||||
@@ -516,6 +530,8 @@ public class EndpointConfiguration {
|
||||
addEndpointAlternative("compress-pdf", "qpdf");
|
||||
addEndpointAlternative("compress-pdf", "Ghostscript");
|
||||
addEndpointAlternative("compress-pdf", "Java");
|
||||
addEndpointAlternative("crop", "Ghostscript");
|
||||
addEndpointAlternative("crop", "Java");
|
||||
addEndpointAlternative("ocr-pdf", "tesseract");
|
||||
addEndpointAlternative("ocr-pdf", "OCRmyPDF");
|
||||
|
||||
@@ -544,6 +560,9 @@ public class EndpointConfiguration {
|
||||
// Pdftohtml dependent endpoints
|
||||
addEndpointToGroup("Pdftohtml", "pdf-to-html");
|
||||
addEndpointToGroup("Pdftohtml", "pdf-to-markdown");
|
||||
|
||||
// Calibre dependent endpoints
|
||||
addEndpointToGroup("Calibre", "pdf-to-epub");
|
||||
}
|
||||
|
||||
private void processEnvironmentConfigs() {
|
||||
|
||||
+155
-6
@@ -1,10 +1,14 @@
|
||||
package stirling.software.common.configuration;
|
||||
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.InvalidPathException;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
@@ -41,6 +45,7 @@ public class RuntimePathConfig {
|
||||
|
||||
// Pipeline paths
|
||||
private final String pipelineWatchedFoldersPath;
|
||||
private final List<String> pipelineWatchedFoldersPaths;
|
||||
private final String pipelineFinishedFoldersPath;
|
||||
private final String pipelineDefaultWebUiConfigs;
|
||||
private final String pipelinePath;
|
||||
@@ -49,20 +54,27 @@ public class RuntimePathConfig {
|
||||
this.properties = properties;
|
||||
this.basePath = InstallationPathConfig.getPath();
|
||||
|
||||
this.pipelinePath = Path.of(basePath, "pipeline").toString();
|
||||
String defaultWatchedFolders = Path.of(this.pipelinePath, "watchedFolders").toString();
|
||||
String defaultFinishedFolders = Path.of(this.pipelinePath, "finishedFolders").toString();
|
||||
String defaultWebUIConfigs = Path.of(this.pipelinePath, "defaultWebUIConfigs").toString();
|
||||
|
||||
System system = properties.getSystem();
|
||||
CustomPaths customPaths = system.getCustomPaths();
|
||||
|
||||
Pipeline pipeline = customPaths.getPipeline();
|
||||
|
||||
this.pipelineWatchedFoldersPath =
|
||||
this.pipelinePath =
|
||||
resolvePath(
|
||||
Path.of(basePath, "pipeline").toString(),
|
||||
pipeline != null ? pipeline.getPipelineDir() : null);
|
||||
String defaultWatchedFolders = Path.of(this.pipelinePath, "watchedFolders").toString();
|
||||
String defaultFinishedFolders = Path.of(this.pipelinePath, "finishedFolders").toString();
|
||||
String defaultWebUIConfigs = Path.of(this.pipelinePath, "defaultWebUIConfigs").toString();
|
||||
|
||||
List<String> watchedFoldersDirs =
|
||||
sanitizePathList(pipeline != null ? pipeline.getWatchedFoldersDirs() : null);
|
||||
this.pipelineWatchedFoldersPaths =
|
||||
resolveWatchedFolderPaths(
|
||||
defaultWatchedFolders,
|
||||
watchedFoldersDirs,
|
||||
pipeline != null ? pipeline.getWatchedFoldersDir() : null);
|
||||
this.pipelineWatchedFoldersPath = this.pipelineWatchedFoldersPaths.get(0);
|
||||
this.pipelineFinishedFoldersPath =
|
||||
resolvePath(
|
||||
defaultFinishedFolders,
|
||||
@@ -72,6 +84,9 @@ public class RuntimePathConfig {
|
||||
defaultWebUIConfigs,
|
||||
pipeline != null ? pipeline.getWebUIConfigsDir() : null);
|
||||
|
||||
// Validate path conflicts after all paths are resolved
|
||||
validatePipelinePaths();
|
||||
|
||||
boolean isDocker = isRunningInDocker();
|
||||
|
||||
// Initialize Operation paths
|
||||
@@ -129,6 +144,140 @@ public class RuntimePathConfig {
|
||||
return StringUtils.isNotBlank(customPath) ? customPath : defaultPath;
|
||||
}
|
||||
|
||||
private List<String> resolveWatchedFolderPaths(
|
||||
String defaultPath, List<String> watchedFoldersDirs, String legacyWatchedFolder) {
|
||||
List<String> rawPaths = new ArrayList<>();
|
||||
|
||||
// Collect paths from new config
|
||||
if (watchedFoldersDirs != null && !watchedFoldersDirs.isEmpty()) {
|
||||
rawPaths.addAll(watchedFoldersDirs);
|
||||
}
|
||||
// Fall back to legacy config
|
||||
else if (StringUtils.isNotBlank(legacyWatchedFolder)) {
|
||||
rawPaths.add(legacyWatchedFolder);
|
||||
}
|
||||
// Fall back to default
|
||||
else {
|
||||
rawPaths.add(defaultPath);
|
||||
}
|
||||
|
||||
// Validate, normalize, and deduplicate paths
|
||||
List<String> validatedPaths = validateAndNormalizePaths(rawPaths);
|
||||
|
||||
// Ensure we have at least one valid path (critical for system to function)
|
||||
if (validatedPaths.isEmpty()) {
|
||||
log.warn(
|
||||
"No valid watched folder paths configured, falling back to default: {}",
|
||||
defaultPath);
|
||||
validatedPaths.add(defaultPath);
|
||||
}
|
||||
|
||||
// Detect overlapping paths (warning only, not blocking)
|
||||
detectOverlappingPaths(validatedPaths);
|
||||
|
||||
return validatedPaths;
|
||||
}
|
||||
|
||||
private List<String> sanitizePathList(List<String> paths) {
|
||||
if (paths == null || paths.isEmpty()) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
List<String> sanitized = new ArrayList<>();
|
||||
for (String path : paths) {
|
||||
if (StringUtils.isNotBlank(path)) {
|
||||
sanitized.add(path.trim());
|
||||
}
|
||||
}
|
||||
return sanitized;
|
||||
}
|
||||
|
||||
private List<String> validateAndNormalizePaths(List<String> paths) {
|
||||
Set<String> normalizedPaths = new LinkedHashSet<>(); // Preserves order, prevents duplicates
|
||||
|
||||
for (String pathStr : paths) {
|
||||
if (StringUtils.isBlank(pathStr)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
try {
|
||||
// Normalize to absolute path
|
||||
Path path = Paths.get(pathStr.trim()).toAbsolutePath().normalize();
|
||||
String normalizedPath = path.toString();
|
||||
|
||||
// Check for duplicates
|
||||
if (normalizedPaths.contains(normalizedPath)) {
|
||||
log.debug("Skipping duplicate watched folder path: {}", pathStr);
|
||||
continue;
|
||||
}
|
||||
|
||||
normalizedPaths.add(normalizedPath);
|
||||
log.info("Registered watched folder path: {}", normalizedPath);
|
||||
|
||||
} catch (InvalidPathException e) {
|
||||
log.error(
|
||||
"Invalid watched folder path '{}' - skipping: {}", pathStr, e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
return new ArrayList<>(normalizedPaths);
|
||||
}
|
||||
|
||||
private void detectOverlappingPaths(List<String> paths) {
|
||||
for (int i = 0; i < paths.size(); i++) {
|
||||
Path path1 = Paths.get(paths.get(i));
|
||||
for (int j = i + 1; j < paths.size(); j++) {
|
||||
Path path2 = Paths.get(paths.get(j));
|
||||
|
||||
// Check if one path is a parent of the other
|
||||
if (path1.startsWith(path2)) {
|
||||
log.warn(
|
||||
"Watched folder path '{}' is nested inside '{}' - this may cause duplicate processing",
|
||||
path1,
|
||||
path2);
|
||||
} else if (path2.startsWith(path1)) {
|
||||
log.warn(
|
||||
"Watched folder path '{}' is nested inside '{}' - this may cause duplicate processing",
|
||||
path2,
|
||||
path1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void validatePipelinePaths() {
|
||||
try {
|
||||
Path finishedPath = Paths.get(pipelineFinishedFoldersPath).toAbsolutePath().normalize();
|
||||
|
||||
for (String watchedPathStr : pipelineWatchedFoldersPaths) {
|
||||
Path watchedPath = Paths.get(watchedPathStr).toAbsolutePath().normalize();
|
||||
|
||||
// Check if watched folder is same as finished folder
|
||||
if (watchedPath.equals(finishedPath)) {
|
||||
log.error(
|
||||
"CRITICAL: Watched folder '{}' is the same as finished folder '{}' - this will cause processing loops!",
|
||||
watchedPath,
|
||||
finishedPath);
|
||||
}
|
||||
// Check if watched folder contains finished folder
|
||||
else if (finishedPath.startsWith(watchedPath)) {
|
||||
log.warn(
|
||||
"Finished folder '{}' is nested inside watched folder '{}' - this may cause issues",
|
||||
finishedPath,
|
||||
watchedPath);
|
||||
}
|
||||
// Check if finished folder contains watched folder
|
||||
else if (watchedPath.startsWith(finishedPath)) {
|
||||
log.error(
|
||||
"CRITICAL: Watched folder '{}' is nested inside finished folder '{}' - this will cause processing loops!",
|
||||
watchedPath,
|
||||
finishedPath);
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("Error validating pipeline paths: {}", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isRunningInDocker() {
|
||||
return Files.exists(Path.of("/.dockerenv"));
|
||||
}
|
||||
|
||||
@@ -164,6 +164,7 @@ public class ApplicationProperties {
|
||||
private String customGlobalAPIKey;
|
||||
private Jwt jwt = new Jwt();
|
||||
private Validation validation = new Validation();
|
||||
private String xFrameOptions = "DENY";
|
||||
|
||||
public Boolean isAltLogin() {
|
||||
return saml2.getEnabled() || oauth2.getEnabled();
|
||||
@@ -458,7 +459,9 @@ public class ApplicationProperties {
|
||||
|
||||
@Data
|
||||
public static class Pipeline {
|
||||
private String pipelineDir;
|
||||
private String watchedFoldersDir;
|
||||
private List<String> watchedFoldersDirs = new ArrayList<>();
|
||||
private String finishedFoldersDir;
|
||||
private String webUIConfigsDir;
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ public class FileMonitor {
|
||||
private final ConcurrentHashMap.KeySetView<Path, Boolean> readyForProcessingFiles;
|
||||
private final WatchService watchService;
|
||||
private final Predicate<Path> pathFilter;
|
||||
private final Path rootDir;
|
||||
private final List<Path> rootDirs;
|
||||
private Set<Path> stagingFiles;
|
||||
|
||||
/**
|
||||
@@ -47,8 +47,28 @@ public class FileMonitor {
|
||||
this.pathFilter = pathFilter;
|
||||
this.readyForProcessingFiles = ConcurrentHashMap.newKeySet();
|
||||
this.watchService = FileSystems.getDefault().newWatchService();
|
||||
log.info("Monitoring directory: {}", runtimePathConfig.getPipelineWatchedFoldersPath());
|
||||
this.rootDir = Path.of(runtimePathConfig.getPipelineWatchedFoldersPath());
|
||||
|
||||
List<String> watchedFoldersDirs = runtimePathConfig.getPipelineWatchedFoldersPaths();
|
||||
List<Path> validRootDirs = new ArrayList<>();
|
||||
|
||||
for (String pathStr : watchedFoldersDirs) {
|
||||
try {
|
||||
Path path = Path.of(pathStr);
|
||||
validRootDirs.add(path);
|
||||
log.info("Monitoring directory: {}", path);
|
||||
} catch (Exception e) {
|
||||
log.error(
|
||||
"Failed to initialize monitoring for path '{}': {}",
|
||||
pathStr,
|
||||
e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
this.rootDirs = Collections.unmodifiableList(validRootDirs);
|
||||
|
||||
if (this.rootDirs.isEmpty()) {
|
||||
log.error("No valid directories to monitor - FileMonitor will not function");
|
||||
}
|
||||
}
|
||||
|
||||
private boolean shouldNotProcess(Path path) {
|
||||
@@ -85,13 +105,15 @@ public class FileMonitor {
|
||||
readyForProcessingFiles.clear();
|
||||
|
||||
if (path2KeyMapping.isEmpty()) {
|
||||
log.warn("not monitoring any directory, even the root directory itself: {}", rootDir);
|
||||
if (Files.exists(
|
||||
rootDir)) { // if the root directory exists, re-register the root directory
|
||||
try {
|
||||
recursivelyRegisterEntry(rootDir);
|
||||
} catch (IOException e) {
|
||||
log.error("unable to register monitoring", e);
|
||||
log.warn("Not monitoring any directories; attempting to re-register root paths.");
|
||||
for (Path rootDir : rootDirs) {
|
||||
if (Files.exists(
|
||||
rootDir)) { // if the root directory exists, re-register the root directory
|
||||
try {
|
||||
recursivelyRegisterEntry(rootDir);
|
||||
} catch (IOException e) {
|
||||
log.error("unable to register monitoring for {}", rootDir, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.attribute.FileTime;
|
||||
import java.time.Instant;
|
||||
import java.util.List;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
@@ -34,7 +35,8 @@ class FileMonitorTest {
|
||||
|
||||
@BeforeEach
|
||||
void setUp() throws IOException {
|
||||
when(runtimePathConfig.getPipelineWatchedFoldersPath()).thenReturn(tempDir.toString());
|
||||
when(runtimePathConfig.getPipelineWatchedFoldersPaths())
|
||||
.thenReturn(List.of(tempDir.toString()));
|
||||
|
||||
// This mock is used in all tests except testPathFilter
|
||||
// We use lenient to avoid UnnecessaryStubbingException in that test
|
||||
|
||||
@@ -221,6 +221,7 @@ tasks.register('npmBuild', Exec) {
|
||||
commandLine = Os.isFamily(Os.FAMILY_WINDOWS) ? ['cmd', '/c', 'npm', 'run', 'build'] : ['npm', 'run', 'build']
|
||||
dependsOn npmInstall
|
||||
inputs.dir(new File(frontendDir, 'src'))
|
||||
inputs.dir(new File(frontendDir, 'public'))
|
||||
inputs.file(new File(frontendDir, 'package.json'))
|
||||
outputs.dir(frontendDistDir)
|
||||
|
||||
|
||||
@@ -118,7 +118,8 @@ public class ExternalAppDepConfig {
|
||||
|
||||
for (String group : affectedGroups) {
|
||||
List<String> affectedFeatures = getAffectedFeatures(group);
|
||||
endpointConfiguration.disableGroup(group);
|
||||
endpointConfiguration.disableGroup(
|
||||
group, EndpointConfiguration.DisableReason.DEPENDENCY);
|
||||
log.warn(
|
||||
"Missing dependency: {} - Disabling group: {} (Affected features: {})",
|
||||
command,
|
||||
@@ -143,7 +144,8 @@ public class ExternalAppDepConfig {
|
||||
commandToGroupMapping.getOrDefault(
|
||||
command, List.of("Weasyprint"));
|
||||
for (String group : affectedGroups) {
|
||||
endpointConfiguration.disableGroup(group);
|
||||
endpointConfiguration.disableGroup(
|
||||
group, EndpointConfiguration.DisableReason.DEPENDENCY);
|
||||
}
|
||||
log.warn(
|
||||
"WeasyPrint version {} is below required {} - disabling"
|
||||
@@ -172,7 +174,8 @@ public class ExternalAppDepConfig {
|
||||
List<String> affectedGroups =
|
||||
commandToGroupMapping.getOrDefault(command, List.of("qpdf"));
|
||||
for (String group : affectedGroups) {
|
||||
endpointConfiguration.disableGroup(group);
|
||||
endpointConfiguration.disableGroup(
|
||||
group, EndpointConfiguration.DisableReason.DEPENDENCY);
|
||||
}
|
||||
log.warn(
|
||||
"qpdf version {} is below required {} - disabling group(s): {}",
|
||||
@@ -226,7 +229,8 @@ public class ExternalAppDepConfig {
|
||||
int ec = runAndWait(List.of(python, "-c", "import cv2"), DEFAULT_TIMEOUT).exitCode();
|
||||
if (ec != 0) {
|
||||
List<String> openCVFeatures = getAffectedFeatures("OpenCV");
|
||||
endpointConfiguration.disableGroup("OpenCV");
|
||||
endpointConfiguration.disableGroup(
|
||||
"OpenCV", EndpointConfiguration.DisableReason.DEPENDENCY);
|
||||
log.warn(
|
||||
"OpenCV not available in Python - Disabling OpenCV features: {}",
|
||||
String.join(", ", openCVFeatures));
|
||||
@@ -236,8 +240,10 @@ public class ExternalAppDepConfig {
|
||||
private void disablePythonAndOpenCV(String reason) {
|
||||
List<String> pythonFeatures = getAffectedFeatures("Python");
|
||||
List<String> openCVFeatures = getAffectedFeatures("OpenCV");
|
||||
endpointConfiguration.disableGroup("Python");
|
||||
endpointConfiguration.disableGroup("OpenCV");
|
||||
endpointConfiguration.disableGroup(
|
||||
"Python", EndpointConfiguration.DisableReason.DEPENDENCY);
|
||||
endpointConfiguration.disableGroup(
|
||||
"OpenCV", EndpointConfiguration.DisableReason.DEPENDENCY);
|
||||
log.warn(
|
||||
"Missing dependency: Python (reason: {}) - Disabling Python features: {} and OpenCV"
|
||||
+ " features: {}",
|
||||
|
||||
@@ -106,16 +106,29 @@ public class WebMvcConfig implements WebMvcConfigurer {
|
||||
.allowCredentials(true)
|
||||
.maxAge(3600);
|
||||
} else if (hasConfiguredOrigins) {
|
||||
// Use user-configured origins
|
||||
// Use user-configured origins + always include Tauri origins for desktop app support
|
||||
logger.info(
|
||||
"Configuring CORS with allowed origins: {}",
|
||||
applicationProperties.getSystem().getCorsAllowedOrigins());
|
||||
|
||||
String[] allowedOrigins =
|
||||
applicationProperties
|
||||
.getSystem()
|
||||
.getCorsAllowedOrigins()
|
||||
.toArray(new String[0]);
|
||||
// Combine user-configured origins with Tauri origins
|
||||
java.util.List<String> allOrigins =
|
||||
new java.util.ArrayList<>(
|
||||
applicationProperties.getSystem().getCorsAllowedOrigins());
|
||||
|
||||
// Always include Tauri origins for desktop app compatibility
|
||||
// Tauri v1 uses tauri://localhost, v2 uses http(s)://tauri.localhost
|
||||
if (!allOrigins.contains("tauri://localhost")) {
|
||||
allOrigins.add("tauri://localhost");
|
||||
}
|
||||
if (!allOrigins.contains("http://tauri.localhost")) {
|
||||
allOrigins.add("http://tauri.localhost");
|
||||
}
|
||||
if (!allOrigins.contains("https://tauri.localhost")) {
|
||||
allOrigins.add("https://tauri.localhost");
|
||||
}
|
||||
|
||||
String[] allowedOrigins = allOrigins.toArray(new String[0]);
|
||||
|
||||
registry.addMapping("/**")
|
||||
.allowedOriginPatterns(allowedOrigins)
|
||||
|
||||
+4
-4
@@ -46,18 +46,18 @@ public class EditTableOfContentsController {
|
||||
@Operation(
|
||||
summary = "Extract PDF Bookmarks",
|
||||
description = "Extracts bookmarks/table of contents from a PDF document as JSON.")
|
||||
@ResponseBody
|
||||
public List<Map<String, Object>> extractBookmarks(@RequestParam("file") MultipartFile file)
|
||||
public ResponseEntity<List<Map<String, Object>>> extractBookmarks(@RequestParam("file") MultipartFile file)
|
||||
throws Exception {
|
||||
try (PDDocument document = pdfDocumentFactory.load(file)) {
|
||||
PDDocumentOutline outline = document.getDocumentCatalog().getDocumentOutline();
|
||||
|
||||
if (outline == null) {
|
||||
log.info("No outline/bookmarks found in PDF");
|
||||
return new ArrayList<>();
|
||||
return ResponseEntity.ok(new ArrayList<>());
|
||||
}
|
||||
|
||||
return extractBookmarkItems(document, outline);
|
||||
List<Map<String, Object>> bookmarks = extractBookmarkItems(document, outline);
|
||||
return ResponseEntity.ok(bookmarks);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+10
-1
@@ -52,9 +52,17 @@ public class PageNumbersController {
|
||||
int pageNumber = request.getStartingNumber();
|
||||
String pagesToNumber = request.getPagesToNumber();
|
||||
String customText = request.getCustomText();
|
||||
int zeroPad = request.getZeroPad();
|
||||
float fontSize = request.getFontSize();
|
||||
String fontType = request.getFontType();
|
||||
String fontColor = request.getFontColor();
|
||||
// compute padded number string where requested
|
||||
String formatN;
|
||||
if (zeroPad > 0) {
|
||||
formatN = String.format("%%0%dd", Math.max(0, zeroPad));
|
||||
} else {
|
||||
formatN = "%d";
|
||||
}
|
||||
|
||||
Color color = Color.BLACK;
|
||||
if (fontColor != null && !fontColor.trim().isEmpty()) {
|
||||
@@ -93,9 +101,10 @@ public class PageNumbersController {
|
||||
PDPage page = document.getPage(i);
|
||||
PDRectangle pageSize = page.getMediaBox();
|
||||
|
||||
String nFormatted = String.format(formatN, pageNumber);
|
||||
String text =
|
||||
customText
|
||||
.replace("{n}", String.valueOf(pageNumber))
|
||||
.replace("{n}", nFormatted)
|
||||
.replace("{total}", String.valueOf(document.getNumberOfPages()))
|
||||
.replace(
|
||||
"{filename}",
|
||||
|
||||
+196
-57
@@ -7,11 +7,13 @@ import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalTime;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.UUID;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
|
||||
@@ -58,6 +60,13 @@ public class StampController {
|
||||
private final CustomPDFDocumentFactory pdfDocumentFactory;
|
||||
private final TempFileManager tempFileManager;
|
||||
|
||||
private static final int MAX_DATE_FORMAT_LENGTH = 50;
|
||||
private static final Pattern SAFE_DATE_FORMAT_PATTERN =
|
||||
Pattern.compile("^[yMdHhmsS/\\-:\\s.,'+EGuwWDFzZXa]+$");
|
||||
private static final Pattern CUSTOM_DATE_PATTERN = Pattern.compile("@date\\{([^}]{1,50})\\}");
|
||||
// Placeholder for escaped @ symbol (using Unicode private use area)
|
||||
private static final String ESCAPED_AT_PLACEHOLDER = "\uE000ESCAPED_AT\uE000";
|
||||
|
||||
/**
|
||||
* Initialize data binder for multipart file uploads. This method registers a custom editor for
|
||||
* MultipartFile to handle file uploads. It sets the MultipartFile to null if the uploaded file
|
||||
@@ -166,7 +175,9 @@ public class StampController {
|
||||
overrideX,
|
||||
overrideY,
|
||||
margin,
|
||||
customColor);
|
||||
customColor,
|
||||
pageIndex,
|
||||
pdfFileName);
|
||||
} else if ("image".equalsIgnoreCase(stampType)) {
|
||||
addImageStamp(
|
||||
contentStream,
|
||||
@@ -201,9 +212,11 @@ public class StampController {
|
||||
float fontSize,
|
||||
String alphabet,
|
||||
float overrideX, // X override
|
||||
float overrideY,
|
||||
float overrideY, // Y override
|
||||
float margin,
|
||||
String colorString) // Y override
|
||||
String colorString,
|
||||
int currentPageNumber,
|
||||
String filename)
|
||||
throws IOException {
|
||||
String resourceDir;
|
||||
PDFont font = new PDType1Font(Standard14Fonts.FontName.HELVETICA);
|
||||
@@ -231,8 +244,6 @@ public class StampController {
|
||||
}
|
||||
}
|
||||
|
||||
contentStream.setFont(font, fontSize);
|
||||
|
||||
Color redactColor;
|
||||
try {
|
||||
if (!colorString.startsWith("#")) {
|
||||
@@ -240,47 +251,54 @@ public class StampController {
|
||||
}
|
||||
redactColor = Color.decode(colorString);
|
||||
} catch (NumberFormatException e) {
|
||||
|
||||
redactColor = Color.LIGHT_GRAY;
|
||||
}
|
||||
|
||||
contentStream.setNonStrokingColor(redactColor);
|
||||
|
||||
PDRectangle pageSize = page.getMediaBox();
|
||||
float x, y;
|
||||
|
||||
if (overrideX >= 0 && overrideY >= 0) {
|
||||
// Use override values if provided
|
||||
x = overrideX;
|
||||
y = overrideY;
|
||||
} else {
|
||||
x = calculatePositionX(pageSize, position, fontSize, font, fontSize, stampText, margin);
|
||||
y =
|
||||
calculatePositionY(
|
||||
pageSize, position, calculateTextCapHeight(font, fontSize), margin);
|
||||
}
|
||||
|
||||
String currentDate = LocalDate.now().toString();
|
||||
String currentTime = LocalTime.now().format(DateTimeFormatter.ofPattern("HH:mm:ss"));
|
||||
|
||||
int pageCount = document.getNumberOfPages();
|
||||
|
||||
String processedStampText =
|
||||
stampText
|
||||
.replace("@date", currentDate)
|
||||
.replace("@time", currentTime)
|
||||
.replace("@page_count", String.valueOf(pageCount));
|
||||
processStampText(stampText, currentPageNumber, pageCount, filename, document);
|
||||
|
||||
// Split the stampText into multiple lines
|
||||
String[] lines =
|
||||
String normalizedText =
|
||||
RegexPatternUtils.getInstance()
|
||||
.getEscapedNewlinePattern()
|
||||
.split(processedStampText);
|
||||
.matcher(processedStampText)
|
||||
.replaceAll("\n");
|
||||
String[] lines = normalizedText.split("\\r?\\n");
|
||||
|
||||
PDRectangle pageSize = page.getMediaBox();
|
||||
|
||||
// Use fontSize directly (default 40 if not specified)
|
||||
float effectiveFontSize = fontSize > 0 ? fontSize : 40f;
|
||||
|
||||
contentStream.setFont(font, effectiveFontSize);
|
||||
|
||||
// Calculate dynamic line height based on font ascent and descent
|
||||
float ascent = font.getFontDescriptor().getAscent();
|
||||
float descent = font.getFontDescriptor().getDescent();
|
||||
float lineHeight = ((ascent - descent) / 1000) * fontSize;
|
||||
float lineHeight = ((ascent - descent) / 1000) * effectiveFontSize;
|
||||
|
||||
float maxLineWidth = 0;
|
||||
for (String line : lines) {
|
||||
float lineWidth = calculateTextWidth(line, font, effectiveFontSize);
|
||||
if (lineWidth > maxLineWidth) {
|
||||
maxLineWidth = lineWidth;
|
||||
}
|
||||
}
|
||||
|
||||
float totalTextHeight = lines.length * lineHeight;
|
||||
|
||||
float x, y;
|
||||
|
||||
if (overrideX >= 0 && overrideY >= 0) {
|
||||
x = overrideX;
|
||||
y = overrideY;
|
||||
} else {
|
||||
x = calculatePositionX(pageSize, position, maxLineWidth, margin);
|
||||
y = calculatePositionY(pageSize, position, totalTextHeight, margin);
|
||||
}
|
||||
|
||||
contentStream.beginText();
|
||||
for (int i = 0; i < lines.length; i++) {
|
||||
@@ -293,6 +311,140 @@ public class StampController {
|
||||
contentStream.endText();
|
||||
}
|
||||
|
||||
/**
|
||||
* Process stamp text by replacing all @commands with their actual values. Supported commands:
|
||||
*
|
||||
* <p>Date & Time:
|
||||
*
|
||||
* <ul>
|
||||
* <li>@date - Current date (YYYY-MM-DD)
|
||||
* <li>@time - Current time (HH:mm:ss)
|
||||
* <li>@datetime - Current date and time (YYYY-MM-DD HH:mm:ss)
|
||||
* <li>@date{format} - Custom date/time format (e.g., @date{dd/MM/yyyy})
|
||||
* <li>@year - Current year (4 digits)
|
||||
* <li>@month - Current month (01-12)
|
||||
* <li>@day - Current day of month (01-31)
|
||||
* </ul>
|
||||
*
|
||||
* <p>Page Information:
|
||||
*
|
||||
* <ul>
|
||||
* <li>@page_number or @page - Current page number
|
||||
* <li>@total_pages or @page_count - Total number of pages
|
||||
* </ul>
|
||||
*
|
||||
* <p>File Information:
|
||||
*
|
||||
* <ul>
|
||||
* <li>@filename - Original filename (without extension)
|
||||
* <li>@filename_full - Original filename (with extension)
|
||||
* </ul>
|
||||
*
|
||||
* <p>Document Metadata:
|
||||
*
|
||||
* <ul>
|
||||
* <li>@author - Document author (from PDF metadata)
|
||||
* <li>@title - Document title (from PDF metadata)
|
||||
* <li>@subject - Document subject (from PDF metadata)
|
||||
* </ul>
|
||||
*
|
||||
* <p>Other:
|
||||
*
|
||||
* <ul>
|
||||
* <li>@uuid - Short unique identifier (8 characters)
|
||||
* </ul>
|
||||
*/
|
||||
private String processStampText(
|
||||
String stampText,
|
||||
int currentPageNumber,
|
||||
int totalPages,
|
||||
String filename,
|
||||
PDDocument document) {
|
||||
if (stampText == null || stampText.isEmpty()) {
|
||||
return "";
|
||||
}
|
||||
|
||||
// Handle escaped @@ sequences first - replace with placeholder to preserve literal @
|
||||
String result = stampText.replace("@@", ESCAPED_AT_PLACEHOLDER);
|
||||
|
||||
LocalDateTime now = LocalDateTime.now();
|
||||
String currentDate = now.toLocalDate().toString();
|
||||
String currentTime = now.toLocalTime().format(DateTimeFormatter.ofPattern("HH:mm:ss"));
|
||||
String currentDateTime = now.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
|
||||
|
||||
String filenameWithoutExt = filename != null ? filename : "";
|
||||
if (filename != null && filename.contains(".")) {
|
||||
int lastDot = filename.lastIndexOf('.');
|
||||
if (lastDot > 0) { // Ensure there's actually a name before the dot
|
||||
filenameWithoutExt = filename.substring(0, lastDot);
|
||||
}
|
||||
}
|
||||
|
||||
String author = "";
|
||||
String title = "";
|
||||
String subject = "";
|
||||
if (document != null && document.getDocumentInformation() != null) {
|
||||
var info = document.getDocumentInformation();
|
||||
author = info.getAuthor() != null ? info.getAuthor() : "";
|
||||
title = info.getTitle() != null ? info.getTitle() : "";
|
||||
subject = info.getSubject() != null ? info.getSubject() : "";
|
||||
}
|
||||
|
||||
String uuid = UUID.randomUUID().toString().substring(0, 8);
|
||||
|
||||
// Process @date{format} with custom format first (must be before simple @date)
|
||||
Matcher matcher = CUSTOM_DATE_PATTERN.matcher(result);
|
||||
StringBuilder sb = new StringBuilder();
|
||||
while (matcher.find()) {
|
||||
String format = matcher.group(1);
|
||||
String replacement = processCustomDateFormat(format, now);
|
||||
matcher.appendReplacement(sb, Matcher.quoteReplacement(replacement));
|
||||
}
|
||||
matcher.appendTail(sb);
|
||||
result = sb.toString();
|
||||
|
||||
result =
|
||||
result.replace("@datetime", currentDateTime)
|
||||
.replace("@date", currentDate)
|
||||
.replace("@time", currentTime)
|
||||
.replace("@year", String.valueOf(now.getYear()))
|
||||
.replace("@month", String.format("%02d", now.getMonthValue()))
|
||||
.replace("@day", String.format("%02d", now.getDayOfMonth()))
|
||||
.replace("@page_number", String.valueOf(currentPageNumber))
|
||||
.replace(
|
||||
"@page_count", String.valueOf(totalPages)) // Must come before @page
|
||||
.replace("@total_pages", String.valueOf(totalPages))
|
||||
.replace(
|
||||
"@page",
|
||||
String.valueOf(currentPageNumber)) // Must come after @page_count
|
||||
.replace("@filename_full", filename != null ? filename : "")
|
||||
.replace("@filename", filenameWithoutExt)
|
||||
.replace("@author", author)
|
||||
.replace("@title", title)
|
||||
.replace("@subject", subject)
|
||||
.replace("@uuid", uuid);
|
||||
|
||||
result = result.replace(ESCAPED_AT_PLACEHOLDER, "@");
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private String processCustomDateFormat(String format, LocalDateTime now) {
|
||||
if (format == null || format.length() > MAX_DATE_FORMAT_LENGTH) {
|
||||
return "[invalid format: too long]";
|
||||
}
|
||||
|
||||
if (!SAFE_DATE_FORMAT_PATTERN.matcher(format).matches()) {
|
||||
return "[invalid format]";
|
||||
}
|
||||
|
||||
try {
|
||||
return now.format(DateTimeFormatter.ofPattern(format));
|
||||
} catch (IllegalArgumentException e) {
|
||||
return "[invalid format: " + format + "]";
|
||||
}
|
||||
}
|
||||
|
||||
private void addImageStamp(
|
||||
PDPageContentStream contentStream,
|
||||
MultipartFile stampImage,
|
||||
@@ -329,8 +481,8 @@ public class StampController {
|
||||
x = overrideX;
|
||||
y = overrideY;
|
||||
} else {
|
||||
x = calculatePositionX(pageSize, position, desiredPhysicalWidth, null, 0, null, margin);
|
||||
y = calculatePositionY(pageSize, position, fontSize, margin);
|
||||
x = calculatePositionX(pageSize, position, desiredPhysicalWidth, margin);
|
||||
y = calculatePositionY(pageSize, position, desiredPhysicalHeight, margin);
|
||||
}
|
||||
|
||||
contentStream.saveGraphicsState();
|
||||
@@ -341,23 +493,14 @@ public class StampController {
|
||||
}
|
||||
|
||||
private float calculatePositionX(
|
||||
PDRectangle pageSize,
|
||||
int position,
|
||||
float contentWidth,
|
||||
PDFont font,
|
||||
float fontSize,
|
||||
String text,
|
||||
float margin)
|
||||
throws IOException {
|
||||
float actualWidth =
|
||||
(text != null) ? calculateTextWidth(text, font, fontSize) : contentWidth;
|
||||
PDRectangle pageSize, int position, float contentWidth, float margin) {
|
||||
return switch (position % 3) {
|
||||
case 1: // Left
|
||||
yield pageSize.getLowerLeftX() + margin;
|
||||
case 2: // Center
|
||||
yield (pageSize.getWidth() - actualWidth) / 2;
|
||||
yield (pageSize.getWidth() - contentWidth) / 2;
|
||||
case 0: // Right
|
||||
yield pageSize.getUpperRightX() - actualWidth - margin;
|
||||
yield pageSize.getUpperRightX() - contentWidth - margin;
|
||||
default:
|
||||
yield 0;
|
||||
};
|
||||
@@ -366,12 +509,12 @@ public class StampController {
|
||||
private float calculatePositionY(
|
||||
PDRectangle pageSize, int position, float height, float margin) {
|
||||
return switch ((position - 1) / 3) {
|
||||
case 0: // Top
|
||||
yield pageSize.getUpperRightY() - height - margin;
|
||||
case 1: // Middle
|
||||
yield (pageSize.getHeight() - height) / 2;
|
||||
case 2: // Bottom
|
||||
yield pageSize.getLowerLeftY() + margin;
|
||||
case 0: // Top - first line near the top
|
||||
yield pageSize.getUpperRightY() - margin;
|
||||
case 1: // Middle - center of text block at page center
|
||||
yield (pageSize.getHeight() + height) / 2;
|
||||
case 2: // Bottom - first line positioned so last line is at bottom margin
|
||||
yield pageSize.getLowerLeftY() + margin + height;
|
||||
default:
|
||||
yield 0;
|
||||
};
|
||||
@@ -380,8 +523,4 @@ public class StampController {
|
||||
private float calculateTextWidth(String text, PDFont font, float fontSize) throws IOException {
|
||||
return font.getStringWidth(text) / 1000 * fontSize;
|
||||
}
|
||||
|
||||
private float calculateTextCapHeight(PDFont font, float fontSize) {
|
||||
return font.getFontDescriptor().getCapHeight() / 1000 * fontSize;
|
||||
}
|
||||
}
|
||||
|
||||
+59
-6
@@ -3,6 +3,7 @@ package stirling.software.SPDF.controller.api.pipeline;
|
||||
import java.io.*;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.FileSystemException;
|
||||
import java.nio.file.FileVisitOption;
|
||||
import java.nio.file.FileVisitResult;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
@@ -14,6 +15,7 @@ import java.time.LocalDate;
|
||||
import java.time.LocalTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.EnumSet;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
@@ -41,14 +43,20 @@ import stirling.software.common.util.FileMonitor;
|
||||
@Slf4j
|
||||
public class PipelineDirectoryProcessor {
|
||||
|
||||
private static final int MAX_DIRECTORY_DEPTH = 50; // Prevent excessive recursion
|
||||
|
||||
private final ObjectMapper objectMapper;
|
||||
private final ApiDocService apiDocService;
|
||||
private final PipelineProcessor processor;
|
||||
private final FileMonitor fileMonitor;
|
||||
private final PostHogService postHogService;
|
||||
private final String watchedFoldersDir;
|
||||
private final List<String> watchedFoldersDirs;
|
||||
private final String finishedFoldersDir;
|
||||
|
||||
// Track processed directories in current scan to prevent duplicates
|
||||
private final ThreadLocal<java.util.Set<Path>> processedDirsInScan =
|
||||
ThreadLocal.withInitial(java.util.HashSet::new);
|
||||
|
||||
public PipelineDirectoryProcessor(
|
||||
ObjectMapper objectMapper,
|
||||
ApiDocService apiDocService,
|
||||
@@ -61,13 +69,26 @@ public class PipelineDirectoryProcessor {
|
||||
this.processor = processor;
|
||||
this.fileMonitor = fileMonitor;
|
||||
this.postHogService = postHogService;
|
||||
this.watchedFoldersDir = runtimePathConfig.getPipelineWatchedFoldersPath();
|
||||
this.watchedFoldersDirs = runtimePathConfig.getPipelineWatchedFoldersPaths();
|
||||
this.finishedFoldersDir = runtimePathConfig.getPipelineFinishedFoldersPath();
|
||||
}
|
||||
|
||||
@Scheduled(fixedRate = 60000)
|
||||
public void scanFolders() {
|
||||
Path watchedFolderPath = Paths.get(watchedFoldersDir).toAbsolutePath();
|
||||
// Clear the processed directories set for this scan cycle
|
||||
processedDirsInScan.get().clear();
|
||||
|
||||
try {
|
||||
for (String watchedFoldersDir : watchedFoldersDirs) {
|
||||
scanWatchedFolder(Paths.get(watchedFoldersDir).toAbsolutePath());
|
||||
}
|
||||
} finally {
|
||||
// Clean up ThreadLocal to prevent memory leaks
|
||||
processedDirsInScan.remove();
|
||||
}
|
||||
}
|
||||
|
||||
private void scanWatchedFolder(Path watchedFolderPath) {
|
||||
if (!Files.exists(watchedFolderPath)) {
|
||||
try {
|
||||
Files.createDirectories(watchedFolderPath);
|
||||
@@ -78,16 +99,34 @@ public class PipelineDirectoryProcessor {
|
||||
}
|
||||
}
|
||||
|
||||
// Validate the path is a directory and readable
|
||||
if (!Files.isDirectory(watchedFolderPath)) {
|
||||
log.error("Path is not a directory: {}", watchedFolderPath);
|
||||
return;
|
||||
}
|
||||
if (!Files.isReadable(watchedFolderPath)) {
|
||||
log.error("Directory is not readable: {}", watchedFolderPath);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
// Use FOLLOW_LINKS to follow symlinks, with max depth to prevent infinite loops
|
||||
Files.walkFileTree(
|
||||
watchedFolderPath,
|
||||
EnumSet.of(FileVisitOption.FOLLOW_LINKS),
|
||||
MAX_DIRECTORY_DEPTH,
|
||||
new SimpleFileVisitor<>() {
|
||||
@Override
|
||||
public FileVisitResult preVisitDirectory(
|
||||
Path dir, BasicFileAttributes attrs) {
|
||||
try {
|
||||
String dirName =
|
||||
dir.getFileName() != null
|
||||
? dir.getFileName().toString()
|
||||
: "";
|
||||
// Skip root directory and "processing" subdirectories
|
||||
if (!dir.equals(watchedFolderPath) && !dir.endsWith("processing")) {
|
||||
if (!dir.equals(watchedFolderPath)
|
||||
&& !"processing".equals(dirName)) {
|
||||
handleDirectory(dir);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
@@ -98,8 +137,11 @@ public class PipelineDirectoryProcessor {
|
||||
|
||||
@Override
|
||||
public FileVisitResult visitFileFailed(Path path, IOException exc) {
|
||||
// Handle broken symlinks or inaccessible directories
|
||||
log.error("Error accessing path: {}", path, exc);
|
||||
// Handle broken symlinks, permission issues, or inaccessible
|
||||
// directories
|
||||
if (exc != null) {
|
||||
log.debug("Cannot access path '{}': {}", path, exc.getMessage());
|
||||
}
|
||||
return FileVisitResult.CONTINUE;
|
||||
}
|
||||
});
|
||||
@@ -109,6 +151,17 @@ public class PipelineDirectoryProcessor {
|
||||
}
|
||||
|
||||
public void handleDirectory(Path dir) throws IOException {
|
||||
// Normalize path to absolute to prevent duplicate processing from different path
|
||||
// representations
|
||||
Path normalizedDir = dir.toAbsolutePath().normalize();
|
||||
|
||||
// Check if we've already processed this directory in this scan cycle
|
||||
java.util.Set<Path> processedDirs = processedDirsInScan.get();
|
||||
if (!processedDirs.add(normalizedDir)) {
|
||||
log.debug("Directory already processed in this scan cycle: {}", normalizedDir);
|
||||
return;
|
||||
}
|
||||
|
||||
log.info("Handling directory: {}", dir);
|
||||
Path processingDir = createProcessingDirectory(dir);
|
||||
Optional<Path> jsonFileOptional = findJsonFile(dir);
|
||||
|
||||
+7
@@ -39,6 +39,13 @@ public class AddPageNumbersRequest extends PDFWithPageNums {
|
||||
requiredMode = RequiredMode.NOT_REQUIRED)
|
||||
private String fontColor;
|
||||
|
||||
@Schema(
|
||||
description = "Zero-padding width for page numbers (Bates Stamping). Set to 0 to disable padding",
|
||||
minimum = "0",
|
||||
defaultValue = "0",
|
||||
requiredMode = RequiredMode.NOT_REQUIRED)
|
||||
private int zeroPad = 0;
|
||||
|
||||
@Schema(
|
||||
description =
|
||||
"Position: 1-9 representing positions on the page (1=top-left, 2=top-center,"
|
||||
|
||||
@@ -32,8 +32,8 @@ public class AddStampRequest extends PDFWithPageNums {
|
||||
private String alphabet = "roman";
|
||||
|
||||
@Schema(
|
||||
description = "The font size of the stamp text and image",
|
||||
defaultValue = "30",
|
||||
description = "The font size of the stamp text and image in points.",
|
||||
defaultValue = "40",
|
||||
requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private float fontSize;
|
||||
|
||||
|
||||
@@ -81,6 +81,7 @@ security:
|
||||
revocation:
|
||||
mode: none # Revocation checking mode: 'none' (disabled), 'ocsp' (OCSP only), 'crl' (CRL only), 'ocsp+crl' (OCSP with CRL fallback)
|
||||
hardFail: false # Fail validation if revocation status cannot be determined (true=strict, false=soft-fail)
|
||||
xFrameOptions: DENY # X-Frame-Options header value. Options: 'DENY' (default, prevents all framing), 'SAMEORIGIN' (allows framing from same domain), 'DISABLED' (no X-Frame-Options header sent). Note: automatically set to DISABLED when login is disabled
|
||||
|
||||
premium:
|
||||
key: 00000000-0000-0000-0000-000000000000
|
||||
@@ -202,7 +203,9 @@ system:
|
||||
name: postgres # set the name of your database. Should match the name of the database you create
|
||||
customPaths:
|
||||
pipeline:
|
||||
pipelineDir: "" # Defaults to /pipeline
|
||||
watchedFoldersDir: "" # Defaults to /pipeline/watchedFolders
|
||||
watchedFoldersDirs: [] # List of watched folder directories. Defaults to watchedFoldersDir or /pipeline/watchedFolders.
|
||||
finishedFoldersDir: "" # Defaults to /pipeline/finishedFolders
|
||||
operations:
|
||||
weasyprint: "" # Defaults to /opt/venv/bin/weasyprint
|
||||
|
||||
+16
-8
@@ -85,10 +85,12 @@ class EditTableOfContentsControllerTest {
|
||||
when(mockOutlineItem.getNextSibling()).thenReturn(null);
|
||||
|
||||
// When
|
||||
List<Map<String, Object>> result = editTableOfContentsController.extractBookmarks(mockFile);
|
||||
ResponseEntity<List<Map<String, Object>>> response = editTableOfContentsController.extractBookmarks(mockFile);
|
||||
|
||||
// Then
|
||||
assertNotNull(result);
|
||||
assertNotNull(response);
|
||||
assertNotNull(response.getBody());
|
||||
List<Map<String, Object>> result = response.getBody();
|
||||
assertEquals(1, result.size());
|
||||
|
||||
Map<String, Object> bookmark = result.get(0);
|
||||
@@ -107,10 +109,12 @@ class EditTableOfContentsControllerTest {
|
||||
when(mockCatalog.getDocumentOutline()).thenReturn(null);
|
||||
|
||||
// When
|
||||
List<Map<String, Object>> result = editTableOfContentsController.extractBookmarks(mockFile);
|
||||
ResponseEntity<List<Map<String, Object>>> response = editTableOfContentsController.extractBookmarks(mockFile);
|
||||
|
||||
// Then
|
||||
assertNotNull(result);
|
||||
assertNotNull(response);
|
||||
assertNotNull(response.getBody());
|
||||
List<Map<String, Object>> result = response.getBody();
|
||||
assertTrue(result.isEmpty());
|
||||
verify(mockDocument).close();
|
||||
}
|
||||
@@ -141,10 +145,12 @@ class EditTableOfContentsControllerTest {
|
||||
when(childItem.getNextSibling()).thenReturn(null);
|
||||
|
||||
// When
|
||||
List<Map<String, Object>> result = editTableOfContentsController.extractBookmarks(mockFile);
|
||||
ResponseEntity<List<Map<String, Object>>> response = editTableOfContentsController.extractBookmarks(mockFile);
|
||||
|
||||
// Then
|
||||
assertNotNull(result);
|
||||
assertNotNull(response);
|
||||
assertNotNull(response.getBody());
|
||||
List<Map<String, Object>> result = response.getBody();
|
||||
assertEquals(1, result.size());
|
||||
|
||||
Map<String, Object> parentBookmark = result.get(0);
|
||||
@@ -177,10 +183,12 @@ class EditTableOfContentsControllerTest {
|
||||
when(mockOutlineItem.getNextSibling()).thenReturn(null);
|
||||
|
||||
// When
|
||||
List<Map<String, Object>> result = editTableOfContentsController.extractBookmarks(mockFile);
|
||||
ResponseEntity<List<Map<String, Object>>> response = editTableOfContentsController.extractBookmarks(mockFile);
|
||||
|
||||
// Then
|
||||
assertNotNull(result);
|
||||
assertNotNull(response);
|
||||
assertNotNull(response.getBody());
|
||||
List<Map<String, Object>> result = response.getBody();
|
||||
assertEquals(1, result.size());
|
||||
|
||||
Map<String, Object> bookmark = result.get(0);
|
||||
|
||||
+567
@@ -0,0 +1,567 @@
|
||||
package stirling.software.SPDF.controller.api.misc;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
import org.apache.pdfbox.pdmodel.PDDocument;
|
||||
import org.apache.pdfbox.pdmodel.PDDocumentInformation;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Nested;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.CsvSource;
|
||||
import org.junit.jupiter.params.provider.ValueSource;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
|
||||
import stirling.software.common.service.CustomPDFDocumentFactory;
|
||||
import stirling.software.common.util.TempFileManager;
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
class StampControllerTest {
|
||||
|
||||
@Mock private CustomPDFDocumentFactory pdfDocumentFactory;
|
||||
@Mock private TempFileManager tempFileManager;
|
||||
|
||||
@InjectMocks private StampController stampController;
|
||||
|
||||
private Method processStampTextMethod;
|
||||
private Method processCustomDateFormatMethod;
|
||||
|
||||
@BeforeEach
|
||||
void setUp() throws NoSuchMethodException {
|
||||
processStampTextMethod =
|
||||
StampController.class.getDeclaredMethod(
|
||||
"processStampText",
|
||||
String.class,
|
||||
int.class,
|
||||
int.class,
|
||||
String.class,
|
||||
PDDocument.class);
|
||||
processStampTextMethod.setAccessible(true);
|
||||
|
||||
processCustomDateFormatMethod =
|
||||
StampController.class.getDeclaredMethod(
|
||||
"processCustomDateFormat", String.class, LocalDateTime.class);
|
||||
processCustomDateFormatMethod.setAccessible(true);
|
||||
}
|
||||
|
||||
private String invokeProcessStampText(
|
||||
String stampText, int pageNumber, int totalPages, String filename, PDDocument document)
|
||||
throws Exception {
|
||||
try {
|
||||
return (String)
|
||||
processStampTextMethod.invoke(
|
||||
stampController, stampText, pageNumber, totalPages, filename, document);
|
||||
} catch (InvocationTargetException e) {
|
||||
throw (Exception) e.getCause();
|
||||
}
|
||||
}
|
||||
|
||||
private String invokeProcessCustomDateFormat(String format, LocalDateTime now)
|
||||
throws Exception {
|
||||
try {
|
||||
return (String) processCustomDateFormatMethod.invoke(stampController, format, now);
|
||||
} catch (InvocationTargetException e) {
|
||||
throw (Exception) e.getCause();
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
@DisplayName("Basic Variable Substitution Tests")
|
||||
class BasicVariableTests {
|
||||
|
||||
@Test
|
||||
@DisplayName("Should replace @page_number with current page")
|
||||
void testPageNumberReplacement() throws Exception {
|
||||
String result = invokeProcessStampText("Page @page_number", 5, 20, "test.pdf", null);
|
||||
assertEquals("Page 5", result);
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Should replace @total_pages with total page count")
|
||||
void testTotalPagesReplacement() throws Exception {
|
||||
String result =
|
||||
invokeProcessStampText("of @total_pages pages", 1, 100, "test.pdf", null);
|
||||
assertEquals("of 100 pages", result);
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Should replace combined page variables")
|
||||
void testCombinedPageVariables() throws Exception {
|
||||
String result =
|
||||
invokeProcessStampText(
|
||||
"Page @page_number of @total_pages", 5, 20, "test.pdf", null);
|
||||
assertEquals("Page 5 of 20", result);
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Should replace @page alias")
|
||||
void testPageAlias() throws Exception {
|
||||
String result = invokeProcessStampText("Page @page", 7, 10, "test.pdf", null);
|
||||
assertEquals("Page 7", result);
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Should replace @page_count alias for total pages")
|
||||
void testPageCountAlias() throws Exception {
|
||||
String result = invokeProcessStampText("Total: @page_count", 1, 50, "test.pdf", null);
|
||||
assertEquals("Total: 50", result);
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
@DisplayName("Filename Variable Tests")
|
||||
class FilenameTests {
|
||||
|
||||
@Test
|
||||
@DisplayName("Should replace @filename with filename without extension")
|
||||
void testFilenameWithoutExtension() throws Exception {
|
||||
String result = invokeProcessStampText("File: @filename", 1, 1, "document.pdf", null);
|
||||
assertEquals("File: document", result);
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Should replace @filename_full with full filename")
|
||||
void testFilenameWithExtension() throws Exception {
|
||||
String result =
|
||||
invokeProcessStampText("File: @filename_full", 1, 1, "document.pdf", null);
|
||||
assertEquals("File: document.pdf", result);
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Should handle filename without extension")
|
||||
void testFilenameWithoutDot() throws Exception {
|
||||
String result = invokeProcessStampText("@filename", 1, 1, "document", null);
|
||||
assertEquals("document", result);
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Should handle null filename")
|
||||
void testNullFilename() throws Exception {
|
||||
String result = invokeProcessStampText("File: @filename", 1, 1, null, null);
|
||||
assertEquals("File: ", result);
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Should handle filename with multiple dots")
|
||||
void testFilenameMultipleDots() throws Exception {
|
||||
String result = invokeProcessStampText("@filename", 1, 1, "my.document.v2.pdf", null);
|
||||
assertEquals("my.document.v2", result);
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Should handle hidden file (starts with dot)")
|
||||
void testHiddenFile() throws Exception {
|
||||
String result = invokeProcessStampText("@filename", 1, 1, ".hidden.pdf", null);
|
||||
assertEquals(".hidden", result);
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
@DisplayName("Date/Time Variable Tests")
|
||||
class DateTimeTests {
|
||||
|
||||
@Test
|
||||
@DisplayName("Should replace @date with current date")
|
||||
void testDateReplacement() throws Exception {
|
||||
String result = invokeProcessStampText("Date: @date", 1, 1, "test.pdf", null);
|
||||
assertTrue(
|
||||
result.matches("Date: \\d{4}-\\d{2}-\\d{2}"),
|
||||
"Date should match YYYY-MM-DD format");
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Should replace @time with current time")
|
||||
void testTimeReplacement() throws Exception {
|
||||
String result = invokeProcessStampText("Time: @time", 1, 1, "test.pdf", null);
|
||||
assertTrue(
|
||||
result.matches("Time: \\d{2}:\\d{2}:\\d{2}"),
|
||||
"Time should match HH:mm:ss format");
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Should replace @datetime with combined date and time")
|
||||
void testDateTimeReplacement() throws Exception {
|
||||
String result = invokeProcessStampText("@datetime", 1, 1, "test.pdf", null);
|
||||
// DateTime format: YYYY-MM-DD HH:mm:ss
|
||||
assertTrue(
|
||||
result.matches("\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}"),
|
||||
"DateTime should match YYYY-MM-DD HH:mm:ss format");
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Should replace @year with current year")
|
||||
void testYearReplacement() throws Exception {
|
||||
String result = invokeProcessStampText("© @year", 1, 1, "test.pdf", null);
|
||||
int currentYear = LocalDateTime.now().getYear();
|
||||
assertEquals("© " + currentYear, result);
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Should replace @month with zero-padded month")
|
||||
void testMonthReplacement() throws Exception {
|
||||
String result = invokeProcessStampText("Month: @month", 1, 1, "test.pdf", null);
|
||||
assertTrue(result.matches("Month: \\d{2}"), "Month should be zero-padded");
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Should replace @day with zero-padded day")
|
||||
void testDayReplacement() throws Exception {
|
||||
String result = invokeProcessStampText("Day: @day", 1, 1, "test.pdf", null);
|
||||
assertTrue(result.matches("Day: \\d{2}"), "Day should be zero-padded");
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
@DisplayName("Custom Date Format Tests")
|
||||
class CustomDateFormatTests {
|
||||
|
||||
@Test
|
||||
@DisplayName("Should handle custom date format dd/MM/yyyy")
|
||||
void testCustomDateFormatSlash() throws Exception {
|
||||
String result = invokeProcessStampText("@date{dd/MM/yyyy}", 1, 1, "test.pdf", null);
|
||||
assertTrue(
|
||||
result.matches("\\d{2}/\\d{2}/\\d{4}"),
|
||||
"Should match dd/MM/yyyy format: " + result);
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Should handle custom date format with time")
|
||||
void testCustomDateFormatWithTime() throws Exception {
|
||||
String result =
|
||||
invokeProcessStampText("@date{yyyy-MM-dd HH:mm}", 1, 1, "test.pdf", null);
|
||||
assertTrue(
|
||||
result.matches("\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}"),
|
||||
"Should match yyyy-MM-dd HH:mm format: " + result);
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Should handle multiple custom date formats in same text")
|
||||
void testMultipleCustomDateFormats() throws Exception {
|
||||
String result =
|
||||
invokeProcessStampText(
|
||||
"Start: @date{dd/MM/yyyy} End: @date{yyyy}", 1, 1, "test.pdf", null);
|
||||
assertTrue(result.contains("/"), "Should contain slash from first format");
|
||||
// Should have year twice (once with slashes, once alone)
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
@DisplayName("Custom Date Format Security Tests")
|
||||
class CustomDateFormatSecurityTests {
|
||||
|
||||
@Test
|
||||
@DisplayName("Should not match format that is too long - regex won't capture it")
|
||||
void testFormatTooLong() throws Exception {
|
||||
String longFormat = "y".repeat(51); // 51 chars, over the 50 char regex limit
|
||||
String result =
|
||||
invokeProcessStampText("@date{" + longFormat + "}", 1, 1, "test.pdf", null);
|
||||
// The CUSTOM_DATE_PATTERN only captures up to 50 chars, so this won't match
|
||||
// The @date part will be replaced by simple replacement, leaving {yyy...}
|
||||
assertTrue(
|
||||
result.contains("{"), "Should contain { because regex didn't match: " + result);
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Should reject format with unsafe characters - shell injection attempt")
|
||||
void testShellInjectionAttempt() throws Exception {
|
||||
String result =
|
||||
invokeProcessStampText("@date{yyyy-MM-dd$(rm -rf /)}", 1, 1, "test.pdf", null);
|
||||
assertEquals("[invalid format]", result);
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Should reject format with unsafe characters - semicolon")
|
||||
void testSemicolonInjection() throws Exception {
|
||||
String result = invokeProcessStampText("@date{yyyy;rm}", 1, 1, "test.pdf", null);
|
||||
assertEquals("[invalid format]", result);
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Should reject format with unsafe characters - backticks")
|
||||
void testBacktickInjection() throws Exception {
|
||||
String result = invokeProcessStampText("@date{`whoami`}", 1, 1, "test.pdf", null);
|
||||
assertEquals("[invalid format]", result);
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@ValueSource(strings = {"$(cmd)", "`cmd`", ";cmd", "|cmd", "&cmd", "<cmd", ">cmd"})
|
||||
@DisplayName("Should reject various injection attempts")
|
||||
void testVariousInjectionAttempts(String injection) throws Exception {
|
||||
String result =
|
||||
invokeProcessStampText("@date{yyyy" + injection + "}", 1, 1, "test.pdf", null);
|
||||
assertEquals("[invalid format]", result);
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Should accept valid format characters")
|
||||
void testValidFormatCharacters() throws Exception {
|
||||
// All these should be valid based on SAFE_DATE_FORMAT_PATTERN: yMdHhmsS/-:.,
|
||||
// '+EGuwWDFzZXa and space
|
||||
String result =
|
||||
invokeProcessStampText("@date{yyyy-MM-dd HH:mm:ss}", 1, 1, "test.pdf", null);
|
||||
assertFalse(
|
||||
result.startsWith("[invalid"), "Valid format should be accepted: " + result);
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Should handle invalid DateTimeFormatter pattern gracefully")
|
||||
void testInvalidFormatterPattern() throws Exception {
|
||||
LocalDateTime now = LocalDateTime.now();
|
||||
// Use 'sssss' - too many seconds digits will throw IllegalArgumentException from
|
||||
// DateTimeFormatter
|
||||
// Note: The pattern 'sssss' passes the SAFE_DATE_FORMAT_PATTERN but fails
|
||||
// DateTimeFormatter.ofPattern()
|
||||
String result = invokeProcessCustomDateFormat("sssss", now);
|
||||
assertTrue(
|
||||
result.startsWith("[invalid format:"),
|
||||
"Invalid pattern should return error message: " + result);
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
@DisplayName("Escape Sequence Tests")
|
||||
class EscapeSequenceTests {
|
||||
|
||||
@Test
|
||||
@DisplayName("Should convert @@ to literal @")
|
||||
void testDoubleAtEscape() throws Exception {
|
||||
String result =
|
||||
invokeProcessStampText("Email: test@@example.com", 1, 1, "test.pdf", null);
|
||||
assertEquals("Email: test@example.com", result);
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Should preserve @@ before variable")
|
||||
void testEscapeBeforeVariable() throws Exception {
|
||||
String result = invokeProcessStampText("@@date is @date", 1, 1, "test.pdf", null);
|
||||
// @@date should become @date, and @date should be replaced with actual date
|
||||
assertTrue(result.startsWith("@date is "), "Should start with literal @date");
|
||||
assertTrue(
|
||||
result.matches("@date is \\d{4}-\\d{2}-\\d{2}"),
|
||||
"Should have date after: " + result);
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Should handle multiple escape sequences")
|
||||
void testMultipleEscapes() throws Exception {
|
||||
String result = invokeProcessStampText("@@one @@two @@three", 1, 1, "test.pdf", null);
|
||||
assertEquals("@one @two @three", result);
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Should handle escape at end of string")
|
||||
void testEscapeAtEnd() throws Exception {
|
||||
String result = invokeProcessStampText("Contact: user@@", 1, 1, "test.pdf", null);
|
||||
assertEquals("Contact: user@", result);
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
@DisplayName("Document Metadata Tests")
|
||||
class DocumentMetadataTests {
|
||||
|
||||
@Test
|
||||
@DisplayName("Should replace @author with document author")
|
||||
void testAuthorReplacement() throws Exception {
|
||||
PDDocument doc = new PDDocument();
|
||||
PDDocumentInformation info = new PDDocumentInformation();
|
||||
info.setAuthor("John Doe");
|
||||
doc.setDocumentInformation(info);
|
||||
|
||||
try {
|
||||
String result = invokeProcessStampText("Author: @author", 1, 1, "test.pdf", doc);
|
||||
assertEquals("Author: John Doe", result);
|
||||
} finally {
|
||||
doc.close();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Should replace @title with document title")
|
||||
void testTitleReplacement() throws Exception {
|
||||
PDDocument doc = new PDDocument();
|
||||
PDDocumentInformation info = new PDDocumentInformation();
|
||||
info.setTitle("My Document Title");
|
||||
doc.setDocumentInformation(info);
|
||||
|
||||
try {
|
||||
String result = invokeProcessStampText("Title: @title", 1, 1, "test.pdf", doc);
|
||||
assertEquals("Title: My Document Title", result);
|
||||
} finally {
|
||||
doc.close();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Should replace @subject with document subject")
|
||||
void testSubjectReplacement() throws Exception {
|
||||
PDDocument doc = new PDDocument();
|
||||
PDDocumentInformation info = new PDDocumentInformation();
|
||||
info.setSubject("Important Subject");
|
||||
doc.setDocumentInformation(info);
|
||||
|
||||
try {
|
||||
String result = invokeProcessStampText("Subject: @subject", 1, 1, "test.pdf", doc);
|
||||
assertEquals("Subject: Important Subject", result);
|
||||
} finally {
|
||||
doc.close();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Should handle null metadata gracefully")
|
||||
void testNullMetadata() throws Exception {
|
||||
PDDocument doc = new PDDocument();
|
||||
// Don't set any document information
|
||||
|
||||
try {
|
||||
String result =
|
||||
invokeProcessStampText("@author @title @subject", 1, 1, "test.pdf", doc);
|
||||
assertEquals(" ", result); // All should be empty strings
|
||||
} finally {
|
||||
doc.close();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Should handle null document gracefully")
|
||||
void testNullDocument() throws Exception {
|
||||
String result = invokeProcessStampText("Author: @author", 1, 1, "test.pdf", null);
|
||||
assertEquals("Author: ", result);
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
@DisplayName("UUID Variable Tests")
|
||||
class UuidTests {
|
||||
|
||||
@Test
|
||||
@DisplayName("Should generate 8-character UUID")
|
||||
void testUuidLength() throws Exception {
|
||||
String result = invokeProcessStampText("ID: @uuid", 1, 1, "test.pdf", null);
|
||||
// UUID format: "ID: " + 8 chars
|
||||
assertEquals(12, result.length(), "Should be 'ID: ' + 8 char UUID");
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Should generate different UUIDs for each call")
|
||||
void testUuidUniqueness() throws Exception {
|
||||
String result1 = invokeProcessStampText("@uuid", 1, 1, "test.pdf", null);
|
||||
String result2 = invokeProcessStampText("@uuid", 1, 1, "test.pdf", null);
|
||||
assertNotEquals(result1, result2, "UUIDs should be unique");
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("UUID should contain only hex characters")
|
||||
void testUuidFormat() throws Exception {
|
||||
String result = invokeProcessStampText("@uuid", 1, 1, "test.pdf", null);
|
||||
assertTrue(result.matches("[0-9a-f]{8}"), "UUID should be 8 hex characters: " + result);
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
@DisplayName("Edge Cases and Error Handling")
|
||||
class EdgeCaseTests {
|
||||
|
||||
@Test
|
||||
@DisplayName("Should handle null stamp text")
|
||||
void testNullStampText() throws Exception {
|
||||
String result = invokeProcessStampText(null, 1, 1, "test.pdf", null);
|
||||
assertEquals("", result);
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Should handle empty stamp text")
|
||||
void testEmptyStampText() throws Exception {
|
||||
String result = invokeProcessStampText("", 1, 1, "test.pdf", null);
|
||||
assertEquals("", result);
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Should handle text with no variables")
|
||||
void testNoVariables() throws Exception {
|
||||
String result = invokeProcessStampText("Just plain text", 1, 1, "test.pdf", null);
|
||||
assertEquals("Just plain text", result);
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Should handle unknown variables")
|
||||
void testUnknownVariable() throws Exception {
|
||||
String result = invokeProcessStampText("@unknown_var", 1, 1, "test.pdf", null);
|
||||
assertEquals("@unknown_var", result);
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Should preserve text around variables")
|
||||
void testPreservesSurroundingText() throws Exception {
|
||||
String result =
|
||||
invokeProcessStampText("Before @page_number After", 5, 10, "test.pdf", null);
|
||||
assertEquals("Before 5 After", result);
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Should handle multiple same variables")
|
||||
void testMultipleSameVariables() throws Exception {
|
||||
String result =
|
||||
invokeProcessStampText("@page_number / @page_number", 3, 10, "test.pdf", null);
|
||||
assertEquals("3 / 3", result);
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Should handle variables adjacent to each other")
|
||||
void testAdjacentVariables() throws Exception {
|
||||
String result = invokeProcessStampText("@page@page_number", 5, 10, "test.pdf", null);
|
||||
// @page should be replaced first (it's in the order), then @page_number
|
||||
// Since @page_number is longer and comes first in replace chain, should work
|
||||
assertEquals("55", result);
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
@DisplayName("Complex Scenario Tests")
|
||||
class ComplexScenarioTests {
|
||||
|
||||
@Test
|
||||
@DisplayName("Should handle legal footer template")
|
||||
void testLegalFooterTemplate() throws Exception {
|
||||
String template = "© @year - All Rights Reserved\\n@filename - Page @page_number";
|
||||
String result = invokeProcessStampText(template, 3, 15, "contract.pdf", null);
|
||||
|
||||
int year = LocalDateTime.now().getYear();
|
||||
String expected = "© " + year + " - All Rights Reserved\\ncontract - Page 3";
|
||||
assertEquals(expected, result);
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Should handle Brazilian date format template")
|
||||
void testBrazilianDateFormat() throws Exception {
|
||||
String template = "Documento criado em @date{dd/MM/yyyy} às @time";
|
||||
String result = invokeProcessStampText(template, 1, 1, "doc.pdf", null);
|
||||
|
||||
assertTrue(result.startsWith("Documento criado em "));
|
||||
assertTrue(result.contains("/"));
|
||||
assertTrue(result.contains(":"));
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@CsvSource({
|
||||
"'Page @page_number of @total_pages', 1, 10, 'Page 1 of 10'",
|
||||
"'Page @page_number of @total_pages', 5, 20, 'Page 5 of 20'",
|
||||
"'Page @page_number of @total_pages', 100, 1000, 'Page 100 of 1000'"
|
||||
})
|
||||
@DisplayName("Should handle page number template with various values")
|
||||
void testPageNumberTemplates(String template, int page, int total, String expected)
|
||||
throws Exception {
|
||||
String result = invokeProcessStampText(template, page, total, "test.pdf", null);
|
||||
assertEquals(expected, result);
|
||||
}
|
||||
}
|
||||
}
|
||||
+2
-1
@@ -33,7 +33,8 @@ public class PersistentAuditEvent {
|
||||
private String principal;
|
||||
private String type;
|
||||
|
||||
@Lob private String data; // JSON blob
|
||||
@Column(columnDefinition = "text")
|
||||
private String data; // JSON blob
|
||||
|
||||
private Instant timestamp;
|
||||
}
|
||||
|
||||
+54
-3
@@ -8,6 +8,7 @@ import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.DependsOn;
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.core.annotation.Order;
|
||||
import org.springframework.security.authentication.ProviderManager;
|
||||
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
|
||||
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
|
||||
@@ -185,11 +186,39 @@ public class SecurityConfiguration {
|
||||
}
|
||||
|
||||
@Bean
|
||||
@Order(1)
|
||||
public SecurityFilterChain samlFilterChain(
|
||||
HttpSecurity http,
|
||||
@Lazy IPRateLimitingFilter rateLimitingFilter,
|
||||
@Lazy JwtAuthenticationFilter jwtAuthenticationFilter)
|
||||
throws Exception {
|
||||
http.securityMatcher("/saml2/**", "/login/saml2/**");
|
||||
|
||||
SessionCreationPolicy sessionPolicy =
|
||||
(securityProperties.isSaml2Active() && runningProOrHigher)
|
||||
? SessionCreationPolicy.IF_REQUIRED
|
||||
: SessionCreationPolicy.STATELESS;
|
||||
|
||||
return configureSecurity(http, rateLimitingFilter, jwtAuthenticationFilter, sessionPolicy);
|
||||
}
|
||||
|
||||
@Bean
|
||||
@Order(2)
|
||||
public SecurityFilterChain filterChain(
|
||||
HttpSecurity http,
|
||||
@Lazy IPRateLimitingFilter rateLimitingFilter,
|
||||
@Lazy JwtAuthenticationFilter jwtAuthenticationFilter)
|
||||
throws Exception {
|
||||
SessionCreationPolicy sessionPolicy = SessionCreationPolicy.STATELESS;
|
||||
return configureSecurity(http, rateLimitingFilter, jwtAuthenticationFilter, sessionPolicy);
|
||||
}
|
||||
|
||||
private SecurityFilterChain configureSecurity(
|
||||
HttpSecurity http,
|
||||
@Lazy IPRateLimitingFilter rateLimitingFilter,
|
||||
@Lazy JwtAuthenticationFilter jwtAuthenticationFilter,
|
||||
SessionCreationPolicy sessionPolicy)
|
||||
throws Exception {
|
||||
// Enable CORS only if we have configured origins
|
||||
CorsConfigurationSource corsSource = corsConfigurationSource();
|
||||
if (corsSource != null) {
|
||||
@@ -201,6 +230,30 @@ public class SecurityConfiguration {
|
||||
|
||||
http.csrf(CsrfConfigurer::disable);
|
||||
|
||||
// Configure X-Frame-Options based on settings.yml configuration
|
||||
// When login is disabled, automatically disable X-Frame-Options to allow embedding
|
||||
if (!loginEnabledValue) {
|
||||
http.headers(headers -> headers.frameOptions(frameOptions -> frameOptions.disable()));
|
||||
} else {
|
||||
String xFrameOption = securityProperties.getXFrameOptions();
|
||||
if (xFrameOption != null) {
|
||||
http.headers(
|
||||
headers -> {
|
||||
if ("DISABLED".equalsIgnoreCase(xFrameOption)) {
|
||||
headers.frameOptions(frameOptions -> frameOptions.disable());
|
||||
} else if ("SAMEORIGIN".equalsIgnoreCase(xFrameOption)) {
|
||||
headers.frameOptions(frameOptions -> frameOptions.sameOrigin());
|
||||
} else {
|
||||
// Default to DENY
|
||||
headers.frameOptions(frameOptions -> frameOptions.deny());
|
||||
}
|
||||
});
|
||||
} else {
|
||||
// If not configured, use default DENY
|
||||
http.headers(headers -> headers.frameOptions(frameOptions -> frameOptions.deny()));
|
||||
}
|
||||
}
|
||||
|
||||
if (loginEnabledValue) {
|
||||
|
||||
http.addFilterBefore(
|
||||
@@ -209,9 +262,7 @@ public class SecurityConfiguration {
|
||||
.addFilterBefore(jwtAuthenticationFilter, UserAuthenticationFilter.class);
|
||||
|
||||
http.sessionManagement(
|
||||
sessionManagement ->
|
||||
sessionManagement.sessionCreationPolicy(
|
||||
SessionCreationPolicy.STATELESS));
|
||||
sessionManagement -> sessionManagement.sessionCreationPolicy(sessionPolicy));
|
||||
http.authenticationProvider(daoAuthenticationProvider());
|
||||
http.requestCache(requestCache -> requestCache.requestCache(new NullRequestCache()));
|
||||
|
||||
|
||||
+55
@@ -186,6 +186,13 @@ public class AdminSettingsController {
|
||||
+ HtmlUtils.htmlEscape(key)));
|
||||
}
|
||||
|
||||
// Validate pipeline path settings
|
||||
String validationError = validatePipelinePathSetting(key, value);
|
||||
if (validationError != null) {
|
||||
return ResponseEntity.badRequest()
|
||||
.body(Map.of("error", HtmlUtils.htmlEscape(validationError)));
|
||||
}
|
||||
|
||||
log.info("Admin updating setting: {} = {}", key, value);
|
||||
GeneralUtils.saveKeyToSettings(key, value);
|
||||
|
||||
@@ -642,6 +649,54 @@ public class AdminSettingsController {
|
||||
return true;
|
||||
}
|
||||
|
||||
private String validatePipelinePathSetting(String key, Object value) {
|
||||
// Validate pipeline path settings
|
||||
if (key.startsWith("system.customPaths.pipeline.watchedFoldersDirs")
|
||||
&& value instanceof java.util.List) {
|
||||
@SuppressWarnings("unchecked")
|
||||
java.util.List<String> paths = (java.util.List<String>) value;
|
||||
|
||||
// Check for empty or all-blank paths
|
||||
if (paths.isEmpty()) {
|
||||
return null; // Empty is OK, will use default
|
||||
}
|
||||
|
||||
// Validate each path
|
||||
java.util.Set<String> normalizedPaths = new java.util.HashSet<>();
|
||||
for (String path : paths) {
|
||||
if (path != null && !path.trim().isEmpty()) {
|
||||
try {
|
||||
java.nio.file.Path normalized =
|
||||
java.nio.file.Paths.get(path.trim()).toAbsolutePath().normalize();
|
||||
String normalizedStr = normalized.toString();
|
||||
|
||||
// Check for duplicates
|
||||
if (normalizedPaths.contains(normalizedStr)) {
|
||||
return "Duplicate path detected: " + path;
|
||||
}
|
||||
normalizedPaths.add(normalizedStr);
|
||||
} catch (java.nio.file.InvalidPathException e) {
|
||||
return "Invalid path: " + path + " - " + e.getMessage();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check for overlapping paths
|
||||
java.util.List<String> pathList = new java.util.ArrayList<>(normalizedPaths);
|
||||
for (int i = 0; i < pathList.size(); i++) {
|
||||
java.nio.file.Path path1 = java.nio.file.Paths.get(pathList.get(i));
|
||||
for (int j = i + 1; j < pathList.size(); j++) {
|
||||
java.nio.file.Path path2 = java.nio.file.Paths.get(pathList.get(j));
|
||||
if (path1.startsWith(path2) || path2.startsWith(path1)) {
|
||||
return "Overlapping paths detected: " + path1 + " and " + path2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null; // Valid
|
||||
}
|
||||
|
||||
private Object getSettingByKey(String key) {
|
||||
if (key == null || key.trim().isEmpty()) {
|
||||
return null;
|
||||
|
||||
+4
-1
@@ -286,7 +286,10 @@ public class AuthController {
|
||||
|
||||
log.debug("Token refreshed for user: {}", username);
|
||||
|
||||
return ResponseEntity.ok(Map.of("access_token", newToken, "expires_in", 3600));
|
||||
return ResponseEntity.ok(
|
||||
Map.of(
|
||||
"user", buildUserResponse(user),
|
||||
"session", Map.of("access_token", newToken, "expires_in", 3600)));
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error("Token refresh error", e);
|
||||
|
||||
@@ -87,7 +87,6 @@ public class User implements UserDetails, Serializable {
|
||||
|
||||
@ElementCollection
|
||||
@MapKeyColumn(name = "setting_key")
|
||||
@Lob
|
||||
@Column(name = "setting_value", columnDefinition = "text")
|
||||
@CollectionTable(name = "user_settings", joinColumns = @JoinColumn(name = "user_id"))
|
||||
@JsonIgnore
|
||||
|
||||
-135
@@ -1,135 +0,0 @@
|
||||
package stirling.software.proprietary.security.saml2;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.security.saml2.provider.service.authentication.Saml2PostAuthenticationRequest;
|
||||
import org.springframework.security.saml2.provider.service.registration.RelyingPartyRegistration;
|
||||
import org.springframework.security.saml2.provider.service.registration.RelyingPartyRegistrationRepository;
|
||||
import org.springframework.security.saml2.provider.service.web.Saml2AuthenticationRequestRepository;
|
||||
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import stirling.software.proprietary.security.service.JwtServiceInterface;
|
||||
|
||||
@Slf4j
|
||||
public class JwtSaml2AuthenticationRequestRepository
|
||||
implements Saml2AuthenticationRequestRepository<Saml2PostAuthenticationRequest> {
|
||||
private final Map<String, String> tokenStore;
|
||||
private final JwtServiceInterface jwtService;
|
||||
private final RelyingPartyRegistrationRepository relyingPartyRegistrationRepository;
|
||||
|
||||
private static final String SAML_REQUEST_TOKEN = "stirling_saml_request_token";
|
||||
|
||||
public JwtSaml2AuthenticationRequestRepository(
|
||||
Map<String, String> tokenStore,
|
||||
JwtServiceInterface jwtService,
|
||||
RelyingPartyRegistrationRepository relyingPartyRegistrationRepository) {
|
||||
this.tokenStore = tokenStore;
|
||||
this.jwtService = jwtService;
|
||||
this.relyingPartyRegistrationRepository = relyingPartyRegistrationRepository;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void saveAuthenticationRequest(
|
||||
Saml2PostAuthenticationRequest authRequest,
|
||||
HttpServletRequest request,
|
||||
HttpServletResponse response) {
|
||||
if (!jwtService.isJwtEnabled()) {
|
||||
log.debug("V2 is not enabled, skipping SAMLRequest token storage");
|
||||
return;
|
||||
}
|
||||
|
||||
if (authRequest == null) {
|
||||
removeAuthenticationRequest(request, response);
|
||||
return;
|
||||
}
|
||||
|
||||
Map<String, Object> claims = serializeSamlRequest(authRequest);
|
||||
String token = jwtService.generateToken("", claims);
|
||||
String relayState = authRequest.getRelayState();
|
||||
|
||||
tokenStore.put(relayState, token);
|
||||
request.setAttribute(SAML_REQUEST_TOKEN, relayState);
|
||||
response.addHeader(SAML_REQUEST_TOKEN, relayState);
|
||||
|
||||
log.debug("Saved SAMLRequest token with RelayState: {}", relayState);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Saml2PostAuthenticationRequest loadAuthenticationRequest(HttpServletRequest request) {
|
||||
String token = extractTokenFromStore(request);
|
||||
|
||||
if (token == null) {
|
||||
log.debug("No SAMLResponse token found in RelayState");
|
||||
return null;
|
||||
}
|
||||
|
||||
Map<String, Object> claims = jwtService.extractClaims(token);
|
||||
return deserializeSamlRequest(claims);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Saml2PostAuthenticationRequest removeAuthenticationRequest(
|
||||
HttpServletRequest request, HttpServletResponse response) {
|
||||
Saml2PostAuthenticationRequest authRequest = loadAuthenticationRequest(request);
|
||||
|
||||
String relayStateId = request.getParameter("RelayState");
|
||||
if (relayStateId != null) {
|
||||
tokenStore.remove(relayStateId);
|
||||
log.debug("Removed SAMLRequest token for RelayState ID: {}", relayStateId);
|
||||
}
|
||||
|
||||
return authRequest;
|
||||
}
|
||||
|
||||
private String extractTokenFromStore(HttpServletRequest request) {
|
||||
String authnRequestId = request.getParameter("RelayState");
|
||||
|
||||
if (authnRequestId != null && !authnRequestId.isEmpty()) {
|
||||
String token = tokenStore.get(authnRequestId);
|
||||
|
||||
if (token != null) {
|
||||
tokenStore.remove(authnRequestId);
|
||||
log.debug("Retrieved SAMLRequest token for RelayState ID: {}", authnRequestId);
|
||||
return token;
|
||||
} else {
|
||||
log.warn("No SAMLRequest token found for RelayState ID: {}", authnRequestId);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private Map<String, Object> serializeSamlRequest(Saml2PostAuthenticationRequest authRequest) {
|
||||
Map<String, Object> claims = new HashMap<>();
|
||||
|
||||
claims.put("id", authRequest.getId());
|
||||
claims.put("relyingPartyRegistrationId", authRequest.getRelyingPartyRegistrationId());
|
||||
claims.put("authenticationRequestUri", authRequest.getAuthenticationRequestUri());
|
||||
claims.put("samlRequest", authRequest.getSamlRequest());
|
||||
claims.put("relayState", authRequest.getRelayState());
|
||||
|
||||
return claims;
|
||||
}
|
||||
|
||||
private Saml2PostAuthenticationRequest deserializeSamlRequest(Map<String, Object> claims) {
|
||||
String relyingPartyRegistrationId = (String) claims.get("relyingPartyRegistrationId");
|
||||
RelyingPartyRegistration relyingPartyRegistration =
|
||||
relyingPartyRegistrationRepository.findByRegistrationId(relyingPartyRegistrationId);
|
||||
|
||||
if (relyingPartyRegistration == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return Saml2PostAuthenticationRequest.withRelyingPartyRegistration(relyingPartyRegistration)
|
||||
.id((String) claims.get("id"))
|
||||
.authenticationRequestUri((String) claims.get("authenticationRequestUri"))
|
||||
.samlRequest((String) claims.get("samlRequest"))
|
||||
.relayState((String) claims.get("relayState"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
+3
-39
@@ -3,7 +3,6 @@ package stirling.software.proprietary.security.saml2;
|
||||
import java.security.cert.X509Certificate;
|
||||
import java.util.Collections;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import org.opensaml.saml.saml2.core.AuthnRequest;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
@@ -12,12 +11,10 @@ import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.security.saml2.core.Saml2X509Credential;
|
||||
import org.springframework.security.saml2.core.Saml2X509Credential.Saml2X509CredentialType;
|
||||
import org.springframework.security.saml2.provider.service.authentication.Saml2PostAuthenticationRequest;
|
||||
import org.springframework.security.saml2.provider.service.registration.InMemoryRelyingPartyRegistrationRepository;
|
||||
import org.springframework.security.saml2.provider.service.registration.RelyingPartyRegistration;
|
||||
import org.springframework.security.saml2.provider.service.registration.RelyingPartyRegistrationRepository;
|
||||
import org.springframework.security.saml2.provider.service.registration.Saml2MessageBinding;
|
||||
import org.springframework.security.saml2.provider.service.web.Saml2AuthenticationRequestRepository;
|
||||
import org.springframework.security.saml2.provider.service.web.authentication.OpenSaml4AuthenticationRequestResolver;
|
||||
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
@@ -27,7 +24,6 @@ import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import stirling.software.common.model.ApplicationProperties;
|
||||
import stirling.software.common.model.ApplicationProperties.Security.SAML2;
|
||||
import stirling.software.proprietary.security.service.JwtServiceInterface;
|
||||
|
||||
@Configuration
|
||||
@Slf4j
|
||||
@@ -153,22 +149,10 @@ public class Saml2Configuration {
|
||||
return new InMemoryRelyingPartyRegistrationRepository(rp);
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnProperty(name = "security.saml2.enabled", havingValue = "true")
|
||||
public Saml2AuthenticationRequestRepository<Saml2PostAuthenticationRequest>
|
||||
saml2AuthenticationRequestRepository(
|
||||
JwtServiceInterface jwtService,
|
||||
RelyingPartyRegistrationRepository relyingPartyRegistrationRepository) {
|
||||
return new JwtSaml2AuthenticationRequestRepository(
|
||||
new ConcurrentHashMap<>(), jwtService, relyingPartyRegistrationRepository);
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnProperty(name = "security.saml2.enabled", havingValue = "true")
|
||||
public OpenSaml4AuthenticationRequestResolver authenticationRequestResolver(
|
||||
RelyingPartyRegistrationRepository relyingPartyRegistrationRepository,
|
||||
Saml2AuthenticationRequestRepository<Saml2PostAuthenticationRequest>
|
||||
saml2AuthenticationRequestRepository) {
|
||||
RelyingPartyRegistrationRepository relyingPartyRegistrationRepository) {
|
||||
OpenSaml4AuthenticationRequestResolver resolver =
|
||||
new OpenSaml4AuthenticationRequestResolver(relyingPartyRegistrationRepository);
|
||||
|
||||
@@ -176,30 +160,10 @@ public class Saml2Configuration {
|
||||
customizer -> {
|
||||
HttpServletRequest request = customizer.getRequest();
|
||||
AuthnRequest authnRequest = customizer.getAuthnRequest();
|
||||
Saml2PostAuthenticationRequest saml2AuthenticationRequest =
|
||||
saml2AuthenticationRequestRepository.loadAuthenticationRequest(request);
|
||||
|
||||
if (saml2AuthenticationRequest != null) {
|
||||
String sessionId = request.getSession(false).getId();
|
||||
// Generate a unique AuthnRequest ID for each SAML request
|
||||
authnRequest.setID("ARQ" + UUID.randomUUID().toString().substring(1));
|
||||
|
||||
log.debug(
|
||||
"Retrieving SAML 2 authentication request ID from the current HTTP session {}",
|
||||
sessionId);
|
||||
|
||||
String authenticationRequestId = saml2AuthenticationRequest.getId();
|
||||
|
||||
if (!authenticationRequestId.isBlank()) {
|
||||
authnRequest.setID(authenticationRequestId);
|
||||
} else {
|
||||
log.warn(
|
||||
"No authentication request found for HTTP session {}. Generating new ID",
|
||||
sessionId);
|
||||
authnRequest.setID("ARQ" + UUID.randomUUID().toString().substring(1));
|
||||
}
|
||||
} else {
|
||||
log.debug("Generating new authentication request ID");
|
||||
authnRequest.setID("ARQ" + UUID.randomUUID().toString().substring(1));
|
||||
}
|
||||
logAuthnRequestDetails(authnRequest);
|
||||
logHttpRequestDetails(request);
|
||||
});
|
||||
|
||||
+1
@@ -67,6 +67,7 @@ public class UserService implements UserServiceInterface {
|
||||
|
||||
private final ApplicationProperties.Security.OAUTH2 oAuth2;
|
||||
|
||||
@Transactional
|
||||
public void processSSOPostLogin(
|
||||
String username,
|
||||
String ssoProviderId,
|
||||
|
||||
+3
-2
@@ -182,8 +182,9 @@ class AuthControllerLoginTest {
|
||||
|
||||
mockMvc.perform(post("/api/v1/auth/refresh"))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.access_token").value("new-token"))
|
||||
.andExpect(jsonPath("$.expires_in").value(3600));
|
||||
.andExpect(jsonPath("$.user").exists())
|
||||
.andExpect(jsonPath("$.session.access_token").value("new-token"))
|
||||
.andExpect(jsonPath("$.session.expires_in").value(3600));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
-243
@@ -1,243 +0,0 @@
|
||||
package stirling.software.proprietary.security.saml2;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
import static org.mockito.ArgumentMatchers.anyMap;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.NullAndEmptySource;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
import org.springframework.mock.web.MockHttpServletRequest;
|
||||
import org.springframework.mock.web.MockHttpServletResponse;
|
||||
import org.springframework.security.saml2.provider.service.authentication.Saml2PostAuthenticationRequest;
|
||||
import org.springframework.security.saml2.provider.service.registration.AssertingPartyMetadata;
|
||||
import org.springframework.security.saml2.provider.service.registration.RelyingPartyRegistration;
|
||||
import org.springframework.security.saml2.provider.service.registration.RelyingPartyRegistrationRepository;
|
||||
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
|
||||
import stirling.software.proprietary.security.service.JwtServiceInterface;
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
class JwtSaml2AuthenticationRequestRepositoryTest {
|
||||
|
||||
private static final String SAML_REQUEST_TOKEN = "stirling_saml_request_token";
|
||||
|
||||
private Map<String, String> tokenStore;
|
||||
|
||||
@Mock private JwtServiceInterface jwtService;
|
||||
|
||||
@Mock private RelyingPartyRegistrationRepository relyingPartyRegistrationRepository;
|
||||
|
||||
private JwtSaml2AuthenticationRequestRepository jwtSaml2AuthenticationRequestRepository;
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
tokenStore = new ConcurrentHashMap<>();
|
||||
jwtSaml2AuthenticationRequestRepository =
|
||||
new JwtSaml2AuthenticationRequestRepository(
|
||||
tokenStore, jwtService, relyingPartyRegistrationRepository);
|
||||
}
|
||||
|
||||
@Test
|
||||
void saveAuthenticationRequest() {
|
||||
var authRequest = mock(Saml2PostAuthenticationRequest.class);
|
||||
var request = mock(MockHttpServletRequest.class);
|
||||
var response = mock(MockHttpServletResponse.class);
|
||||
String token = "testToken";
|
||||
String id = "testId";
|
||||
String relayState = "testRelayState";
|
||||
String authnRequestUri = "example.com/authnRequest";
|
||||
String samlRequest = "testSamlRequest";
|
||||
String relyingPartyRegistrationId = "stirling-pdf";
|
||||
|
||||
when(jwtService.isJwtEnabled()).thenReturn(true);
|
||||
when(authRequest.getRelayState()).thenReturn(relayState);
|
||||
when(authRequest.getId()).thenReturn(id);
|
||||
when(authRequest.getAuthenticationRequestUri()).thenReturn(authnRequestUri);
|
||||
when(authRequest.getSamlRequest()).thenReturn(samlRequest);
|
||||
when(authRequest.getRelyingPartyRegistrationId()).thenReturn(relyingPartyRegistrationId);
|
||||
when(jwtService.generateToken(eq(""), anyMap())).thenReturn(token);
|
||||
|
||||
jwtSaml2AuthenticationRequestRepository.saveAuthenticationRequest(
|
||||
authRequest, request, response);
|
||||
|
||||
verify(request).setAttribute(SAML_REQUEST_TOKEN, relayState);
|
||||
verify(response).addHeader(SAML_REQUEST_TOKEN, relayState);
|
||||
}
|
||||
|
||||
@Test
|
||||
void saveAuthenticationRequestWithNullRequest() {
|
||||
var request = mock(MockHttpServletRequest.class);
|
||||
var response = mock(MockHttpServletResponse.class);
|
||||
|
||||
jwtSaml2AuthenticationRequestRepository.saveAuthenticationRequest(null, request, response);
|
||||
|
||||
assertTrue(tokenStore.isEmpty());
|
||||
}
|
||||
|
||||
@Test
|
||||
void loadAuthenticationRequest() {
|
||||
var request = mock(MockHttpServletRequest.class);
|
||||
var relyingPartyRegistration = mock(RelyingPartyRegistration.class);
|
||||
var assertingPartyMetadata = mock(AssertingPartyMetadata.class);
|
||||
String relayState = "testRelayState";
|
||||
String token = "testToken";
|
||||
Map<String, Object> claims =
|
||||
Map.of(
|
||||
"id", "testId",
|
||||
"relyingPartyRegistrationId", "stirling-pdf",
|
||||
"authenticationRequestUri", "example.com/authnRequest",
|
||||
"samlRequest", "testSamlRequest",
|
||||
"relayState", relayState);
|
||||
|
||||
when(request.getParameter("RelayState")).thenReturn(relayState);
|
||||
when(jwtService.extractClaims(token)).thenReturn(claims);
|
||||
when(relyingPartyRegistrationRepository.findByRegistrationId("stirling-pdf"))
|
||||
.thenReturn(relyingPartyRegistration);
|
||||
when(relyingPartyRegistration.getRegistrationId()).thenReturn("stirling-pdf");
|
||||
when(relyingPartyRegistration.getAssertingPartyMetadata())
|
||||
.thenReturn(assertingPartyMetadata);
|
||||
when(assertingPartyMetadata.getSingleSignOnServiceLocation())
|
||||
.thenReturn("https://example.com/sso");
|
||||
tokenStore.put(relayState, token);
|
||||
|
||||
var result = jwtSaml2AuthenticationRequestRepository.loadAuthenticationRequest(request);
|
||||
|
||||
assertNotNull(result);
|
||||
assertFalse(tokenStore.containsKey(relayState));
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@NullAndEmptySource
|
||||
void loadAuthenticationRequestWithInvalidRelayState(String relayState) {
|
||||
var request = mock(MockHttpServletRequest.class);
|
||||
when(request.getParameter("RelayState")).thenReturn(relayState);
|
||||
|
||||
var result = jwtSaml2AuthenticationRequestRepository.loadAuthenticationRequest(request);
|
||||
|
||||
assertNull(result);
|
||||
}
|
||||
|
||||
@Test
|
||||
void loadAuthenticationRequestWithNonExistentToken() {
|
||||
var request = mock(MockHttpServletRequest.class);
|
||||
when(request.getParameter("RelayState")).thenReturn("nonExistentRelayState");
|
||||
|
||||
var result = jwtSaml2AuthenticationRequestRepository.loadAuthenticationRequest(request);
|
||||
|
||||
assertNull(result);
|
||||
}
|
||||
|
||||
@Test
|
||||
void loadAuthenticationRequestWithNullRelyingPartyRegistration() {
|
||||
var request = mock(MockHttpServletRequest.class);
|
||||
String relayState = "testRelayState";
|
||||
String token = "testToken";
|
||||
Map<String, Object> claims =
|
||||
Map.of(
|
||||
"id", "testId",
|
||||
"relyingPartyRegistrationId", "stirling-pdf",
|
||||
"authenticationRequestUri", "example.com/authnRequest",
|
||||
"samlRequest", "testSamlRequest",
|
||||
"relayState", relayState);
|
||||
|
||||
when(request.getParameter("RelayState")).thenReturn(relayState);
|
||||
when(jwtService.extractClaims(token)).thenReturn(claims);
|
||||
when(relyingPartyRegistrationRepository.findByRegistrationId("stirling-pdf"))
|
||||
.thenReturn(null);
|
||||
tokenStore.put(relayState, token);
|
||||
|
||||
var result = jwtSaml2AuthenticationRequestRepository.loadAuthenticationRequest(request);
|
||||
|
||||
assertNull(result);
|
||||
}
|
||||
|
||||
@Test
|
||||
void removeAuthenticationRequest() {
|
||||
var request = mock(HttpServletRequest.class);
|
||||
var response = mock(HttpServletResponse.class);
|
||||
var relyingPartyRegistration = mock(RelyingPartyRegistration.class);
|
||||
var assertingPartyMetadata = mock(AssertingPartyMetadata.class);
|
||||
String relayState = "testRelayState";
|
||||
String token = "testToken";
|
||||
Map<String, Object> claims =
|
||||
Map.of(
|
||||
"id", "testId",
|
||||
"relyingPartyRegistrationId", "stirling-pdf",
|
||||
"authenticationRequestUri", "example.com/authnRequest",
|
||||
"samlRequest", "testSamlRequest",
|
||||
"relayState", relayState);
|
||||
|
||||
when(request.getParameter("RelayState")).thenReturn(relayState);
|
||||
when(jwtService.extractClaims(token)).thenReturn(claims);
|
||||
when(relyingPartyRegistrationRepository.findByRegistrationId("stirling-pdf"))
|
||||
.thenReturn(relyingPartyRegistration);
|
||||
when(relyingPartyRegistration.getRegistrationId()).thenReturn("stirling-pdf");
|
||||
when(relyingPartyRegistration.getAssertingPartyMetadata())
|
||||
.thenReturn(assertingPartyMetadata);
|
||||
when(assertingPartyMetadata.getSingleSignOnServiceLocation())
|
||||
.thenReturn("https://example.com/sso");
|
||||
tokenStore.put(relayState, token);
|
||||
|
||||
var result =
|
||||
jwtSaml2AuthenticationRequestRepository.removeAuthenticationRequest(
|
||||
request, response);
|
||||
|
||||
assertNotNull(result);
|
||||
assertFalse(tokenStore.containsKey(relayState));
|
||||
}
|
||||
|
||||
@Test
|
||||
void removeAuthenticationRequestWithNullRelayState() {
|
||||
var request = mock(HttpServletRequest.class);
|
||||
var response = mock(HttpServletResponse.class);
|
||||
when(request.getParameter("RelayState")).thenReturn(null);
|
||||
|
||||
var result =
|
||||
jwtSaml2AuthenticationRequestRepository.removeAuthenticationRequest(
|
||||
request, response);
|
||||
|
||||
assertNull(result);
|
||||
}
|
||||
|
||||
@Test
|
||||
void removeAuthenticationRequestWithNonExistentToken() {
|
||||
var request = mock(HttpServletRequest.class);
|
||||
var response = mock(HttpServletResponse.class);
|
||||
when(request.getParameter("RelayState")).thenReturn("nonExistentRelayState");
|
||||
|
||||
var result =
|
||||
jwtSaml2AuthenticationRequestRepository.removeAuthenticationRequest(
|
||||
request, response);
|
||||
|
||||
assertNull(result);
|
||||
}
|
||||
|
||||
@Test
|
||||
void removeAuthenticationRequestWithOnlyRelayState() {
|
||||
var request = mock(HttpServletRequest.class);
|
||||
var response = mock(HttpServletResponse.class);
|
||||
String relayState = "testRelayState";
|
||||
|
||||
when(request.getParameter("RelayState")).thenReturn(relayState);
|
||||
|
||||
var result =
|
||||
jwtSaml2AuthenticationRequestRepository.removeAuthenticationRequest(
|
||||
request, response);
|
||||
|
||||
assertNull(result);
|
||||
assertFalse(tokenStore.containsKey(relayState));
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -67,7 +67,7 @@ springBoot {
|
||||
|
||||
allprojects {
|
||||
group = 'stirling.software'
|
||||
version = '2.4.0'
|
||||
version = '2.4.3'
|
||||
|
||||
configurations.configureEach {
|
||||
exclude group: 'commons-logging', module: 'commons-logging'
|
||||
@@ -537,4 +537,4 @@ tasks.register('buildRestartHelper', Jar) {
|
||||
doLast {
|
||||
println "restart-helper.jar created at: ${destinationDirectory.get()}/restart-helper.jar"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Generated
+259
-217
@@ -11,27 +11,28 @@
|
||||
"dependencies": {
|
||||
"@atlaskit/pragmatic-drag-and-drop": "^1.7.7",
|
||||
"@dnd-kit/core": "^6.3.1",
|
||||
"@embedpdf/core": "^1.5.0",
|
||||
"@embedpdf/engines": "^1.5.0",
|
||||
"@embedpdf/plugin-annotation": "^1.5.0",
|
||||
"@embedpdf/plugin-bookmark": "^1.5.0",
|
||||
"@embedpdf/plugin-export": "^1.5.0",
|
||||
"@embedpdf/plugin-history": "^1.5.0",
|
||||
"@embedpdf/plugin-interaction-manager": "^1.5.0",
|
||||
"@embedpdf/plugin-loader": "^1.5.0",
|
||||
"@embedpdf/plugin-pan": "^1.5.0",
|
||||
"@embedpdf/plugin-print": "^1.5.0",
|
||||
"@embedpdf/plugin-redaction": "^1.5.0",
|
||||
"@embedpdf/plugin-render": "^1.5.0",
|
||||
"@embedpdf/plugin-rotate": "^1.5.0",
|
||||
"@embedpdf/plugin-scroll": "^1.5.0",
|
||||
"@embedpdf/plugin-search": "^1.5.0",
|
||||
"@embedpdf/plugin-selection": "^1.5.0",
|
||||
"@embedpdf/plugin-spread": "^1.5.0",
|
||||
"@embedpdf/plugin-thumbnail": "^1.5.0",
|
||||
"@embedpdf/plugin-tiling": "^1.5.0",
|
||||
"@embedpdf/plugin-viewport": "^1.5.0",
|
||||
"@embedpdf/plugin-zoom": "^1.5.0",
|
||||
"@embedpdf/core": "^2.3.0",
|
||||
"@embedpdf/engines": "^2.3.0",
|
||||
"@embedpdf/models": "^2.3.0",
|
||||
"@embedpdf/plugin-annotation": "^2.3.0",
|
||||
"@embedpdf/plugin-bookmark": "^2.3.0",
|
||||
"@embedpdf/plugin-document-manager": "^2.3.0",
|
||||
"@embedpdf/plugin-export": "^2.3.0",
|
||||
"@embedpdf/plugin-history": "^2.3.0",
|
||||
"@embedpdf/plugin-interaction-manager": "^2.3.0",
|
||||
"@embedpdf/plugin-pan": "^2.3.0",
|
||||
"@embedpdf/plugin-print": "^2.3.0",
|
||||
"@embedpdf/plugin-redaction": "^2.3.0",
|
||||
"@embedpdf/plugin-render": "^2.3.0",
|
||||
"@embedpdf/plugin-rotate": "^2.3.0",
|
||||
"@embedpdf/plugin-scroll": "^2.3.0",
|
||||
"@embedpdf/plugin-search": "^2.3.0",
|
||||
"@embedpdf/plugin-selection": "^2.3.0",
|
||||
"@embedpdf/plugin-spread": "^2.3.0",
|
||||
"@embedpdf/plugin-thumbnail": "^2.3.0",
|
||||
"@embedpdf/plugin-tiling": "^2.3.0",
|
||||
"@embedpdf/plugin-viewport": "^2.3.0",
|
||||
"@embedpdf/plugin-zoom": "^2.3.0",
|
||||
"@emotion/react": "^11.14.0",
|
||||
"@emotion/styled": "^11.14.1",
|
||||
"@iconify/react": "^6.0.2",
|
||||
@@ -47,13 +48,13 @@
|
||||
"@supabase/supabase-js": "^2.47.13",
|
||||
"@tailwindcss/postcss": "^4.1.13",
|
||||
"@tanstack/react-virtual": "^3.13.12",
|
||||
"@tauri-apps/api": "^2.5.0",
|
||||
"@tauri-apps/plugin-fs": "^2.4.0",
|
||||
"@tauri-apps/plugin-http": "^2.5.4",
|
||||
"@tauri-apps/plugin-shell": "^2.3.3",
|
||||
"@tauri-apps/api": "^2.9.1",
|
||||
"@tauri-apps/plugin-fs": "^2.4.5",
|
||||
"@tauri-apps/plugin-http": "^2.5.6",
|
||||
"@tauri-apps/plugin-shell": "^2.3.4",
|
||||
"autoprefixer": "^10.4.21",
|
||||
"axios": "^1.12.2",
|
||||
"globals": "^17.0.0",
|
||||
"axios": "^1.13.2",
|
||||
"globals": "^17.1.0",
|
||||
"i18next": "^25.5.2",
|
||||
"i18next-browser-languagedetector": "^8.2.0",
|
||||
"jszip": "^3.10.1",
|
||||
@@ -62,7 +63,7 @@
|
||||
"pdfjs-dist": "^5.4.149",
|
||||
"peerjs": "^1.5.5",
|
||||
"posthog-js": "^1.268.0",
|
||||
"qrcode.react": "^4.1.0",
|
||||
"qrcode.react": "^4.2.0",
|
||||
"react": "^19.1.1",
|
||||
"react-dom": "^19.1.1",
|
||||
"react-i18next": "^15.7.3",
|
||||
@@ -75,10 +76,10 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@eslint/js": "^9.36.0",
|
||||
"@iconify-json/material-symbols": "^1.2.48",
|
||||
"@iconify/utils": "^3.0.2",
|
||||
"@iconify-json/material-symbols": "^1.2.53",
|
||||
"@iconify/utils": "^3.1.0",
|
||||
"@playwright/test": "^1.55.0",
|
||||
"@tauri-apps/cli": "^2.5.0",
|
||||
"@tauri-apps/cli": "^2.9.6",
|
||||
"@testing-library/dom": "^10.4.1",
|
||||
"@testing-library/jest-dom": "^6.8.0",
|
||||
"@testing-library/react": "^16.3.0",
|
||||
@@ -552,13 +553,13 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@embedpdf/core": {
|
||||
"version": "1.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@embedpdf/core/-/core-1.5.0.tgz",
|
||||
"integrity": "sha512-Yrh9XoVaT8cUgzgqpJ7hx5wg6BqQrCFirqqlSwVb+Ly9oNn4fZbR9GycIWmzJOU5XBnaOJjXfQSaDyoNP0woNA==",
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/@embedpdf/core/-/core-2.3.0.tgz",
|
||||
"integrity": "sha512-aPD7lNSCOLc5Nos9xGA3qAT5jFZdrTT7IVcpxtM1BOKa1FI0XmotJ8vgzcRxH/FLwUASC4xwR9QxzTKp2aLsZQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@embedpdf/engines": "1.5.0",
|
||||
"@embedpdf/models": "1.5.0"
|
||||
"@embedpdf/engines": "2.3.0",
|
||||
"@embedpdf/models": "2.3.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"preact": "^10.26.4",
|
||||
@@ -569,13 +570,20 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@embedpdf/engines": {
|
||||
"version": "1.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@embedpdf/engines/-/engines-1.5.0.tgz",
|
||||
"integrity": "sha512-/GzhjHFHWfOaX7vjgFJX/pyq668wYjoda1bZ9MpwF/EF000Wwy2Q0AOhprjldPFz8ASKjwKwqsXmaqrK99yOAQ==",
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/@embedpdf/engines/-/engines-2.3.0.tgz",
|
||||
"integrity": "sha512-QxNY58E2HgNgnbsTt5TnDUNvKoyabkf5IniGsiN5+rx6f4SFDpCnz3h1VJxNReWDyn9e16QlkUfgXX0qQWd3iQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@embedpdf/models": "1.5.0",
|
||||
"@embedpdf/pdfium": "1.5.0"
|
||||
"@embedpdf/fonts-arabic": "1.0.0",
|
||||
"@embedpdf/fonts-hebrew": "1.0.0",
|
||||
"@embedpdf/fonts-jp": "1.0.0",
|
||||
"@embedpdf/fonts-kr": "1.0.0",
|
||||
"@embedpdf/fonts-latin": "1.0.0",
|
||||
"@embedpdf/fonts-sc": "1.0.0",
|
||||
"@embedpdf/fonts-tc": "1.0.0",
|
||||
"@embedpdf/models": "2.3.0",
|
||||
"@embedpdf/pdfium": "2.3.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"preact": "^10.26.4",
|
||||
@@ -585,64 +593,125 @@
|
||||
"vue": ">=3.2.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@embedpdf/fonts-arabic": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@embedpdf/fonts-arabic/-/fonts-arabic-1.0.0.tgz",
|
||||
"integrity": "sha512-SnGvQb+LwPZQO2WjjvlmXrJZolJUfLYbLZQSaYUw1vrQyMyJKT4LewvJGG+hZ+Yz2fz7OMIQ+4Gc98mGODZtOg==",
|
||||
"license": "OFL-1.1"
|
||||
},
|
||||
"node_modules/@embedpdf/fonts-hebrew": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@embedpdf/fonts-hebrew/-/fonts-hebrew-1.0.0.tgz",
|
||||
"integrity": "sha512-5HVAKGL7VqPeTxxADDrSqAFBxfmAXdP8fIqrPwJIKkqdK2643bOer8CqnnpO3/nPoFhkzxhttWMB9BGiqSW62w==",
|
||||
"license": "OFL-1.1"
|
||||
},
|
||||
"node_modules/@embedpdf/fonts-jp": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@embedpdf/fonts-jp/-/fonts-jp-1.0.0.tgz",
|
||||
"integrity": "sha512-BY2tv/mcICUUKf+M/bizf3RU65PMqKClJ/e5o9mgMibxyML0OQvEDwYMRPODQkKgJKXCO3ScHmVvcmXp6kt+fA==",
|
||||
"license": "OFL-1.1"
|
||||
},
|
||||
"node_modules/@embedpdf/fonts-kr": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@embedpdf/fonts-kr/-/fonts-kr-1.0.0.tgz",
|
||||
"integrity": "sha512-bh88HXSvOBS581kgmihWY7Ijp9hBsvlmXogFG5LSNx9UBAobRcakZiFMGieRBc06hUSkpo7WhjaFM/z/SfQ8dQ==",
|
||||
"license": "OFL-1.1"
|
||||
},
|
||||
"node_modules/@embedpdf/fonts-latin": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@embedpdf/fonts-latin/-/fonts-latin-1.0.0.tgz",
|
||||
"integrity": "sha512-LLYysdr8O6sRNzhmW3PbF3AeA8xnqvOi4XLFfIfNlW5uEZ+qsJdcfd78Q78sFJMhlaOAYFMziMMsnOzmx463rA==",
|
||||
"license": "OFL-1.1"
|
||||
},
|
||||
"node_modules/@embedpdf/fonts-sc": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@embedpdf/fonts-sc/-/fonts-sc-1.0.0.tgz",
|
||||
"integrity": "sha512-ETXl7XCwaQLSSvMO3EUDwMNqtL64kX2LlFxarTRi/NsIGGOIxUurGfKtrkmtnKHrWy1jAJSt6oxK2uJhvdvQIw==",
|
||||
"license": "OFL-1.1"
|
||||
},
|
||||
"node_modules/@embedpdf/fonts-tc": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@embedpdf/fonts-tc/-/fonts-tc-1.0.0.tgz",
|
||||
"integrity": "sha512-rGZJbVD6DYS5BbXdpEMnWkpVF0Knar+bsiyb2o3+YRx7O8eyFubEBQUSUInirQk69HA6fc3GhYCg7TyC/oD76Q==",
|
||||
"license": "OFL-1.1"
|
||||
},
|
||||
"node_modules/@embedpdf/models": {
|
||||
"version": "1.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@embedpdf/models/-/models-1.5.0.tgz",
|
||||
"integrity": "sha512-x/1li3jdag+IzfZkcfRLKLqASLep4v6dgVi3z0JArwaicFra8k1IY2xaVTrwcZyx7pRb/rxvoO9yLHW0Y34NFw==",
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/@embedpdf/models/-/models-2.3.0.tgz",
|
||||
"integrity": "sha512-YAH3YdXl/UOhVcvMPd6mtU+tJ3veh24Q5swRDfuWUsJ3L2CcAG2P+4pjj4EAwvWUQcmN/HlVOjVQL0PkbkytKw==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@embedpdf/pdfium": {
|
||||
"version": "1.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@embedpdf/pdfium/-/pdfium-1.5.0.tgz",
|
||||
"integrity": "sha512-PI32t2U4ThZC907n2Iwr8E5WqmC574G83u3V9ysNFl29N9kasrY9RiLSzU4W/yQvXPjIbpQHBsbMKXLjCFBI9w==",
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/@embedpdf/pdfium/-/pdfium-2.3.0.tgz",
|
||||
"integrity": "sha512-AIWHDDG24we1r8sWVO9Uae6V2ISXji2gIkZS3+CjtYowaBCpMTSu4QEQRnjQam2EWrEMVIJOXwBfx11TZKrxWA==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@embedpdf/plugin-annotation": {
|
||||
"version": "1.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@embedpdf/plugin-annotation/-/plugin-annotation-1.5.0.tgz",
|
||||
"integrity": "sha512-mxEPI6xYwOGaf9fYfoywuj6nwA10eHFPBuN066MzwphDk6DOHJGZ3Vq8zNQBXh20c/Lb25PL718D7MZWxZLUHg==",
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/@embedpdf/plugin-annotation/-/plugin-annotation-2.3.0.tgz",
|
||||
"integrity": "sha512-TIN/OiDTg5tCNsebp1SWnS6aa7nnDvRrrZe3jx7Sg5IMEiZc6P3z+0aOjJtvoz0cp3Xi7Bb0PQsTLwo+bdfpVg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@embedpdf/models": "1.5.0",
|
||||
"@embedpdf/utils": "1.5.0"
|
||||
"@embedpdf/models": "2.3.0",
|
||||
"@embedpdf/utils": "2.3.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@embedpdf/core": "1.5.0",
|
||||
"@embedpdf/plugin-history": "1.5.0",
|
||||
"@embedpdf/plugin-interaction-manager": "1.5.0",
|
||||
"@embedpdf/plugin-selection": "1.5.0",
|
||||
"@embedpdf/core": "2.3.0",
|
||||
"@embedpdf/plugin-history": "2.3.0",
|
||||
"@embedpdf/plugin-interaction-manager": "2.3.0",
|
||||
"@embedpdf/plugin-selection": "2.3.0",
|
||||
"preact": "^10.26.4",
|
||||
"react": ">=16.8.0",
|
||||
"react-dom": ">=16.8.0",
|
||||
"svelte": ">=5 <6",
|
||||
"vue": ">=3.2.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@embedpdf/plugin-bookmark": {
|
||||
"version": "1.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@embedpdf/plugin-bookmark/-/plugin-bookmark-1.5.0.tgz",
|
||||
"integrity": "sha512-s3C9PtVesy5X8Ds/C9TEElFiqfKGRklG/uNPTROpNoolfpi0h7qX2xqqh/9+FzKH2nHjVcPB7Pp432v16h7eRA==",
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/@embedpdf/plugin-bookmark/-/plugin-bookmark-2.3.0.tgz",
|
||||
"integrity": "sha512-7XO2NntgRb/Jk1XN/EOf7+yVaOPVVFvBuF0xlCqnz2BGAnMNrTn8QE73FtluJBgNhuK9LwDT2C4W+BTD2gd59Q==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@embedpdf/models": "1.5.0"
|
||||
"@embedpdf/models": "2.3.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@embedpdf/core": "1.5.0",
|
||||
"@embedpdf/core": "2.3.0",
|
||||
"preact": "^10.26.4",
|
||||
"react": ">=16.8.0",
|
||||
"react-dom": ">=16.8.0",
|
||||
"svelte": ">=5 <6",
|
||||
"vue": ">=3.2.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@embedpdf/plugin-document-manager": {
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/@embedpdf/plugin-document-manager/-/plugin-document-manager-2.3.0.tgz",
|
||||
"integrity": "sha512-hdKaWU1sjlLgXo2iWF4N734lklCfSO5Tj1xqk+0omxOpnVL1Ed5fzFO2N584pMkfFn1xo9Y2JPHSUtCdzF7/EQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@embedpdf/models": "2.3.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@embedpdf/core": "2.3.0",
|
||||
"preact": "^10.26.4",
|
||||
"react": ">=16.8.0",
|
||||
"react-dom": ">=16.8.0",
|
||||
"svelte": ">=5 <6",
|
||||
"vue": ">=3.2.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@embedpdf/plugin-export": {
|
||||
"version": "1.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@embedpdf/plugin-export/-/plugin-export-1.5.0.tgz",
|
||||
"integrity": "sha512-luk68mNW9l2X31qk4b02phKaqDl9aDXUAgHVz1EWrgwXQ3Oz9WEdu60utYARYDiepDo3Caadll8RwctYSf/anA==",
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/@embedpdf/plugin-export/-/plugin-export-2.3.0.tgz",
|
||||
"integrity": "sha512-Xa048lKnc1jehWbaWv5qER1RVIHhHqt+JhgzAlqFSURXmzowbUzVEDBZ7fYImXRkpqp+ZeyBhWfZ60DBNE55Cw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@embedpdf/models": "1.5.0"
|
||||
"@embedpdf/models": "2.3.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@embedpdf/core": "1.5.0",
|
||||
"@embedpdf/core": "2.3.0",
|
||||
"preact": "^10.26.4",
|
||||
"react": ">=16.8.0",
|
||||
"react-dom": ">=16.8.0",
|
||||
@@ -651,31 +720,15 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@embedpdf/plugin-history": {
|
||||
"version": "1.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@embedpdf/plugin-history/-/plugin-history-1.5.0.tgz",
|
||||
"integrity": "sha512-p7PTNNaIr4gH3jLwX+eLJe1DeUXgi21kVGN6SRx/pocH8esg4jqoOeD/YiRRZoZnPOiy0jBXVhkPkwSmY7a2hQ==",
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/@embedpdf/plugin-history/-/plugin-history-2.3.0.tgz",
|
||||
"integrity": "sha512-+fr/kjK2Z9BiC53IMlUZvWjkD6iilcI3XCUKQPXRgS5MDAuwpVlgdAtc+3VAMlG3IddElxVFdvvxRO9R89k5Mg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@embedpdf/models": "1.5.0"
|
||||
"@embedpdf/models": "2.3.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@embedpdf/core": "1.5.0",
|
||||
"preact": "^10.26.4",
|
||||
"react": ">=16.8.0",
|
||||
"react-dom": ">=16.8.0",
|
||||
"vue": ">=3.2.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@embedpdf/plugin-interaction-manager": {
|
||||
"version": "1.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@embedpdf/plugin-interaction-manager/-/plugin-interaction-manager-1.5.0.tgz",
|
||||
"integrity": "sha512-ckHgTfvkW6c5Ta7Mc+Dl9C2foVnvEpqEJ84wyBnqrU0OWbe/jsiPhyKBVeartMGqNI/kVfaQTXupyrKhekAVmg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@embedpdf/models": "1.5.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@embedpdf/core": "1.5.0",
|
||||
"@embedpdf/core": "2.3.0",
|
||||
"preact": "^10.26.4",
|
||||
"react": ">=16.8.0",
|
||||
"react-dom": ">=16.8.0",
|
||||
@@ -683,16 +736,16 @@
|
||||
"vue": ">=3.2.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@embedpdf/plugin-loader": {
|
||||
"version": "1.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@embedpdf/plugin-loader/-/plugin-loader-1.5.0.tgz",
|
||||
"integrity": "sha512-P4YpIZfaW69etYIjphyaL4cGl2pB14h3OdTE0tRQ2pZYZHFLTvlt4q9B3PVSdhlSrHK5nob7jfLGon2U7xCslg==",
|
||||
"node_modules/@embedpdf/plugin-interaction-manager": {
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/@embedpdf/plugin-interaction-manager/-/plugin-interaction-manager-2.3.0.tgz",
|
||||
"integrity": "sha512-1/tDLPoQm6skNe/WOd6QD7SA0XRKphbJHi/s9XY4fhGgBvlD5XHFrYxtmrsaheYjqIBFtAWWZ3m5lAXRaO/igA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@embedpdf/models": "1.5.0"
|
||||
"@embedpdf/models": "2.3.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@embedpdf/core": "1.5.0",
|
||||
"@embedpdf/core": "2.3.0",
|
||||
"preact": "^10.26.4",
|
||||
"react": ">=16.8.0",
|
||||
"react-dom": ">=16.8.0",
|
||||
@@ -701,17 +754,17 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@embedpdf/plugin-pan": {
|
||||
"version": "1.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@embedpdf/plugin-pan/-/plugin-pan-1.5.0.tgz",
|
||||
"integrity": "sha512-EMQ08dHqLkZmFVuLOO6h3AAinFPQoA1r6OlL9z+p0sswq31JAgd4X7+xjYIpI01z/V3+cTzPHzp7qwob5E4tbA==",
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/@embedpdf/plugin-pan/-/plugin-pan-2.3.0.tgz",
|
||||
"integrity": "sha512-5yGxLpn28PHKCYx3tjzeVir7D5vHZ0Fk9HJRJr4K+Uqbg8pYFavb9tseXzPE4FcqpejqZo2DZyfo54ErQFXEyQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@embedpdf/models": "1.5.0"
|
||||
"@embedpdf/models": "2.3.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@embedpdf/core": "1.5.0",
|
||||
"@embedpdf/plugin-interaction-manager": "1.5.0",
|
||||
"@embedpdf/plugin-viewport": "1.5.0",
|
||||
"@embedpdf/core": "2.3.0",
|
||||
"@embedpdf/plugin-interaction-manager": "2.3.0",
|
||||
"@embedpdf/plugin-viewport": "2.3.0",
|
||||
"preact": "^10.26.4",
|
||||
"react": ">=16.8.0",
|
||||
"react-dom": ">=16.8.0",
|
||||
@@ -720,15 +773,15 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@embedpdf/plugin-print": {
|
||||
"version": "1.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@embedpdf/plugin-print/-/plugin-print-1.5.0.tgz",
|
||||
"integrity": "sha512-rjorvNxAZfO9X4cFZVU9fHnldMWqMceJGmr3mH+yj7KdHePvNDDP+omyZyZKtxlUZENaeDI2h6k5z0GbhBz6sQ==",
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/@embedpdf/plugin-print/-/plugin-print-2.3.0.tgz",
|
||||
"integrity": "sha512-LNxvXm3rZkRXXC41IArBDiwPLzSflmBmxxi+L+91xvw8n/FWUeXfWwQn7oQEAGq9Ha/3pEVHTls48QSFZN0mhg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@embedpdf/models": "1.5.0"
|
||||
"@embedpdf/models": "2.3.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@embedpdf/core": "1.5.0",
|
||||
"@embedpdf/core": "2.3.0",
|
||||
"preact": "^10.26.4",
|
||||
"react": ">=18.0.0",
|
||||
"react-dom": ">=18.0.0",
|
||||
@@ -737,34 +790,35 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@embedpdf/plugin-redaction": {
|
||||
"version": "1.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@embedpdf/plugin-redaction/-/plugin-redaction-1.5.0.tgz",
|
||||
"integrity": "sha512-txiukr5UKAGvJzl6dVBmmIT1v3r/t4e2qYm1hqU2faGgNCa2dwk79x9mDBlvWwxlJXCDFuFE+7Ps9/nU6qmU2w==",
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/@embedpdf/plugin-redaction/-/plugin-redaction-2.3.0.tgz",
|
||||
"integrity": "sha512-un6AQL5Pqcm9v1tCV9Mb3NeowsGUtlCT/198k4nd+SWOMWNsbuFqI+rWOGV3auqXRGSzKj0gnt29t8aaeLpLeA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@embedpdf/models": "1.5.0",
|
||||
"@embedpdf/utils": "1.5.0"
|
||||
"@embedpdf/models": "2.3.0",
|
||||
"@embedpdf/utils": "2.3.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@embedpdf/core": "1.5.0",
|
||||
"@embedpdf/plugin-interaction-manager": "1.5.0",
|
||||
"@embedpdf/plugin-selection": "1.5.0",
|
||||
"@embedpdf/core": "2.3.0",
|
||||
"@embedpdf/plugin-interaction-manager": "2.3.0",
|
||||
"@embedpdf/plugin-selection": "2.3.0",
|
||||
"preact": "^10.26.4",
|
||||
"react": ">=16.8.0",
|
||||
"react-dom": ">=16.8.0",
|
||||
"svelte": ">=5 <6",
|
||||
"vue": ">=3.2.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@embedpdf/plugin-render": {
|
||||
"version": "1.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@embedpdf/plugin-render/-/plugin-render-1.5.0.tgz",
|
||||
"integrity": "sha512-ywwSj0ByrlkvrJIHKRzqxARkOZriki8VJUC+T4MV8fGyF4CzvCRJyKlPktahFz+VxhoodqTh7lBCib68dH+GvA==",
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/@embedpdf/plugin-render/-/plugin-render-2.3.0.tgz",
|
||||
"integrity": "sha512-UyQncK5NTokuEVISUcxPOXpZP4SItn4MjfeEaPsTXJkSRjHL4g3mU3iWy0nXJMCOT10OB+5m7qQ0/KkF4f+b5w==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@embedpdf/models": "1.5.0"
|
||||
"@embedpdf/models": "2.3.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@embedpdf/core": "1.5.0",
|
||||
"@embedpdf/core": "2.3.0",
|
||||
"preact": "^10.26.4",
|
||||
"react": ">=16.8.0",
|
||||
"react-dom": ">=16.8.0",
|
||||
@@ -773,15 +827,15 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@embedpdf/plugin-rotate": {
|
||||
"version": "1.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@embedpdf/plugin-rotate/-/plugin-rotate-1.5.0.tgz",
|
||||
"integrity": "sha512-5EmBCsq0VfrE3xWY6ofuVm8S6aK95EbAycRIk1wczcmTdvpsuXZ6P2ZaECUgYMcpZ6uAg4/kGf8X8VVZuCihSQ==",
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/@embedpdf/plugin-rotate/-/plugin-rotate-2.3.0.tgz",
|
||||
"integrity": "sha512-vibDXHA0L2LlMrmkSuanmdtUpc2JPBuQybiGwf9F4wlleKN3f7uSWxZsHdVAxWdzsaG+/26QTGl75otZLnVuig==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@embedpdf/models": "1.5.0"
|
||||
"@embedpdf/models": "2.3.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@embedpdf/core": "1.5.0",
|
||||
"@embedpdf/core": "2.3.0",
|
||||
"preact": "^10.26.4",
|
||||
"react": ">=16.8.0",
|
||||
"react-dom": ">=16.8.0",
|
||||
@@ -790,16 +844,16 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@embedpdf/plugin-scroll": {
|
||||
"version": "1.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@embedpdf/plugin-scroll/-/plugin-scroll-1.5.0.tgz",
|
||||
"integrity": "sha512-RNmTZCZ8X1mA8cw9M7TMDuhO9GtkOalGha2bBL3En3D1IlDRS7PzNNMSMV7eqT7OQICSTltlpJ8p8Qi5esvL/Q==",
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/@embedpdf/plugin-scroll/-/plugin-scroll-2.3.0.tgz",
|
||||
"integrity": "sha512-8pdaSY9QuqdX22Ykw2jKn07Rx6FIsDdj/O0+mlbccY/ISofj9WEFNeQgnOY64OUTDyurJYqpYvq6QqvgbGLs+A==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@embedpdf/models": "1.5.0"
|
||||
"@embedpdf/models": "2.3.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@embedpdf/core": "1.5.0",
|
||||
"@embedpdf/plugin-viewport": "1.5.0",
|
||||
"@embedpdf/core": "2.3.0",
|
||||
"@embedpdf/plugin-viewport": "2.3.0",
|
||||
"preact": "^10.26.4",
|
||||
"react": ">=16.8.0",
|
||||
"react-dom": ">=16.8.0",
|
||||
@@ -808,16 +862,15 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@embedpdf/plugin-search": {
|
||||
"version": "1.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@embedpdf/plugin-search/-/plugin-search-1.5.0.tgz",
|
||||
"integrity": "sha512-TB5b0H8Iobx/azVUBIlG2ClaKtf0y3/Xi3E/iB8BwvkIE2+g6EGfp8IMXIn8WDXST6bbvJEP31Ab0Ilp6SVkiw==",
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/@embedpdf/plugin-search/-/plugin-search-2.3.0.tgz",
|
||||
"integrity": "sha512-VNXmNf7fIIRWGVwf2kIUeUeLkUTJlq9AGjUO2TyuYJTWTsmfT4LEqPDDpwC6NDVFhzWE6xwbb3bxvY/9bqBMzw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@embedpdf/models": "1.5.0"
|
||||
"@embedpdf/models": "2.3.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@embedpdf/core": "1.5.0",
|
||||
"@embedpdf/plugin-loader": "1.5.0",
|
||||
"@embedpdf/core": "2.3.0",
|
||||
"preact": "^10.26.4",
|
||||
"react": ">=16.8.0",
|
||||
"react-dom": ">=16.8.0",
|
||||
@@ -826,17 +879,17 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@embedpdf/plugin-selection": {
|
||||
"version": "1.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@embedpdf/plugin-selection/-/plugin-selection-1.5.0.tgz",
|
||||
"integrity": "sha512-zrxLBAZQoPswDuf9q9DrYaQc6B0Ysc2U1hueTjNH/4+ydfl0BFXZkKR63C2e3YmWtXvKjkoIj0GyPzsiBORLUw==",
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/@embedpdf/plugin-selection/-/plugin-selection-2.3.0.tgz",
|
||||
"integrity": "sha512-+emaY4vff3ynAf5C3PfCOlleQIqiImbBpb6zkG5SVUa9Vn5x0SfYGT4Jumtbzq8XBknC1QIRKVlplC9BcnjcmQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@embedpdf/models": "1.5.0"
|
||||
"@embedpdf/models": "2.3.0",
|
||||
"@embedpdf/utils": "2.3.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@embedpdf/core": "1.5.0",
|
||||
"@embedpdf/plugin-interaction-manager": "1.5.0",
|
||||
"@embedpdf/plugin-viewport": "1.5.0",
|
||||
"@embedpdf/core": "2.3.0",
|
||||
"@embedpdf/plugin-interaction-manager": "2.3.0",
|
||||
"preact": "^10.26.4",
|
||||
"react": ">=16.8.0",
|
||||
"react-dom": ">=16.8.0",
|
||||
@@ -845,16 +898,15 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@embedpdf/plugin-spread": {
|
||||
"version": "1.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@embedpdf/plugin-spread/-/plugin-spread-1.5.0.tgz",
|
||||
"integrity": "sha512-3EU5Cp+fPQSiMjvMR/P2kXxXry/RlnxHLs4JeskAaH95QcqWW3VD+DrHkWSiLFkdhI18rNNGNlMc5RvDGvbXGQ==",
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/@embedpdf/plugin-spread/-/plugin-spread-2.3.0.tgz",
|
||||
"integrity": "sha512-sFqYKwzKGPaCXn6hAyv6GHdVTlL2vg3poxRNd2W5kLQo07YtHlSjXr/XAhaGT/a4GtR9rtbSJ4hWNJjzIcwE0g==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@embedpdf/models": "1.5.0"
|
||||
"@embedpdf/models": "2.3.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@embedpdf/core": "1.5.0",
|
||||
"@embedpdf/plugin-loader": "1.5.0",
|
||||
"@embedpdf/core": "2.3.0",
|
||||
"preact": "^10.26.4",
|
||||
"react": ">=16.8.0",
|
||||
"react-dom": ">=16.8.0",
|
||||
@@ -863,16 +915,16 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@embedpdf/plugin-thumbnail": {
|
||||
"version": "1.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@embedpdf/plugin-thumbnail/-/plugin-thumbnail-1.5.0.tgz",
|
||||
"integrity": "sha512-Z2qpyyr5s2M6460KDGu1Vk6rdbQFIoCpnyFAT6e7UaTIKkqJSNpmjqMsBU5PosYCFu/cClpHPvS7tg9/IKAk6g==",
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/@embedpdf/plugin-thumbnail/-/plugin-thumbnail-2.3.0.tgz",
|
||||
"integrity": "sha512-CAOnipeBtdKSHGBuIm5420GykUw7k2rB7Z9GwouTbbycS7Cw+kiaGpOfHfenoKPTlWMkHYAwFcZiWKV3XG/nRQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@embedpdf/models": "1.5.0"
|
||||
"@embedpdf/models": "2.3.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@embedpdf/core": "1.5.0",
|
||||
"@embedpdf/plugin-render": "1.5.0",
|
||||
"@embedpdf/core": "2.3.0",
|
||||
"@embedpdf/plugin-render": "2.3.0",
|
||||
"preact": "^10.26.4",
|
||||
"react": ">=16.8.0",
|
||||
"react-dom": ">=16.8.0",
|
||||
@@ -881,18 +933,18 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@embedpdf/plugin-tiling": {
|
||||
"version": "1.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@embedpdf/plugin-tiling/-/plugin-tiling-1.5.0.tgz",
|
||||
"integrity": "sha512-0Vx9elHNpMM+zv8hEoZXBEm8Q0+4kU52LxOlTYRr1A5FskF836sUct6g1ngwK1bmfbAfpz+62PnYI2EeilDZig==",
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/@embedpdf/plugin-tiling/-/plugin-tiling-2.3.0.tgz",
|
||||
"integrity": "sha512-6VJ042WksIyZVWyvXq1nf0Ct+U4Pl6+QUDy1ThJefwk/HKDfWU2zEr/+1STJKVWgfUx5QRdipf6Jghd+HnOg3Q==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@embedpdf/models": "1.5.0"
|
||||
"@embedpdf/models": "2.3.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@embedpdf/core": "1.5.0",
|
||||
"@embedpdf/plugin-render": "1.5.0",
|
||||
"@embedpdf/plugin-scroll": "1.5.0",
|
||||
"@embedpdf/plugin-viewport": "1.5.0",
|
||||
"@embedpdf/core": "2.3.0",
|
||||
"@embedpdf/plugin-render": "2.3.0",
|
||||
"@embedpdf/plugin-scroll": "2.3.0",
|
||||
"@embedpdf/plugin-viewport": "2.3.0",
|
||||
"preact": "^10.26.4",
|
||||
"react": ">=16.8.0",
|
||||
"react-dom": ">=16.8.0",
|
||||
@@ -901,15 +953,15 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@embedpdf/plugin-viewport": {
|
||||
"version": "1.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@embedpdf/plugin-viewport/-/plugin-viewport-1.5.0.tgz",
|
||||
"integrity": "sha512-G8GDyYRhfehw72+r4qKkydnA5+AU8qH67g01Y12b0DzI0VIzymh/05Z4dK8DsY3jyWPXJfw2hlg5+KDHaMBHgQ==",
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/@embedpdf/plugin-viewport/-/plugin-viewport-2.3.0.tgz",
|
||||
"integrity": "sha512-3NQp3hVfRF7DMUPNAVOfZsqQQrugEfY0voRUrQI90eyi16GFntN3CP9Mc5cOp2jnUICMYlirQ/om+KCseMHS2Q==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@embedpdf/models": "1.5.0"
|
||||
"@embedpdf/models": "2.3.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@embedpdf/core": "1.5.0",
|
||||
"@embedpdf/core": "2.3.0",
|
||||
"preact": "^10.26.4",
|
||||
"react": ">=16.8.0",
|
||||
"react-dom": ">=16.8.0",
|
||||
@@ -918,19 +970,17 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@embedpdf/plugin-zoom": {
|
||||
"version": "1.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@embedpdf/plugin-zoom/-/plugin-zoom-1.5.0.tgz",
|
||||
"integrity": "sha512-LiDkCd5/IXg2CRORl1Yikan2op+AYXSxhHzCFatyBdwzVj+n4y9I74OwCI62Mar8WDAIMyXZDCQxGPToSm+zDw==",
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/@embedpdf/plugin-zoom/-/plugin-zoom-2.3.0.tgz",
|
||||
"integrity": "sha512-wnBqK02ku0zCViqQfSD1Vohy+aBUogXrqUTwo1/1QFEphmgnCHnHbEUduh9M0ghcT4s26pBgbJqCrShpGYAdvQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@embedpdf/models": "1.5.0",
|
||||
"hammerjs": "^2.0.8"
|
||||
"@embedpdf/models": "2.3.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@embedpdf/core": "1.5.0",
|
||||
"@embedpdf/plugin-interaction-manager": "1.5.0",
|
||||
"@embedpdf/plugin-scroll": "1.5.0",
|
||||
"@embedpdf/plugin-viewport": "1.5.0",
|
||||
"@embedpdf/core": "2.3.0",
|
||||
"@embedpdf/plugin-scroll": "2.3.0",
|
||||
"@embedpdf/plugin-viewport": "2.3.0",
|
||||
"preact": "^10.26.4",
|
||||
"react": ">=16.8.0",
|
||||
"react-dom": ">=16.8.0",
|
||||
@@ -939,14 +989,15 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@embedpdf/utils": {
|
||||
"version": "1.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@embedpdf/utils/-/utils-1.5.0.tgz",
|
||||
"integrity": "sha512-L6jsAPQPGM8ne+MMFAd5gqXb1RNEgNyh16VvVUVKcVnJlBhwil59nVeEQ0cwPhjF5qVeY6MQDIOjBzJqkgXOYg==",
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/@embedpdf/utils/-/utils-2.3.0.tgz",
|
||||
"integrity": "sha512-9DV+tu+GsnijchNSG/NzslnxTGIUH6j2MxBR8QOoZLsWETEVaMLkHtbvzXPyMOx/5RlvBn8wR0jNKTNptOCnXQ==",
|
||||
"license": "MIT",
|
||||
"peerDependencies": {
|
||||
"preact": "^10.26.4",
|
||||
"react": ">=16.8.0",
|
||||
"react-dom": ">=16.8.0",
|
||||
"svelte": ">=5 <6",
|
||||
"vue": ">=3.2.0"
|
||||
}
|
||||
},
|
||||
@@ -1898,9 +1949,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@iconify-json/material-symbols": {
|
||||
"version": "1.2.50",
|
||||
"resolved": "https://registry.npmjs.org/@iconify-json/material-symbols/-/material-symbols-1.2.50.tgz",
|
||||
"integrity": "sha512-71tjHR70h46LHtBFab3fAd2V/wPTO7JMV5lKnRn3IcF303LaFgAlO0BZeTJDcmCv9d0snRZmnoLZAJVD7/eisw==",
|
||||
"version": "1.2.53",
|
||||
"resolved": "https://registry.npmjs.org/@iconify-json/material-symbols/-/material-symbols-1.2.53.tgz",
|
||||
"integrity": "sha512-2jXBKFdNzL9zy6chnJqubykL9WZno7rEP6/isSzpp6fKJJMXXhRtVkaGw1Clle0RlXGWzVkd/eiYUH8f9/ILrQ==",
|
||||
"dev": true,
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
@@ -4128,27 +4179,27 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@tauri-apps/plugin-fs": {
|
||||
"version": "2.4.4",
|
||||
"resolved": "https://registry.npmjs.org/@tauri-apps/plugin-fs/-/plugin-fs-2.4.4.tgz",
|
||||
"integrity": "sha512-MTorXxIRmOnOPT1jZ3w96vjSuScER38ryXY88vl5F0uiKdnvTKKTtaEjTEo8uPbl4e3gnUtfsDVwC7h77GQLvQ==",
|
||||
"version": "2.4.5",
|
||||
"resolved": "https://registry.npmjs.org/@tauri-apps/plugin-fs/-/plugin-fs-2.4.5.tgz",
|
||||
"integrity": "sha512-dVxWWGE6VrOxC7/jlhyE+ON/Cc2REJlM35R3PJX3UvFw2XwYhLGQVAIyrehenDdKjotipjYEVc4YjOl3qq90fA==",
|
||||
"license": "MIT OR Apache-2.0",
|
||||
"dependencies": {
|
||||
"@tauri-apps/api": "^2.8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@tauri-apps/plugin-http": {
|
||||
"version": "2.5.4",
|
||||
"resolved": "https://registry.npmjs.org/@tauri-apps/plugin-http/-/plugin-http-2.5.4.tgz",
|
||||
"integrity": "sha512-/i4U/9za3mrytTgfRn5RHneKubZE/dwRmshYwyMvNRlkWjvu1m4Ma72kcbVJMZFGXpkbl+qLyWMGrihtWB76Zg==",
|
||||
"version": "2.5.6",
|
||||
"resolved": "https://registry.npmjs.org/@tauri-apps/plugin-http/-/plugin-http-2.5.6.tgz",
|
||||
"integrity": "sha512-KhCK3TDNDF4vdz75/j+KNQipYKf+295Visa8r32QcXScg0+D3JwShcCM6D+FN8WuDF24X3KSiAB8QtRxW6jKRA==",
|
||||
"license": "MIT OR Apache-2.0",
|
||||
"dependencies": {
|
||||
"@tauri-apps/api": "^2.8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@tauri-apps/plugin-shell": {
|
||||
"version": "2.3.3",
|
||||
"resolved": "https://registry.npmjs.org/@tauri-apps/plugin-shell/-/plugin-shell-2.3.3.tgz",
|
||||
"integrity": "sha512-Xod+pRcFxmOWFWEnqH5yZcA7qwAMuaaDkMR1Sply+F8VfBj++CGnj2xf5UoialmjZ2Cvd8qrvSCbU+7GgNVsKQ==",
|
||||
"version": "2.3.4",
|
||||
"resolved": "https://registry.npmjs.org/@tauri-apps/plugin-shell/-/plugin-shell-2.3.4.tgz",
|
||||
"integrity": "sha512-ktsRWf8wHLD17aZEyqE8c5x98eNAuTizR1FSX475zQ4TxaiJnhwksLygQz+AGwckJL5bfEP13nWrlTNQJUpKpA==",
|
||||
"license": "MIT OR Apache-2.0",
|
||||
"dependencies": {
|
||||
"@tauri-apps/api": "^2.8.0"
|
||||
@@ -7033,9 +7084,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/devalue": {
|
||||
"version": "5.6.1",
|
||||
"resolved": "https://registry.npmjs.org/devalue/-/devalue-5.6.1.tgz",
|
||||
"integrity": "sha512-jDwizj+IlEZBunHcOuuFVBnIMPAEHvTsJj0BcIp94xYguLRVBcXO853px/MyIJvbVzWdsGvrRweIUWJw8hBP7A==",
|
||||
"version": "5.6.2",
|
||||
"resolved": "https://registry.npmjs.org/devalue/-/devalue-5.6.2.tgz",
|
||||
"integrity": "sha512-nPRkjWzzDQlsejL1WVifk5rvcFi/y1onBRxjaFMjZeR9mFpqu2gmAZ9xUB9/IEanEP/vBtGeGganC/GO1fmufg==",
|
||||
"license": "MIT",
|
||||
"peer": true
|
||||
},
|
||||
@@ -8556,9 +8607,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/globals": {
|
||||
"version": "17.0.0",
|
||||
"resolved": "https://registry.npmjs.org/globals/-/globals-17.0.0.tgz",
|
||||
"integrity": "sha512-gv5BeD2EssA793rlFWVPMMCqefTlpusw6/2TbAVMy0FzcG8wKJn4O+NqJ4+XWmmwrayJgw5TzrmWjFgmz1XPqw==",
|
||||
"version": "17.1.0",
|
||||
"resolved": "https://registry.npmjs.org/globals/-/globals-17.1.0.tgz",
|
||||
"integrity": "sha512-8HoIcWI5fCvG5NADj4bDav+er9B9JMj2vyL2pI8D0eismKyUvPLTSs+Ln3wqhwcp306i73iyVnEKx3F6T47TGw==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
@@ -8660,15 +8711,6 @@
|
||||
"integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==",
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/hammerjs": {
|
||||
"version": "2.0.8",
|
||||
"resolved": "https://registry.npmjs.org/hammerjs/-/hammerjs-2.0.8.tgz",
|
||||
"integrity": "sha512-tSQXBXS/MWQOn/RKckawJ61vvsDpCom87JgxiYdGwHdOa0ht0vzUWDlfioofFCRU0L+6NGDt6XzbgoJvZkMeRQ==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=0.8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/has-bigints": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.1.0.tgz",
|
||||
@@ -12176,9 +12218,9 @@
|
||||
"license": "0BSD"
|
||||
},
|
||||
"node_modules/react-router": {
|
||||
"version": "7.11.0",
|
||||
"resolved": "https://registry.npmjs.org/react-router/-/react-router-7.11.0.tgz",
|
||||
"integrity": "sha512-uI4JkMmjbWCZc01WVP2cH7ZfSzH91JAZUDd7/nIprDgWxBV1TkkmLToFh7EbMTcMak8URFRa2YoBL/W8GWnCTQ==",
|
||||
"version": "7.13.0",
|
||||
"resolved": "https://registry.npmjs.org/react-router/-/react-router-7.13.0.tgz",
|
||||
"integrity": "sha512-PZgus8ETambRT17BUm/LL8lX3Of+oiLaPuVTRH3l1eLvSPpKO3AvhAEb5N7ihAFZQrYDqkvvWfFh9p0z9VsjLw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"cookie": "^1.0.1",
|
||||
@@ -12198,12 +12240,12 @@
|
||||
}
|
||||
},
|
||||
"node_modules/react-router-dom": {
|
||||
"version": "7.11.0",
|
||||
"resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-7.11.0.tgz",
|
||||
"integrity": "sha512-e49Ir/kMGRzFOOrYQBdoitq3ULigw4lKbAyKusnvtDu2t4dBX4AGYPrzNvorXmVuOyeakai6FUPW5MmibvVG8g==",
|
||||
"version": "7.13.0",
|
||||
"resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-7.13.0.tgz",
|
||||
"integrity": "sha512-5CO/l5Yahi2SKC6rGZ+HDEjpjkGaG/ncEP7eWFTvFxbHP8yeeI0PxTDjimtpXYlR3b3i9/WIL4VJttPrESIf2g==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"react-router": "7.11.0"
|
||||
"react-router": "7.13.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=20.0.0"
|
||||
@@ -13448,9 +13490,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/svelte": {
|
||||
"version": "5.46.1",
|
||||
"resolved": "https://registry.npmjs.org/svelte/-/svelte-5.46.1.tgz",
|
||||
"integrity": "sha512-ynjfCHD3nP2el70kN5Pmg37sSi0EjOm9FgHYQdC4giWG/hzO3AatzXXJJgP305uIhGQxSufJLuYWtkY8uK/8RA==",
|
||||
"version": "5.48.2",
|
||||
"resolved": "https://registry.npmjs.org/svelte/-/svelte-5.48.2.tgz",
|
||||
"integrity": "sha512-VPWD+UyoSFZ7Nxix5K/F8yWiKWOiROkLlWYXOZReE0TUycw+58YWB3D6lAKT+57xmN99wRX4H3oZmw0NPy7y3Q==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
@@ -13462,7 +13504,7 @@
|
||||
"aria-query": "^5.3.1",
|
||||
"axobject-query": "^4.1.0",
|
||||
"clsx": "^2.1.1",
|
||||
"devalue": "^5.5.0",
|
||||
"devalue": "^5.6.2",
|
||||
"esm-env": "^1.2.1",
|
||||
"esrap": "^2.2.1",
|
||||
"is-reference": "^3.0.3",
|
||||
|
||||
+32
-31
@@ -7,27 +7,28 @@
|
||||
"dependencies": {
|
||||
"@atlaskit/pragmatic-drag-and-drop": "^1.7.7",
|
||||
"@dnd-kit/core": "^6.3.1",
|
||||
"@embedpdf/core": "^1.5.0",
|
||||
"@embedpdf/engines": "^1.5.0",
|
||||
"@embedpdf/plugin-annotation": "^1.5.0",
|
||||
"@embedpdf/plugin-bookmark": "^1.5.0",
|
||||
"@embedpdf/plugin-export": "^1.5.0",
|
||||
"@embedpdf/plugin-history": "^1.5.0",
|
||||
"@embedpdf/plugin-interaction-manager": "^1.5.0",
|
||||
"@embedpdf/plugin-loader": "^1.5.0",
|
||||
"@embedpdf/plugin-pan": "^1.5.0",
|
||||
"@embedpdf/plugin-print": "^1.5.0",
|
||||
"@embedpdf/plugin-redaction": "^1.5.0",
|
||||
"@embedpdf/plugin-render": "^1.5.0",
|
||||
"@embedpdf/plugin-rotate": "^1.5.0",
|
||||
"@embedpdf/plugin-scroll": "^1.5.0",
|
||||
"@embedpdf/plugin-search": "^1.5.0",
|
||||
"@embedpdf/plugin-selection": "^1.5.0",
|
||||
"@embedpdf/plugin-spread": "^1.5.0",
|
||||
"@embedpdf/plugin-thumbnail": "^1.5.0",
|
||||
"@embedpdf/plugin-tiling": "^1.5.0",
|
||||
"@embedpdf/plugin-viewport": "^1.5.0",
|
||||
"@embedpdf/plugin-zoom": "^1.5.0",
|
||||
"@embedpdf/core": "^2.3.0",
|
||||
"@embedpdf/engines": "^2.3.0",
|
||||
"@embedpdf/models": "^2.3.0",
|
||||
"@embedpdf/plugin-annotation": "^2.3.0",
|
||||
"@embedpdf/plugin-bookmark": "^2.3.0",
|
||||
"@embedpdf/plugin-export": "^2.3.0",
|
||||
"@embedpdf/plugin-history": "^2.3.0",
|
||||
"@embedpdf/plugin-document-manager": "^2.3.0",
|
||||
"@embedpdf/plugin-interaction-manager": "^2.3.0",
|
||||
"@embedpdf/plugin-pan": "^2.3.0",
|
||||
"@embedpdf/plugin-print": "^2.3.0",
|
||||
"@embedpdf/plugin-redaction": "^2.3.0",
|
||||
"@embedpdf/plugin-render": "^2.3.0",
|
||||
"@embedpdf/plugin-rotate": "^2.3.0",
|
||||
"@embedpdf/plugin-scroll": "^2.3.0",
|
||||
"@embedpdf/plugin-search": "^2.3.0",
|
||||
"@embedpdf/plugin-selection": "^2.3.0",
|
||||
"@embedpdf/plugin-spread": "^2.3.0",
|
||||
"@embedpdf/plugin-thumbnail": "^2.3.0",
|
||||
"@embedpdf/plugin-tiling": "^2.3.0",
|
||||
"@embedpdf/plugin-viewport": "^2.3.0",
|
||||
"@embedpdf/plugin-zoom": "^2.3.0",
|
||||
"@emotion/react": "^11.14.0",
|
||||
"@emotion/styled": "^11.14.1",
|
||||
"@iconify/react": "^6.0.2",
|
||||
@@ -43,13 +44,13 @@
|
||||
"@supabase/supabase-js": "^2.47.13",
|
||||
"@tailwindcss/postcss": "^4.1.13",
|
||||
"@tanstack/react-virtual": "^3.13.12",
|
||||
"@tauri-apps/api": "^2.5.0",
|
||||
"@tauri-apps/plugin-fs": "^2.4.0",
|
||||
"@tauri-apps/plugin-http": "^2.5.4",
|
||||
"@tauri-apps/plugin-shell": "^2.3.3",
|
||||
"@tauri-apps/api": "^2.9.1",
|
||||
"@tauri-apps/plugin-fs": "^2.4.5",
|
||||
"@tauri-apps/plugin-http": "^2.5.6",
|
||||
"@tauri-apps/plugin-shell": "^2.3.4",
|
||||
"autoprefixer": "^10.4.21",
|
||||
"axios": "^1.12.2",
|
||||
"globals": "^17.0.0",
|
||||
"axios": "^1.13.2",
|
||||
"globals": "^17.1.0",
|
||||
"i18next": "^25.5.2",
|
||||
"i18next-browser-languagedetector": "^8.2.0",
|
||||
"jszip": "^3.10.1",
|
||||
@@ -58,7 +59,7 @@
|
||||
"pdfjs-dist": "^5.4.149",
|
||||
"peerjs": "^1.5.5",
|
||||
"posthog-js": "^1.268.0",
|
||||
"qrcode.react": "^4.1.0",
|
||||
"qrcode.react": "^4.2.0",
|
||||
"react": "^19.1.1",
|
||||
"react-dom": "^19.1.1",
|
||||
"react-i18next": "^15.7.3",
|
||||
@@ -126,10 +127,10 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@eslint/js": "^9.36.0",
|
||||
"@iconify-json/material-symbols": "^1.2.48",
|
||||
"@iconify/utils": "^3.0.2",
|
||||
"@iconify-json/material-symbols": "^1.2.53",
|
||||
"@iconify/utils": "^3.1.0",
|
||||
"@playwright/test": "^1.55.0",
|
||||
"@tauri-apps/cli": "^2.5.0",
|
||||
"@tauri-apps/cli": "^2.9.6",
|
||||
"@testing-library/dom": "^10.4.1",
|
||||
"@testing-library/jest-dom": "^6.8.0",
|
||||
"@testing-library/react": "^16.3.0",
|
||||
|
||||
@@ -439,7 +439,9 @@ fullscreen = "ملء الشاشة"
|
||||
[settings.general.updates]
|
||||
title = "تحديثات البرنامج"
|
||||
description = "التحقق من التحديثات وعرض معلومات الإصدار"
|
||||
currentVersion = "الإصدار الحالي"
|
||||
currentBackendVersion = "Current Backend Version"
|
||||
currentFrontendVersion = "Current Frontend Version"
|
||||
versionMismatch = "Warning: A mismatch has been detected between the client version and the AppConfig version. Using different versions can lead to compatibility issues, errors, and security risks. Please ensure that server and client are using the same version."
|
||||
latestVersion = "أحدث إصدار"
|
||||
checkForUpdates = "التحقق من التحديثات"
|
||||
viewDetails = "عرض التفاصيل"
|
||||
@@ -950,6 +952,7 @@ title = "تقسيم تلقائي بالحجم/العدد"
|
||||
desc = "تقسيم ملف PDF واحد إلى مستندات متعددة بناءً على الحجم أو عدد الصفحات أو عدد المستندات"
|
||||
|
||||
[home.replaceColor]
|
||||
tags = "replace color,invert color,color replacement,swap colors,change color,invert,negative,color swap,find and replace color,convert color,color change"
|
||||
title = "استبدال وعكس الألوان"
|
||||
desc = "استبدال الألوان أو عكسها في مستندات PDF"
|
||||
|
||||
@@ -964,18 +967,22 @@ title = "المسح الآلي للمجلدات"
|
||||
desc = "رابط إلى دليل المسح الآلي للمجلدات"
|
||||
|
||||
[home.devSsoGuide]
|
||||
tags = "SSO,single sign-on,authentication,SAML,OAuth,OIDC,login,enterprise,identity provider,IdP"
|
||||
title = "دليل SSO"
|
||||
desc = "رابط إلى دليل SSO"
|
||||
|
||||
[home.devAirgapped]
|
||||
tags = "air-gapped,offline,isolated,no internet,disconnected,secure,network isolation,standalone"
|
||||
title = "إعداد معزول"
|
||||
desc = "رابط إلى دليل الإعداد المعزول"
|
||||
|
||||
[home.addPassword]
|
||||
tags = "encrypt,password,lock,secure,protect,security,encryption,safeguard,confidential,private,restrict access"
|
||||
title = "إضافة كلمة مرور"
|
||||
desc = "تشفير مستند PDF الخاص بك بكلمة مرور."
|
||||
|
||||
[home.changePermissions]
|
||||
tags = "permissions,restrictions,rights,access control,allow,deny,printing,copying,editing,modify permissions,security settings,user rights"
|
||||
title = "تغيير الأذونات"
|
||||
desc = "تغيير قيود المستند وأذوناته"
|
||||
|
||||
@@ -985,10 +992,12 @@ title = "أتمتة"
|
||||
desc = "ابنِ تدفّقات عمل متعددة الخطوات بسلسلة إجراءات PDF. مثالي للمهام المتكررة."
|
||||
|
||||
[home.overlay-pdfs]
|
||||
tags = "overlay,combine,merge,layer,superimpose,overlay PDF,layer PDFs,combine PDFs,stack,overlay pages,background,foreground,composite"
|
||||
desc = "تراكب ملف PDF فوق آخر"
|
||||
title = "تراكب ملفات PDF"
|
||||
|
||||
[home.pdfTextEditor]
|
||||
tags = "edit text,modify text,change text,edit content,update text,rewrite,correct,amend,redline,revise,text editor,content editor"
|
||||
title = "محرر نصوص PDF"
|
||||
desc = "مراجعة وتحرير صادرات Stirling PDF بصيغة JSON مع تحرير نصوص مجمّعة وإعادة إنشاء PDF"
|
||||
|
||||
@@ -3553,6 +3562,31 @@ imageSize = "حجم الصورة"
|
||||
margin = "الهامش"
|
||||
positionAndFormatting = "الموضع والتنسيق"
|
||||
quickPosition = "اختر موضعًا على الصفحة لوضع الختم."
|
||||
clickToExpand = "Click to expand"
|
||||
customDateDesc = "Custom format"
|
||||
dateDesc = "Current date"
|
||||
dateTimeVars = "Date & Time"
|
||||
datetimeDesc = "Date and time combined"
|
||||
dynamicVariables = "Dynamic Variables"
|
||||
examples = "Examples"
|
||||
fileVars = "File Information"
|
||||
filenameDesc = "Filename without extension"
|
||||
filenameFullDesc = "Filename with extension"
|
||||
metadataDesc = "From PDF document properties"
|
||||
metadataVars = "Document Metadata"
|
||||
multiLine = "multi-line"
|
||||
otherVars = "Other"
|
||||
pageNumberDesc = "Current page number"
|
||||
pageVars = "Page Information"
|
||||
preview = "Preview:"
|
||||
selectTemplate = "Select a template..."
|
||||
stampTextDescription = "Use dynamic variables below. Use @@ for literal @. Use \\n for new lines."
|
||||
timeDesc = "Current time"
|
||||
totalPagesDesc = "Total number of pages"
|
||||
useTemplate = "Use Template"
|
||||
uuidDesc = "Short unique identifier (8 chars)"
|
||||
variablesHelp = "Click on any variable to insert it into your stamp text. Use @@ for literal @."
|
||||
yearMonthDayDesc = "Individual date parts"
|
||||
|
||||
[AddStampRequest.error]
|
||||
failed = "حدث خطأ أثناء إضافة الختم إلى ملف PDF."
|
||||
@@ -3560,6 +3594,14 @@ failed = "حدث خطأ أثناء إضافة الختم إلى ملف PDF."
|
||||
[AddStampRequest.results]
|
||||
title = "نتائج إضافة الختم"
|
||||
|
||||
[AddStampRequest.template]
|
||||
custom = "Custom"
|
||||
dateHeader = "Date Header"
|
||||
draftWatermark = "Draft Watermark"
|
||||
europeanDate = "European Date"
|
||||
pageNumberFooter = "Page Number Footer"
|
||||
timestamp = "Timestamp"
|
||||
|
||||
[removeImagePdf]
|
||||
tags = "إزالة الصورة,عمليات الصفحة,الخلفية,جانب الخادم"
|
||||
|
||||
@@ -4526,6 +4568,13 @@ description = "الحد الأقصى لعدد محاولات تسجيل الدخ
|
||||
label = "وقت إعادة التعيين لتسجيل الدخول (بالدقائق)"
|
||||
description = "المدة قبل إعادة تعيين عدد المحاولات الفاشلة"
|
||||
|
||||
[admin.settings.security.xFrameOptions]
|
||||
label = "X-Frame-Options"
|
||||
description = "Controls whether the application can be embedded in iframes"
|
||||
deny = "Deny (Prevents all framing)"
|
||||
sameorigin = "Same Origin (Allow framing from same domain)"
|
||||
disabled = "Disabled (No X-Frame-Options header)"
|
||||
|
||||
[admin.settings.security.csrfDisabled]
|
||||
label = "تعطيل حماية CSRF"
|
||||
description = "تعطيل حماية تزوير طلبات المواقع (غير مستحسن)"
|
||||
|
||||
@@ -439,7 +439,9 @@ fullscreen = "Tam ekran"
|
||||
[settings.general.updates]
|
||||
title = "Proqram yeniləmələri"
|
||||
description = "Yeniləmələri yoxlayın və versiya məlumatlarını görün"
|
||||
currentVersion = "Cari versiya"
|
||||
currentBackendVersion = "Current Backend Version"
|
||||
currentFrontendVersion = "Current Frontend Version"
|
||||
versionMismatch = "Warning: A mismatch has been detected between the client version and the AppConfig version. Using different versions can lead to compatibility issues, errors, and security risks. Please ensure that server and client are using the same version."
|
||||
latestVersion = "Ən son versiya"
|
||||
checkForUpdates = "Yeniləmələri yoxla"
|
||||
viewDetails = "Ətraflı bax"
|
||||
@@ -950,6 +952,7 @@ title = "Say/Ölçüyə Əsasən Avtomatik Ayır"
|
||||
desc = "PDF-i ölçüyə, səhifə sayına və ya sənəd sayına əsasən bir neçə PDF-ə ayır."
|
||||
|
||||
[home.replaceColor]
|
||||
tags = "replace color,invert color,color replacement,swap colors,change color,invert,negative,color swap,find and replace color,convert color,color change"
|
||||
title = "Rəngi əvəz et və invert et"
|
||||
desc = "PDF sənədlərində rəngləri əvəz edin və ya invert edin"
|
||||
|
||||
@@ -964,18 +967,22 @@ title = "Avtomatik qovluq skanı"
|
||||
desc = "Avtomatlaşdırılmış qovluq skan təlimatına keçid"
|
||||
|
||||
[home.devSsoGuide]
|
||||
tags = "SSO,single sign-on,authentication,SAML,OAuth,OIDC,login,enterprise,identity provider,IdP"
|
||||
title = "SSO təlimatı"
|
||||
desc = "SSO təlimatına keçid"
|
||||
|
||||
[home.devAirgapped]
|
||||
tags = "air-gapped,offline,isolated,no internet,disconnected,secure,network isolation,standalone"
|
||||
title = "Şəbəkəsiz quraşdırma"
|
||||
desc = "Təcrid edilmiş quraşdırma təlimatına keçid"
|
||||
|
||||
[home.addPassword]
|
||||
tags = "encrypt,password,lock,secure,protect,security,encryption,safeguard,confidential,private,restrict access"
|
||||
title = "Şifr Əlavə Et"
|
||||
desc = "Sənədini şifr ilə kilidlə."
|
||||
|
||||
[home.changePermissions]
|
||||
tags = "permissions,restrictions,rights,access control,allow,deny,printing,copying,editing,modify permissions,security settings,user rights"
|
||||
title = "İcazələri Dəyişdir"
|
||||
desc = "Sənəd məhdudiyyətlərini və icazələrini dəyişin"
|
||||
|
||||
@@ -985,10 +992,12 @@ title = "Avtomatlaşdır"
|
||||
desc = "PDF əməliyyatlarını zəncirləyərək çoxaddımlı iş axınları qurun. Təkrarlanan tapşırıqlar üçün idealdır."
|
||||
|
||||
[home.overlay-pdfs]
|
||||
tags = "overlay,combine,merge,layer,superimpose,overlay PDF,layer PDFs,combine PDFs,stack,overlay pages,background,foreground,composite"
|
||||
desc = "Bir PDF-i digərinin üstünə qoyur"
|
||||
title = "Üst-Üstə Qoy"
|
||||
|
||||
[home.pdfTextEditor]
|
||||
tags = "edit text,modify text,change text,edit content,update text,rewrite,correct,amend,redline,revise,text editor,content editor"
|
||||
title = "PDF Mətn Redaktoru"
|
||||
desc = "Qruplaşdırılmış mətn redaktəsi və PDF yenidən yaradılması ilə Stirling PDF JSON ixraclarını nəzərdən keçirin və redaktə edin"
|
||||
|
||||
@@ -3553,6 +3562,31 @@ imageSize = "Şəkil ölçüsü"
|
||||
margin = "Kənar boşluğu"
|
||||
positionAndFormatting = "Mövqe və formatlama"
|
||||
quickPosition = "Möhürü yerləşdirmək üçün səhifədə bir mövqe seçin."
|
||||
clickToExpand = "Click to expand"
|
||||
customDateDesc = "Custom format"
|
||||
dateDesc = "Current date"
|
||||
dateTimeVars = "Date & Time"
|
||||
datetimeDesc = "Date and time combined"
|
||||
dynamicVariables = "Dynamic Variables"
|
||||
examples = "Examples"
|
||||
fileVars = "File Information"
|
||||
filenameDesc = "Filename without extension"
|
||||
filenameFullDesc = "Filename with extension"
|
||||
metadataDesc = "From PDF document properties"
|
||||
metadataVars = "Document Metadata"
|
||||
multiLine = "multi-line"
|
||||
otherVars = "Other"
|
||||
pageNumberDesc = "Current page number"
|
||||
pageVars = "Page Information"
|
||||
preview = "Preview:"
|
||||
selectTemplate = "Select a template..."
|
||||
stampTextDescription = "Use dynamic variables below. Use @@ for literal @. Use \\n for new lines."
|
||||
timeDesc = "Current time"
|
||||
totalPagesDesc = "Total number of pages"
|
||||
useTemplate = "Use Template"
|
||||
uuidDesc = "Short unique identifier (8 chars)"
|
||||
variablesHelp = "Click on any variable to insert it into your stamp text. Use @@ for literal @."
|
||||
yearMonthDayDesc = "Individual date parts"
|
||||
|
||||
[AddStampRequest.error]
|
||||
failed = "PDF-ə möhür əlavə edilərkən xəta baş verdi."
|
||||
@@ -3560,6 +3594,14 @@ failed = "PDF-ə möhür əlavə edilərkən xəta baş verdi."
|
||||
[AddStampRequest.results]
|
||||
title = "Möhür nəticələri"
|
||||
|
||||
[AddStampRequest.template]
|
||||
custom = "Custom"
|
||||
dateHeader = "Date Header"
|
||||
draftWatermark = "Draft Watermark"
|
||||
europeanDate = "European Date"
|
||||
pageNumberFooter = "Page Number Footer"
|
||||
timestamp = "Timestamp"
|
||||
|
||||
[removeImagePdf]
|
||||
tags = "Şəkil Sil,Səhifə Əməliyyatları,Back end,server-tərəf"
|
||||
|
||||
@@ -4526,6 +4568,13 @@ description = "Hesabın bloklanmasından əvvəl maksimal uğursuz giriş cəhdl
|
||||
label = "Girişi sıfırlama vaxtı (dəqiqə)"
|
||||
description = "Uğursuz giriş cəhdlərinin sıfırlanmasına qədər olan vaxt"
|
||||
|
||||
[admin.settings.security.xFrameOptions]
|
||||
label = "X-Frame-Options"
|
||||
description = "Controls whether the application can be embedded in iframes"
|
||||
deny = "Deny (Prevents all framing)"
|
||||
sameorigin = "Same Origin (Allow framing from same domain)"
|
||||
disabled = "Disabled (No X-Frame-Options header)"
|
||||
|
||||
[admin.settings.security.csrfDisabled]
|
||||
label = "CSRF mühafizəsini söndür"
|
||||
description = "Cross-Site Request Forgery mühafizəsini söndür (tövsiyə olunmur)"
|
||||
|
||||
@@ -439,7 +439,9 @@ fullscreen = "Цял екран"
|
||||
[settings.general.updates]
|
||||
title = "Актуализации на софтуера"
|
||||
description = "Проверете за актуализации и вижте информация за версията"
|
||||
currentVersion = "Текуща версия"
|
||||
currentBackendVersion = "Current Backend Version"
|
||||
currentFrontendVersion = "Current Frontend Version"
|
||||
versionMismatch = "Warning: A mismatch has been detected between the client version and the AppConfig version. Using different versions can lead to compatibility issues, errors, and security risks. Please ensure that server and client are using the same version."
|
||||
latestVersion = "Последна версия"
|
||||
checkForUpdates = "Провери за актуализации"
|
||||
viewDetails = "Виж подробности"
|
||||
@@ -950,6 +952,7 @@ title = "Авто делене по размер/брой"
|
||||
desc = "Разделете един PDF на множество документи въз основа на размер, брой страници или брой документи"
|
||||
|
||||
[home.replaceColor]
|
||||
tags = "replace color,invert color,color replacement,swap colors,change color,invert,negative,color swap,find and replace color,convert color,color change"
|
||||
title = "Смени/обърни цветове"
|
||||
desc = "Заместване или инвертиране на цветове в PDF документи"
|
||||
|
||||
@@ -964,18 +967,22 @@ title = "Авто сканиране на папки"
|
||||
desc = "Връзка към ръководство за автоматизирано сканиране на папки"
|
||||
|
||||
[home.devSsoGuide]
|
||||
tags = "SSO,single sign-on,authentication,SAML,OAuth,OIDC,login,enterprise,identity provider,IdP"
|
||||
title = "Ръководство за SSO"
|
||||
desc = "Връзка към SSO ръководство"
|
||||
|
||||
[home.devAirgapped]
|
||||
tags = "air-gapped,offline,isolated,no internet,disconnected,secure,network isolation,standalone"
|
||||
title = "Настройка за air‑gapped среда"
|
||||
desc = "Връзка към ръководство за air‑gapped настройка"
|
||||
|
||||
[home.addPassword]
|
||||
tags = "encrypt,password,lock,secure,protect,security,encryption,safeguard,confidential,private,restrict access"
|
||||
title = "Добавете парола"
|
||||
desc = "Шифровайте вашия PDF документ с парола."
|
||||
|
||||
[home.changePermissions]
|
||||
tags = "permissions,restrictions,rights,access control,allow,deny,printing,copying,editing,modify permissions,security settings,user rights"
|
||||
title = "Промяна на правата"
|
||||
desc = "Промяна на ограниченията и разрешенията на документа"
|
||||
|
||||
@@ -985,10 +992,12 @@ title = "Автоматизация"
|
||||
desc = "Създавайте многостъпкови работни процеси чрез свързване на PDF действия. Идеално за повтарящи се задачи."
|
||||
|
||||
[home.overlay-pdfs]
|
||||
tags = "overlay,combine,merge,layer,superimpose,overlay PDF,layer PDFs,combine PDFs,stack,overlay pages,background,foreground,composite"
|
||||
desc = "Наслагва PDF файлове върху друг PDF"
|
||||
title = "Наслагване PDF-и"
|
||||
|
||||
[home.pdfTextEditor]
|
||||
tags = "edit text,modify text,change text,edit content,update text,rewrite,correct,amend,redline,revise,text editor,content editor"
|
||||
title = "PDF текстов редактор"
|
||||
desc = "Преглеждайте и редактирайте JSON експорти на Stirling PDF с групово редактиране на текст и повторно генериране на PDF"
|
||||
|
||||
@@ -3553,6 +3562,31 @@ imageSize = "Размер на изображението"
|
||||
margin = "Отстъп"
|
||||
positionAndFormatting = "Позиция и форматиране"
|
||||
quickPosition = "Изберете позиция на страницата, където да поставите печата."
|
||||
clickToExpand = "Click to expand"
|
||||
customDateDesc = "Custom format"
|
||||
dateDesc = "Current date"
|
||||
dateTimeVars = "Date & Time"
|
||||
datetimeDesc = "Date and time combined"
|
||||
dynamicVariables = "Dynamic Variables"
|
||||
examples = "Examples"
|
||||
fileVars = "File Information"
|
||||
filenameDesc = "Filename without extension"
|
||||
filenameFullDesc = "Filename with extension"
|
||||
metadataDesc = "From PDF document properties"
|
||||
metadataVars = "Document Metadata"
|
||||
multiLine = "multi-line"
|
||||
otherVars = "Other"
|
||||
pageNumberDesc = "Current page number"
|
||||
pageVars = "Page Information"
|
||||
preview = "Preview:"
|
||||
selectTemplate = "Select a template..."
|
||||
stampTextDescription = "Use dynamic variables below. Use @@ for literal @. Use \\n for new lines."
|
||||
timeDesc = "Current time"
|
||||
totalPagesDesc = "Total number of pages"
|
||||
useTemplate = "Use Template"
|
||||
uuidDesc = "Short unique identifier (8 chars)"
|
||||
variablesHelp = "Click on any variable to insert it into your stamp text. Use @@ for literal @."
|
||||
yearMonthDayDesc = "Individual date parts"
|
||||
|
||||
[AddStampRequest.error]
|
||||
failed = "Възникна грешка при добавяне на печат към PDF."
|
||||
@@ -3560,6 +3594,14 @@ failed = "Възникна грешка при добавяне на печат
|
||||
[AddStampRequest.results]
|
||||
title = "Резултати от печата"
|
||||
|
||||
[AddStampRequest.template]
|
||||
custom = "Custom"
|
||||
dateHeader = "Date Header"
|
||||
draftWatermark = "Draft Watermark"
|
||||
europeanDate = "European Date"
|
||||
pageNumberFooter = "Page Number Footer"
|
||||
timestamp = "Timestamp"
|
||||
|
||||
[removeImagePdf]
|
||||
tags = "Премахване на изображение, операции на страници, админ страна, страна на сървъра"
|
||||
|
||||
@@ -4526,6 +4568,13 @@ description = "Максимален брой неуспешни опити за
|
||||
label = "Време за нулиране на входа (минути)"
|
||||
description = "Време, преди неуспешните опити за вход да се нулират"
|
||||
|
||||
[admin.settings.security.xFrameOptions]
|
||||
label = "X-Frame-Options"
|
||||
description = "Controls whether the application can be embedded in iframes"
|
||||
deny = "Deny (Prevents all framing)"
|
||||
sameorigin = "Same Origin (Allow framing from same domain)"
|
||||
disabled = "Disabled (No X-Frame-Options header)"
|
||||
|
||||
[admin.settings.security.csrfDisabled]
|
||||
label = "Деактивирай CSRF защита"
|
||||
description = "Деактивира защита срещу Cross-Site Request Forgery (не се препоръчва)"
|
||||
|
||||
@@ -439,7 +439,9 @@ fullscreen = "བརྙན་ཤེལ་ཆ་ཚང་།"
|
||||
[settings.general.updates]
|
||||
title = "མཉེན་ཆས་གསར་བརྗེ།"
|
||||
description = "གསར་བརྗེའི་གནས་ཚུལ་ལ་ཞིབ་བཤེར་དང་ཐོན་རིམ་གྱི་ཆ་འཕྲིན་ལ་ལྟོས།"
|
||||
currentVersion = "ད་ལྟའི་ཐོན་རིམ།"
|
||||
currentBackendVersion = "Current Backend Version"
|
||||
currentFrontendVersion = "Current Frontend Version"
|
||||
versionMismatch = "Warning: A mismatch has been detected between the client version and the AppConfig version. Using different versions can lead to compatibility issues, errors, and security risks. Please ensure that server and client are using the same version."
|
||||
latestVersion = "ཐོན་རིམ་གསར་ཤོས།"
|
||||
checkForUpdates = "གསར་བརྗེ་ལ་ཞིབ་བཤེར།"
|
||||
viewDetails = "ཞིབ་ཕྲའི་གནས་ཚུལ་ལ་ལྟོས།"
|
||||
@@ -950,6 +952,7 @@ title = "ཆེ་ཆུང་/གྲངས་ཚད་ཀྱིས་རང་
|
||||
desc = "རང་འགུལ་གྱིས་ཡིག་ཆའི་ཆེ་ཆུང་དང་ཡང་ན་ཤོག་ངོས་གྲངས་ལ་གཞིགས་ནས་PDFsབགོད་དགོས།"
|
||||
|
||||
[home.replaceColor]
|
||||
tags = "replace color,invert color,color replacement,swap colors,change color,invert,negative,color swap,find and replace color,convert color,color change"
|
||||
title = "ཁ་དོག་བརྗེ་ལེན་དང་བསྒྱུར་བ།"
|
||||
desc = "PDFཡིག་ཆའི་ནང་ཁ་དོག་བརྗེ་ལེན་བྱེད་པའམ་ཡང་ན་བསྒྱུར་བ།"
|
||||
|
||||
@@ -964,18 +967,22 @@ title = "རང་འགུལ་ཅན་གྱི་སྣོད་བཅུ
|
||||
desc = "རང་འགུལ་སྣོད་ཀྱི་པར་བཤེར་ལམ་སྟོན་ལ་འབྲེལ་མཐུད་བྱེད།"
|
||||
|
||||
[home.devSsoGuide]
|
||||
tags = "SSO,single sign-on,authentication,SAML,OAuth,OIDC,login,enterprise,identity provider,IdP"
|
||||
title = "SSO ལམ་སྟོན།"
|
||||
desc = "SSO ལམ་སྟོན་ལ་འབྲེལ་མཐུད་བྱེད།"
|
||||
|
||||
[home.devAirgapped]
|
||||
tags = "air-gapped,offline,isolated,no internet,disconnected,secure,network isolation,standalone"
|
||||
title = "མཁའ་དབྱིངས་ཀྱི་ཆ་སྒྲིག་སྒྲིག་བཀོད།"
|
||||
desc = "མཁའ་རླུང་གི་བར་ཐག་གིས་སྒྲིག་པའི་སྒྲིག་ལམ་ལ་འབྲེལ་མཐུད་བྱེད་པ།"
|
||||
|
||||
[home.addPassword]
|
||||
tags = "encrypt,password,lock,secure,protect,security,encryption,safeguard,confidential,private,restrict access"
|
||||
title = "གསང་གྲངས་ཁ་སྣོན་བྱེད།"
|
||||
desc = "གསང་གྲངས་སྲུང་སྐྱོབ་དང་ཚད་བཀག་PDFཡིག་ཆ་ལ་ཁ་སྣོན་བྱེད་པ།"
|
||||
|
||||
[home.changePermissions]
|
||||
tags = "permissions,restrictions,rights,access control,allow,deny,printing,copying,editing,modify permissions,security settings,user rights"
|
||||
title = "འཕོ་འགྱུར།"
|
||||
desc = "ཡིག་ཆའི་ཚད་བཀག་དང་ཆོག་མཆན་བསྒྱུར་བ།"
|
||||
|
||||
@@ -985,10 +992,12 @@ title = "རང་འགུལ་ཅན།"
|
||||
desc = "གོམ་པ་མང་པོའི་ལས་ཀའི་འགྲོ་ལུགས་དེ་PDFབྱ་སྤྱོད་མཉམ་དུ་སྒྲིག་ནས་བཟོས། ལས་འགན་ཡང་བསྐྱར་འཚོག་པར་འཚམ་པོ་ཡོད།"
|
||||
|
||||
[home.overlay-pdfs]
|
||||
tags = "overlay,combine,merge,layer,superimpose,overlay PDF,layer PDFs,combine PDFs,stack,overlay pages,background,foreground,composite"
|
||||
desc = "གཞན་ཞིག་གི་སྟེང་དུ་PDFགཅིག་བཀབ་དགོས།"
|
||||
title = "བཀབ་པའི་PDFs"
|
||||
|
||||
[home.pdfTextEditor]
|
||||
tags = "edit text,modify text,change text,edit content,update text,rewrite,correct,amend,redline,revise,text editor,content editor"
|
||||
title = "PDFཡིག་འབྲིའི་རྩོམ་སྒྲིག་པ།"
|
||||
desc = "ད་ཡོད་ཀྱི་ཡིག་ཆ་དང་པར་རིས་PDFནང་དུ་རྩོམ་སྒྲིག་བྱས།"
|
||||
|
||||
@@ -3553,6 +3562,31 @@ imageSize = "པར་རིས་ཚད་གཞི།"
|
||||
margin = "མཐའ་ཤོག"
|
||||
positionAndFormatting = "ལས་གནས་དང་རྩ་སྒྲིག།"
|
||||
quickPosition = "ཤོག་ངོས་སྟེང་དུ་གནས་ཡུལ་ཞིག་འདེམས་ནས་མཚོན་རྟགས་འཇོག་དགོས།"
|
||||
clickToExpand = "Click to expand"
|
||||
customDateDesc = "Custom format"
|
||||
dateDesc = "Current date"
|
||||
dateTimeVars = "Date & Time"
|
||||
datetimeDesc = "Date and time combined"
|
||||
dynamicVariables = "Dynamic Variables"
|
||||
examples = "Examples"
|
||||
fileVars = "File Information"
|
||||
filenameDesc = "Filename without extension"
|
||||
filenameFullDesc = "Filename with extension"
|
||||
metadataDesc = "From PDF document properties"
|
||||
metadataVars = "Document Metadata"
|
||||
multiLine = "multi-line"
|
||||
otherVars = "Other"
|
||||
pageNumberDesc = "Current page number"
|
||||
pageVars = "Page Information"
|
||||
preview = "Preview:"
|
||||
selectTemplate = "Select a template..."
|
||||
stampTextDescription = "Use dynamic variables below. Use @@ for literal @. Use \\n for new lines."
|
||||
timeDesc = "Current time"
|
||||
totalPagesDesc = "Total number of pages"
|
||||
useTemplate = "Use Template"
|
||||
uuidDesc = "Short unique identifier (8 chars)"
|
||||
variablesHelp = "Click on any variable to insert it into your stamp text. Use @@ for literal @."
|
||||
yearMonthDayDesc = "Individual date parts"
|
||||
|
||||
[AddStampRequest.error]
|
||||
failed = "PDF ལ་མཚོན་རྟགས་ཁ་སྣོན་བྱེད་སྐབས་ནོར་འཁྲུལ་བྱུང་ཡོད།"
|
||||
@@ -3560,6 +3594,14 @@ failed = "PDF ལ་མཚོན་རྟགས་ཁ་སྣོན་བྱེ
|
||||
[AddStampRequest.results]
|
||||
title = "མཚོན་རྟགས་གྲུབ་འབྲས།"
|
||||
|
||||
[AddStampRequest.template]
|
||||
custom = "Custom"
|
||||
dateHeader = "Date Header"
|
||||
draftWatermark = "Draft Watermark"
|
||||
europeanDate = "European Date"
|
||||
pageNumberFooter = "Page Number Footer"
|
||||
timestamp = "Timestamp"
|
||||
|
||||
[removeImagePdf]
|
||||
tags = "པར་རིས་མེད་པར་བཟོས་པ། ཤོག་ངོས་བཀོལ་སྤྱོད། རྒྱབ་མཇུག་། ཞབས་ཞུ་པ།"
|
||||
|
||||
@@ -4526,6 +4568,13 @@ description = "རྩིས་ཁྲའི་བཀག་སྡོམ་མ་
|
||||
label = "ནང་འཇུག་བསྐྱར་སྒྲིག་དུས་ཚོད།"
|
||||
description = "ནང་འཇུག་ཚོད་ལྟ་འཐུས་ཤོར་མ་བྱུང་གོང་གི་དུས་ཚོད།"
|
||||
|
||||
[admin.settings.security.xFrameOptions]
|
||||
label = "X-Frame-Options"
|
||||
description = "Controls whether the application can be embedded in iframes"
|
||||
deny = "Deny (Prevents all framing)"
|
||||
sameorigin = "Same Origin (Allow framing from same domain)"
|
||||
disabled = "Disabled (No X-Frame-Options header)"
|
||||
|
||||
[admin.settings.security.csrfDisabled]
|
||||
label = "CSRF སྲུང་སྐྱོབ།"
|
||||
description = "ས་ཁོངས་བརྒལ་བའི་རེ་འདུན་རྫུན་བཟོ་སྲུང་སྐྱོབ།"
|
||||
|
||||
@@ -439,7 +439,9 @@ fullscreen = "Pantalla completa"
|
||||
[settings.general.updates]
|
||||
title = "Actualitzacions de programari"
|
||||
description = "Comprova actualitzacions i informació de la versió"
|
||||
currentVersion = "Versió actual"
|
||||
currentBackendVersion = "Current Backend Version"
|
||||
currentFrontendVersion = "Current Frontend Version"
|
||||
versionMismatch = "Warning: A mismatch has been detected between the client version and the AppConfig version. Using different versions can lead to compatibility issues, errors, and security risks. Please ensure that server and client are using the same version."
|
||||
latestVersion = "Última versió"
|
||||
checkForUpdates = "Comprova actualitzacions"
|
||||
viewDetails = "Veure detalls"
|
||||
@@ -950,6 +952,7 @@ title = "Divideix auto per mida/pàg."
|
||||
desc = "Divideix un únic PDF en múltiples documents basant-se en la mida, el nombre de pàgines o el nombre de documents"
|
||||
|
||||
[home.replaceColor]
|
||||
tags = "replace color,invert color,color replacement,swap colors,change color,invert,negative,color swap,find and replace color,convert color,color change"
|
||||
title = "Substitueix i inverteix el color"
|
||||
desc = "Substitueix o inverteix colors en documents PDF"
|
||||
|
||||
@@ -964,18 +967,22 @@ title = "Escaneig automàtic de carpeta"
|
||||
desc = "Enllaç a la guia d'escaneig automàtic de carpetes"
|
||||
|
||||
[home.devSsoGuide]
|
||||
tags = "SSO,single sign-on,authentication,SAML,OAuth,OIDC,login,enterprise,identity provider,IdP"
|
||||
title = "Guia d'SSO"
|
||||
desc = "Enllaç a la guia d'SSO"
|
||||
|
||||
[home.devAirgapped]
|
||||
tags = "air-gapped,offline,isolated,no internet,disconnected,secure,network isolation,standalone"
|
||||
title = "Configuració air-gapped"
|
||||
desc = "Enllaç a la guia de configuració en entorn air-gapped"
|
||||
|
||||
[home.addPassword]
|
||||
tags = "encrypt,password,lock,secure,protect,security,encryption,safeguard,confidential,private,restrict access"
|
||||
title = "Afegir Contrasenya"
|
||||
desc = "Xifra el document PDF amb contrasenya."
|
||||
|
||||
[home.changePermissions]
|
||||
tags = "permissions,restrictions,rights,access control,allow,deny,printing,copying,editing,modify permissions,security settings,user rights"
|
||||
title = "Canviar Permissos"
|
||||
desc = "Canvia les restriccions i els permisos del document"
|
||||
|
||||
@@ -985,10 +992,12 @@ title = "Automatitza"
|
||||
desc = "Construeix fluxos de treball multietapa enllaçant accions PDF. Ideal per a tasques recurrents."
|
||||
|
||||
[home.overlay-pdfs]
|
||||
tags = "overlay,combine,merge,layer,superimpose,overlay PDF,layer PDFs,combine PDFs,stack,overlay pages,background,foreground,composite"
|
||||
desc = "Superposa PDFs sobre un altre PDF"
|
||||
title = "Superposar PDFs"
|
||||
|
||||
[home.pdfTextEditor]
|
||||
tags = "edit text,modify text,change text,edit content,update text,rewrite,correct,amend,redline,revise,text editor,content editor"
|
||||
title = "Editor de text PDF"
|
||||
desc = "Revisa i edita exportacions JSON de Stirling PDF amb edició de text agrupada i regeneració del PDF"
|
||||
|
||||
@@ -3553,6 +3562,31 @@ imageSize = "Mida de la imatge"
|
||||
margin = "Marge"
|
||||
positionAndFormatting = "Posició i format"
|
||||
quickPosition = "Seleccioneu una posició a la pàgina per col·locar el segell."
|
||||
clickToExpand = "Click to expand"
|
||||
customDateDesc = "Custom format"
|
||||
dateDesc = "Current date"
|
||||
dateTimeVars = "Date & Time"
|
||||
datetimeDesc = "Date and time combined"
|
||||
dynamicVariables = "Dynamic Variables"
|
||||
examples = "Examples"
|
||||
fileVars = "File Information"
|
||||
filenameDesc = "Filename without extension"
|
||||
filenameFullDesc = "Filename with extension"
|
||||
metadataDesc = "From PDF document properties"
|
||||
metadataVars = "Document Metadata"
|
||||
multiLine = "multi-line"
|
||||
otherVars = "Other"
|
||||
pageNumberDesc = "Current page number"
|
||||
pageVars = "Page Information"
|
||||
preview = "Preview:"
|
||||
selectTemplate = "Select a template..."
|
||||
stampTextDescription = "Use dynamic variables below. Use @@ for literal @. Use \\n for new lines."
|
||||
timeDesc = "Current time"
|
||||
totalPagesDesc = "Total number of pages"
|
||||
useTemplate = "Use Template"
|
||||
uuidDesc = "Short unique identifier (8 chars)"
|
||||
variablesHelp = "Click on any variable to insert it into your stamp text. Use @@ for literal @."
|
||||
yearMonthDayDesc = "Individual date parts"
|
||||
|
||||
[AddStampRequest.error]
|
||||
failed = "S'ha produït un error en afegir el segell al PDF."
|
||||
@@ -3560,6 +3594,14 @@ failed = "S'ha produït un error en afegir el segell al PDF."
|
||||
[AddStampRequest.results]
|
||||
title = "Resultats del segell"
|
||||
|
||||
[AddStampRequest.template]
|
||||
custom = "Custom"
|
||||
dateHeader = "Date Header"
|
||||
draftWatermark = "Draft Watermark"
|
||||
europeanDate = "European Date"
|
||||
pageNumberFooter = "Page Number Footer"
|
||||
timestamp = "Timestamp"
|
||||
|
||||
[removeImagePdf]
|
||||
tags = "Elimina imatge,Operacions de pàgina,Back-end,Servidor"
|
||||
|
||||
@@ -4526,6 +4568,13 @@ description = "Nombre màxim d'intents d'inici de sessió fallits abans de bloqu
|
||||
label = "Temps de reinicialització d'inici de sessió (minuts)"
|
||||
description = "Temps abans que es restableixin els intents d'inici de sessió fallits"
|
||||
|
||||
[admin.settings.security.xFrameOptions]
|
||||
label = "X-Frame-Options"
|
||||
description = "Controls whether the application can be embedded in iframes"
|
||||
deny = "Deny (Prevents all framing)"
|
||||
sameorigin = "Same Origin (Allow framing from same domain)"
|
||||
disabled = "Disabled (No X-Frame-Options header)"
|
||||
|
||||
[admin.settings.security.csrfDisabled]
|
||||
label = "Desactiva la protecció CSRF"
|
||||
description = "Desactiva la protecció contra Cross-Site Request Forgery (no recomanat)"
|
||||
|
||||
@@ -439,7 +439,9 @@ fullscreen = "Celá obrazovka"
|
||||
[settings.general.updates]
|
||||
title = "Aktualizace softwaru"
|
||||
description = "Zkontrolujte aktualizace a zobrazte informace o verzi"
|
||||
currentVersion = "Aktuální verze"
|
||||
currentBackendVersion = "Current Backend Version"
|
||||
currentFrontendVersion = "Current Frontend Version"
|
||||
versionMismatch = "Warning: A mismatch has been detected between the client version and the AppConfig version. Using different versions can lead to compatibility issues, errors, and security risks. Please ensure that server and client are using the same version."
|
||||
latestVersion = "Nejnovější verze"
|
||||
checkForUpdates = "Zkontrolovat aktualizace"
|
||||
viewDetails = "Zobrazit podrobnosti"
|
||||
@@ -950,6 +952,7 @@ title = "Automaticky rozdělit podle velikosti/počtu"
|
||||
desc = "Rozdělí jeden PDF na více dokumentů podle velikosti, počtu stránek nebo počtu dokumentů"
|
||||
|
||||
[home.replaceColor]
|
||||
tags = "replace color,invert color,color replacement,swap colors,change color,invert,negative,color swap,find and replace color,convert color,color change"
|
||||
title = "Nahradit a invertovat barvy"
|
||||
desc = "Nahradit nebo invertovat barvy v dokumentech PDF"
|
||||
|
||||
@@ -964,18 +967,22 @@ title = "Autom. skenování složek"
|
||||
desc = "Odkaz na průvodce automatizovaným skenováním složek"
|
||||
|
||||
[home.devSsoGuide]
|
||||
tags = "SSO,single sign-on,authentication,SAML,OAuth,OIDC,login,enterprise,identity provider,IdP"
|
||||
title = "Průvodce SSO"
|
||||
desc = "Odkaz na průvodce SSO"
|
||||
|
||||
[home.devAirgapped]
|
||||
tags = "air-gapped,offline,isolated,no internet,disconnected,secure,network isolation,standalone"
|
||||
title = "Offline nastavení"
|
||||
desc = "Odkaz na průvodce nastavením v odpojeném prostředí"
|
||||
|
||||
[home.addPassword]
|
||||
tags = "encrypt,password,lock,secure,protect,security,encryption,safeguard,confidential,private,restrict access"
|
||||
title = "Přidat heslo"
|
||||
desc = "Zašifrovat váš PDF dokument heslem."
|
||||
|
||||
[home.changePermissions]
|
||||
tags = "permissions,restrictions,rights,access control,allow,deny,printing,copying,editing,modify permissions,security settings,user rights"
|
||||
title = "Změnit oprávnění"
|
||||
desc = "Změnit omezení a oprávnění dokumentu"
|
||||
|
||||
@@ -985,10 +992,12 @@ title = "Automatizace"
|
||||
desc = "Vytvářejte vícekrokové workflow řetězením akcí PDF. Ideální pro opakující se úlohy."
|
||||
|
||||
[home.overlay-pdfs]
|
||||
tags = "overlay,combine,merge,layer,superimpose,overlay PDF,layer PDFs,combine PDFs,stack,overlay pages,background,foreground,composite"
|
||||
desc = "Překryje PDF nad jiným PDF"
|
||||
title = "Překrýt PDF"
|
||||
|
||||
[home.pdfTextEditor]
|
||||
tags = "edit text,modify text,change text,edit content,update text,rewrite,correct,amend,redline,revise,text editor,content editor"
|
||||
title = "Editor textu PDF"
|
||||
desc = "Prohlížejte a upravujte exporty JSON ze Stirling PDF se skupinovými úpravami textu a regenerací PDF"
|
||||
|
||||
@@ -3553,6 +3562,31 @@ imageSize = "Velikost obrázku"
|
||||
margin = "Okraj"
|
||||
positionAndFormatting = "Umístění a formátování"
|
||||
quickPosition = "Vyberte na stránce pozici pro umístění razítka."
|
||||
clickToExpand = "Click to expand"
|
||||
customDateDesc = "Custom format"
|
||||
dateDesc = "Current date"
|
||||
dateTimeVars = "Date & Time"
|
||||
datetimeDesc = "Date and time combined"
|
||||
dynamicVariables = "Dynamic Variables"
|
||||
examples = "Examples"
|
||||
fileVars = "File Information"
|
||||
filenameDesc = "Filename without extension"
|
||||
filenameFullDesc = "Filename with extension"
|
||||
metadataDesc = "From PDF document properties"
|
||||
metadataVars = "Document Metadata"
|
||||
multiLine = "multi-line"
|
||||
otherVars = "Other"
|
||||
pageNumberDesc = "Current page number"
|
||||
pageVars = "Page Information"
|
||||
preview = "Preview:"
|
||||
selectTemplate = "Select a template..."
|
||||
stampTextDescription = "Use dynamic variables below. Use @@ for literal @. Use \\n for new lines."
|
||||
timeDesc = "Current time"
|
||||
totalPagesDesc = "Total number of pages"
|
||||
useTemplate = "Use Template"
|
||||
uuidDesc = "Short unique identifier (8 chars)"
|
||||
variablesHelp = "Click on any variable to insert it into your stamp text. Use @@ for literal @."
|
||||
yearMonthDayDesc = "Individual date parts"
|
||||
|
||||
[AddStampRequest.error]
|
||||
failed = "Při přidávání razítka do PDF došlo k chybě."
|
||||
@@ -3560,6 +3594,14 @@ failed = "Při přidávání razítka do PDF došlo k chybě."
|
||||
[AddStampRequest.results]
|
||||
title = "Výsledky razítka"
|
||||
|
||||
[AddStampRequest.template]
|
||||
custom = "Custom"
|
||||
dateHeader = "Date Header"
|
||||
draftWatermark = "Draft Watermark"
|
||||
europeanDate = "European Date"
|
||||
pageNumberFooter = "Page Number Footer"
|
||||
timestamp = "Timestamp"
|
||||
|
||||
[removeImagePdf]
|
||||
tags = "Odstranit obrázek,Operace stránek,zadní strana,serverová strana"
|
||||
|
||||
@@ -4526,6 +4568,13 @@ description = "Maximální počet neúspěšných pokusů o přihlášení před
|
||||
label = "Čas pro reset přihlášení (minuty)"
|
||||
description = "Doba, po které se neúspěšné pokusy o přihlášení resetují"
|
||||
|
||||
[admin.settings.security.xFrameOptions]
|
||||
label = "X-Frame-Options"
|
||||
description = "Controls whether the application can be embedded in iframes"
|
||||
deny = "Deny (Prevents all framing)"
|
||||
sameorigin = "Same Origin (Allow framing from same domain)"
|
||||
disabled = "Disabled (No X-Frame-Options header)"
|
||||
|
||||
[admin.settings.security.csrfDisabled]
|
||||
label = "Zakázat ochranu CSRF"
|
||||
description = "Zakázat ochranu proti Cross-Site Request Forgery (nedoporučuje se)"
|
||||
|
||||
@@ -439,7 +439,9 @@ fullscreen = "Fuldskærm"
|
||||
[settings.general.updates]
|
||||
title = "Softwareopdateringer"
|
||||
description = "Søg efter opdateringer og se versionsinfo"
|
||||
currentVersion = "Nuværende version"
|
||||
currentBackendVersion = "Current Backend Version"
|
||||
currentFrontendVersion = "Current Frontend Version"
|
||||
versionMismatch = "Warning: A mismatch has been detected between the client version and the AppConfig version. Using different versions can lead to compatibility issues, errors, and security risks. Please ensure that server and client are using the same version."
|
||||
latestVersion = "Seneste version"
|
||||
checkForUpdates = "Søg efter opdateringer"
|
||||
viewDetails = "Vis detaljer"
|
||||
@@ -950,6 +952,7 @@ title = "Auto-opdel størrelse/antal"
|
||||
desc = "Opdel en enkelt PDF i flere dokumenter baseret på størrelse, sideantal eller dokumentantal"
|
||||
|
||||
[home.replaceColor]
|
||||
tags = "replace color,invert color,color replacement,swap colors,change color,invert,negative,color swap,find and replace color,convert color,color change"
|
||||
title = "Erstat og inverter farver"
|
||||
desc = "Erstat eller inverter farver i PDF-dokumenter"
|
||||
|
||||
@@ -964,18 +967,22 @@ title = "Automatiseret mappescanning"
|
||||
desc = "Link til guide for automatiseret mappescanning"
|
||||
|
||||
[home.devSsoGuide]
|
||||
tags = "SSO,single sign-on,authentication,SAML,OAuth,OIDC,login,enterprise,identity provider,IdP"
|
||||
title = "SSO-vejledning"
|
||||
desc = "Link til SSO-vejledning"
|
||||
|
||||
[home.devAirgapped]
|
||||
tags = "air-gapped,offline,isolated,no internet,disconnected,secure,network isolation,standalone"
|
||||
title = "Air-gapped opsætning"
|
||||
desc = "Link til guide for air-gapped opsætning"
|
||||
|
||||
[home.addPassword]
|
||||
tags = "encrypt,password,lock,secure,protect,security,encryption,safeguard,confidential,private,restrict access"
|
||||
title = "Tilføj Adgangskode"
|
||||
desc = "Kryptér dit PDF-dokument med en adgangskode."
|
||||
|
||||
[home.changePermissions]
|
||||
tags = "permissions,restrictions,rights,access control,allow,deny,printing,copying,editing,modify permissions,security settings,user rights"
|
||||
title = "Ændre Tilladelser"
|
||||
desc = "Ændr dokumentbegrænsninger og tilladelser"
|
||||
|
||||
@@ -985,10 +992,12 @@ title = "Automatiser"
|
||||
desc = "Byg flertrins-workflows ved at kæde PDF-handlinger sammen. Ideelt til tilbagevendende opgaver."
|
||||
|
||||
[home.overlay-pdfs]
|
||||
tags = "overlay,combine,merge,layer,superimpose,overlay PDF,layer PDFs,combine PDFs,stack,overlay pages,background,foreground,composite"
|
||||
desc = "Overlejrer PDF'er oven på en anden PDF"
|
||||
title = "Overlejr PDF'er"
|
||||
|
||||
[home.pdfTextEditor]
|
||||
tags = "edit text,modify text,change text,edit content,update text,rewrite,correct,amend,redline,revise,text editor,content editor"
|
||||
title = "PDF-teksteditor"
|
||||
desc = "Gennemse og rediger Stirling PDF JSON-eksporter med grupperet tekstredigering og regenerering af PDF"
|
||||
|
||||
@@ -3553,6 +3562,31 @@ imageSize = "Billedstørrelse"
|
||||
margin = "Margen"
|
||||
positionAndFormatting = "Placering og formatering"
|
||||
quickPosition = "Vælg en placering på siden til stemplet."
|
||||
clickToExpand = "Click to expand"
|
||||
customDateDesc = "Custom format"
|
||||
dateDesc = "Current date"
|
||||
dateTimeVars = "Date & Time"
|
||||
datetimeDesc = "Date and time combined"
|
||||
dynamicVariables = "Dynamic Variables"
|
||||
examples = "Examples"
|
||||
fileVars = "File Information"
|
||||
filenameDesc = "Filename without extension"
|
||||
filenameFullDesc = "Filename with extension"
|
||||
metadataDesc = "From PDF document properties"
|
||||
metadataVars = "Document Metadata"
|
||||
multiLine = "multi-line"
|
||||
otherVars = "Other"
|
||||
pageNumberDesc = "Current page number"
|
||||
pageVars = "Page Information"
|
||||
preview = "Preview:"
|
||||
selectTemplate = "Select a template..."
|
||||
stampTextDescription = "Use dynamic variables below. Use @@ for literal @. Use \\n for new lines."
|
||||
timeDesc = "Current time"
|
||||
totalPagesDesc = "Total number of pages"
|
||||
useTemplate = "Use Template"
|
||||
uuidDesc = "Short unique identifier (8 chars)"
|
||||
variablesHelp = "Click on any variable to insert it into your stamp text. Use @@ for literal @."
|
||||
yearMonthDayDesc = "Individual date parts"
|
||||
|
||||
[AddStampRequest.error]
|
||||
failed = "Der opstod en fejl under tilføjelse af stempel til PDF'en."
|
||||
@@ -3560,6 +3594,14 @@ failed = "Der opstod en fejl under tilføjelse af stempel til PDF'en."
|
||||
[AddStampRequest.results]
|
||||
title = "Stempelresultater"
|
||||
|
||||
[AddStampRequest.template]
|
||||
custom = "Custom"
|
||||
dateHeader = "Date Header"
|
||||
draftWatermark = "Draft Watermark"
|
||||
europeanDate = "European Date"
|
||||
pageNumberFooter = "Page Number Footer"
|
||||
timestamp = "Timestamp"
|
||||
|
||||
[removeImagePdf]
|
||||
tags = "Fjern Billede,Sideoperationer,Back end,server side"
|
||||
|
||||
@@ -4526,6 +4568,13 @@ description = "Maksimalt antal mislykkede loginforsøg før kontolock"
|
||||
label = "Nulstil login (minutter)"
|
||||
description = "Tid før mislykkede loginforsøg nulstilles"
|
||||
|
||||
[admin.settings.security.xFrameOptions]
|
||||
label = "X-Frame-Options"
|
||||
description = "Controls whether the application can be embedded in iframes"
|
||||
deny = "Deny (Prevents all framing)"
|
||||
sameorigin = "Same Origin (Allow framing from same domain)"
|
||||
disabled = "Disabled (No X-Frame-Options header)"
|
||||
|
||||
[admin.settings.security.csrfDisabled]
|
||||
label = "Deaktivér CSRF-beskyttelse"
|
||||
description = "Deaktivér Cross-Site Request Forgery-beskyttelse (anbefales ikke)"
|
||||
|
||||
@@ -439,7 +439,9 @@ fullscreen = "Vollbild"
|
||||
[settings.general.updates]
|
||||
title = "Software-Updates"
|
||||
description = "Nach Updates suchen und Versionsinformationen anzeigen"
|
||||
currentVersion = "Aktuelle Version"
|
||||
currentBackendVersion = "Current Backend Version"
|
||||
currentFrontendVersion = "Current Frontend Version"
|
||||
versionMismatch = "Warning: A mismatch has been detected between the client version and the AppConfig version. Using different versions can lead to compatibility issues, errors, and security risks. Please ensure that server and client are using the same version."
|
||||
latestVersion = "Neueste Version"
|
||||
checkForUpdates = "Nach Updates suchen"
|
||||
viewDetails = "Details anzeigen"
|
||||
@@ -950,6 +952,7 @@ title = "Teilen nach Größe/Anzahl"
|
||||
desc = "Teilen Sie ein einzelnes PDF basierend auf Größe, Seitenanzahl oder Dokumentanzahl in mehrere Dokumente auf"
|
||||
|
||||
[home.replaceColor]
|
||||
tags = "replace color,invert color,color replacement,swap colors,change color,invert,negative,color swap,find and replace color,convert color,color change"
|
||||
title = "Farbe ersetzen & invertieren"
|
||||
desc = "Farben in PDF-Dokumenten ersetzen oder invertieren"
|
||||
|
||||
@@ -964,18 +967,22 @@ title = "Autom. Ordner-Scan"
|
||||
desc = "Link zum Leitfaden für automatisches Ordner-Scannen"
|
||||
|
||||
[home.devSsoGuide]
|
||||
tags = "SSO,single sign-on,authentication,SAML,OAuth,OIDC,login,enterprise,identity provider,IdP"
|
||||
title = "SSO-Anleitung"
|
||||
desc = "Link zum SSO-Leitfaden"
|
||||
|
||||
[home.devAirgapped]
|
||||
tags = "air-gapped,offline,isolated,no internet,disconnected,secure,network isolation,standalone"
|
||||
title = "Offline-Setup"
|
||||
desc = "Link zum Air-Gap-Einrichtungsleitfaden"
|
||||
|
||||
[home.addPassword]
|
||||
tags = "encrypt,password,lock,secure,protect,security,encryption,safeguard,confidential,private,restrict access"
|
||||
title = "Passwort hinzufügen"
|
||||
desc = "Das PDF mit einem Passwort verschlüsseln"
|
||||
|
||||
[home.changePermissions]
|
||||
tags = "permissions,restrictions,rights,access control,allow,deny,printing,copying,editing,modify permissions,security settings,user rights"
|
||||
title = "Berechtigungen ändern"
|
||||
desc = "Dokumentbeschränkungen und -berechtigungen ändern"
|
||||
|
||||
@@ -985,10 +992,12 @@ title = "Automatisieren"
|
||||
desc = "Mehrstufige Arbeitsabläufe durch Verkettung von PDF-Aktionen erstellen. Ideal für wiederkehrende Aufgaben."
|
||||
|
||||
[home.overlay-pdfs]
|
||||
tags = "overlay,combine,merge,layer,superimpose,overlay PDF,layer PDFs,combine PDFs,stack,overlay pages,background,foreground,composite"
|
||||
desc = "Ein PDF über ein anderes legen"
|
||||
title = "PDFs überlagern"
|
||||
|
||||
[home.pdfTextEditor]
|
||||
tags = "edit text,modify text,change text,edit content,update text,rewrite,correct,amend,redline,revise,text editor,content editor"
|
||||
title = "PDF-Texteditor"
|
||||
desc = "Vorhandenen Text und Bilder in PDFs bearbeiten"
|
||||
|
||||
@@ -3553,6 +3562,31 @@ imageSize = "Bildgröße"
|
||||
margin = "Rand"
|
||||
positionAndFormatting = "Position & Formatierung"
|
||||
quickPosition = "Wählen Sie eine Position auf der Seite, um den Stempel zu platzieren."
|
||||
clickToExpand = "Click to expand"
|
||||
customDateDesc = "Custom format"
|
||||
dateDesc = "Current date"
|
||||
dateTimeVars = "Date & Time"
|
||||
datetimeDesc = "Date and time combined"
|
||||
dynamicVariables = "Dynamic Variables"
|
||||
examples = "Examples"
|
||||
fileVars = "File Information"
|
||||
filenameDesc = "Filename without extension"
|
||||
filenameFullDesc = "Filename with extension"
|
||||
metadataDesc = "From PDF document properties"
|
||||
metadataVars = "Document Metadata"
|
||||
multiLine = "multi-line"
|
||||
otherVars = "Other"
|
||||
pageNumberDesc = "Current page number"
|
||||
pageVars = "Page Information"
|
||||
preview = "Preview:"
|
||||
selectTemplate = "Select a template..."
|
||||
stampTextDescription = "Use dynamic variables below. Use @@ for literal @. Use \\n for new lines."
|
||||
timeDesc = "Current time"
|
||||
totalPagesDesc = "Total number of pages"
|
||||
useTemplate = "Use Template"
|
||||
uuidDesc = "Short unique identifier (8 chars)"
|
||||
variablesHelp = "Click on any variable to insert it into your stamp text. Use @@ for literal @."
|
||||
yearMonthDayDesc = "Individual date parts"
|
||||
|
||||
[AddStampRequest.error]
|
||||
failed = "Beim Hinzufügen des Stempels zum PDF ist ein Fehler aufgetreten."
|
||||
@@ -3560,6 +3594,14 @@ failed = "Beim Hinzufügen des Stempels zum PDF ist ein Fehler aufgetreten."
|
||||
[AddStampRequest.results]
|
||||
title = "Stempel-Ergebnisse"
|
||||
|
||||
[AddStampRequest.template]
|
||||
custom = "Custom"
|
||||
dateHeader = "Date Header"
|
||||
draftWatermark = "Draft Watermark"
|
||||
europeanDate = "European Date"
|
||||
pageNumberFooter = "Page Number Footer"
|
||||
timestamp = "Timestamp"
|
||||
|
||||
[removeImagePdf]
|
||||
tags = "bild entfernen,seitenoperationen,back end,server side"
|
||||
|
||||
@@ -4526,6 +4568,13 @@ description = "Maximale Anzahl fehlgeschlagener Anmeldeversuche vor Kontosperre"
|
||||
label = "Zurücksetzungszeit für Anmeldungen (Minuten)"
|
||||
description = "Zeit, nach der fehlgeschlagene Anmeldeversuche zurückgesetzt werden"
|
||||
|
||||
[admin.settings.security.xFrameOptions]
|
||||
label = "X-Frame-Options"
|
||||
description = "Controls whether the application can be embedded in iframes"
|
||||
deny = "Deny (Prevents all framing)"
|
||||
sameorigin = "Same Origin (Allow framing from same domain)"
|
||||
disabled = "Disabled (No X-Frame-Options header)"
|
||||
|
||||
[admin.settings.security.csrfDisabled]
|
||||
label = "CSRF-Schutz deaktivieren"
|
||||
description = "Cross-Site Request Forgery-Schutz deaktivieren (nicht empfohlen)"
|
||||
|
||||
@@ -439,7 +439,9 @@ fullscreen = "Πλήρης οθόνη"
|
||||
[settings.general.updates]
|
||||
title = "Ενημερώσεις λογισμικού"
|
||||
description = "Έλεγχος ενημερώσεων και προβολή πληροφοριών έκδοσης"
|
||||
currentVersion = "Τρέχουσα έκδοση"
|
||||
currentBackendVersion = "Current Backend Version"
|
||||
currentFrontendVersion = "Current Frontend Version"
|
||||
versionMismatch = "Warning: A mismatch has been detected between the client version and the AppConfig version. Using different versions can lead to compatibility issues, errors, and security risks. Please ensure that server and client are using the same version."
|
||||
latestVersion = "Νεότερη έκδοση"
|
||||
checkForUpdates = "Έλεγχος για ενημερώσεις"
|
||||
viewDetails = "Προβολή λεπτομερειών"
|
||||
@@ -950,6 +952,7 @@ title = "Αυτόματο σπάσιμο με μέγεθος/σελ."
|
||||
desc = "Διαχωρισμός ενός PDF σε πολλαπλά έγγραφα βάσει μεγέθους, αριθμού σελίδων ή αριθμού εγγράφων"
|
||||
|
||||
[home.replaceColor]
|
||||
tags = "replace color,invert color,color replacement,swap colors,change color,invert,negative,color swap,find and replace color,convert color,color change"
|
||||
title = "Αλλαγή & αντιστροφή χρώματος"
|
||||
desc = "Αντικαταστήστε ή αντιστρέψτε χρώματα σε έγγραφα PDF"
|
||||
|
||||
@@ -964,18 +967,22 @@ title = "Αυτόματη σάρωση φακέλων"
|
||||
desc = "Σύνδεσμος προς τον οδηγό αυτοματοποιημένης σάρωσης φακέλων"
|
||||
|
||||
[home.devSsoGuide]
|
||||
tags = "SSO,single sign-on,authentication,SAML,OAuth,OIDC,login,enterprise,identity provider,IdP"
|
||||
title = "Οδηγός SSO"
|
||||
desc = "Σύνδεσμος προς τον οδηγό SSO"
|
||||
|
||||
[home.devAirgapped]
|
||||
tags = "air-gapped,offline,isolated,no internet,disconnected,secure,network isolation,standalone"
|
||||
title = "Ρύθμιση Air-gapped"
|
||||
desc = "Σύνδεσμος προς τον οδηγό ρύθμισης Air-gapped"
|
||||
|
||||
[home.addPassword]
|
||||
tags = "encrypt,password,lock,secure,protect,security,encryption,safeguard,confidential,private,restrict access"
|
||||
title = "Προσθήκη κωδικού"
|
||||
desc = "Κρυπτογράφηση του εγγράφου PDF με κωδικό."
|
||||
|
||||
[home.changePermissions]
|
||||
tags = "permissions,restrictions,rights,access control,allow,deny,printing,copying,editing,modify permissions,security settings,user rights"
|
||||
title = "Αλλαγή δικαιωμάτων"
|
||||
desc = "Αλλαγή περιορισμών και δικαιωμάτων εγγράφου"
|
||||
|
||||
@@ -985,10 +992,12 @@ title = "Αυτοματοποίηση"
|
||||
desc = "Δημιουργήστε ροές πολλών βημάτων συνδέοντας ενέργειες PDF. Ιδανικό για επαναλαμβανόμενες εργασίες."
|
||||
|
||||
[home.overlay-pdfs]
|
||||
tags = "overlay,combine,merge,layer,superimpose,overlay PDF,layer PDFs,combine PDFs,stack,overlay pages,background,foreground,composite"
|
||||
desc = "Επικάλυψη PDF πάνω σε άλλο PDF"
|
||||
title = "Επικάλυψη PDF"
|
||||
|
||||
[home.pdfTextEditor]
|
||||
tags = "edit text,modify text,change text,edit content,update text,rewrite,correct,amend,redline,revise,text editor,content editor"
|
||||
title = "Επεξεργαστής κειμένου PDF"
|
||||
desc = "Επιθεωρήστε και επεξεργαστείτε εξαγωγές JSON του Stirling PDF με ομαδοποιημένη επεξεργασία κειμένου και αναδημιουργία PDF"
|
||||
|
||||
@@ -3553,6 +3562,31 @@ imageSize = "Μέγεθος εικόνας"
|
||||
margin = "Περιθώριο"
|
||||
positionAndFormatting = "Θέση & μορφοποίηση"
|
||||
quickPosition = "Επιλέξτε μια θέση στη σελίδα για τοποθέτηση της σφραγίδας."
|
||||
clickToExpand = "Click to expand"
|
||||
customDateDesc = "Custom format"
|
||||
dateDesc = "Current date"
|
||||
dateTimeVars = "Date & Time"
|
||||
datetimeDesc = "Date and time combined"
|
||||
dynamicVariables = "Dynamic Variables"
|
||||
examples = "Examples"
|
||||
fileVars = "File Information"
|
||||
filenameDesc = "Filename without extension"
|
||||
filenameFullDesc = "Filename with extension"
|
||||
metadataDesc = "From PDF document properties"
|
||||
metadataVars = "Document Metadata"
|
||||
multiLine = "multi-line"
|
||||
otherVars = "Other"
|
||||
pageNumberDesc = "Current page number"
|
||||
pageVars = "Page Information"
|
||||
preview = "Preview:"
|
||||
selectTemplate = "Select a template..."
|
||||
stampTextDescription = "Use dynamic variables below. Use @@ for literal @. Use \\n for new lines."
|
||||
timeDesc = "Current time"
|
||||
totalPagesDesc = "Total number of pages"
|
||||
useTemplate = "Use Template"
|
||||
uuidDesc = "Short unique identifier (8 chars)"
|
||||
variablesHelp = "Click on any variable to insert it into your stamp text. Use @@ for literal @."
|
||||
yearMonthDayDesc = "Individual date parts"
|
||||
|
||||
[AddStampRequest.error]
|
||||
failed = "Παρουσιάστηκε σφάλμα κατά την προσθήκη σφραγίδας στο PDF."
|
||||
@@ -3560,6 +3594,14 @@ failed = "Παρουσιάστηκε σφάλμα κατά την προσθήκ
|
||||
[AddStampRequest.results]
|
||||
title = "Αποτελέσματα σφράγισης"
|
||||
|
||||
[AddStampRequest.template]
|
||||
custom = "Custom"
|
||||
dateHeader = "Date Header"
|
||||
draftWatermark = "Draft Watermark"
|
||||
europeanDate = "European Date"
|
||||
pageNumberFooter = "Page Number Footer"
|
||||
timestamp = "Timestamp"
|
||||
|
||||
[removeImagePdf]
|
||||
tags = "αφαίρεση εικόνας,λειτουργίες σελίδας,backend,server side"
|
||||
|
||||
@@ -4526,6 +4568,13 @@ description = "Μέγιστος αριθμός αποτυχημένων προσ
|
||||
label = "Χρόνος επαναφοράς σύνδεσης (λεπτά)"
|
||||
description = "Χρόνος πριν μηδενιστούν οι αποτυχημένες προσπάθειες σύνδεσης"
|
||||
|
||||
[admin.settings.security.xFrameOptions]
|
||||
label = "X-Frame-Options"
|
||||
description = "Controls whether the application can be embedded in iframes"
|
||||
deny = "Deny (Prevents all framing)"
|
||||
sameorigin = "Same Origin (Allow framing from same domain)"
|
||||
disabled = "Disabled (No X-Frame-Options header)"
|
||||
|
||||
[admin.settings.security.csrfDisabled]
|
||||
label = "Απενεργοποίηση προστασίας CSRF"
|
||||
description = "Απενεργοποίηση προστασίας Cross-Site Request Forgery (δεν συνιστάται)"
|
||||
|
||||
@@ -219,6 +219,9 @@ pagesAndStarting = "Pages & Starting Number"
|
||||
positionAndPages = "Position & Pages"
|
||||
preview = "Position Selection"
|
||||
previewDisclaimer = "Preview is approximate. Final output may vary due to PDF font metrics."
|
||||
zeroPad = "Zero‑pad Width (Bates Stamping)"
|
||||
zeroPadTooltip = "Zero‑pad (Bates Stamp) page numbers to this width (e.g., 3 ⇒ 001). Set 0 to disable."
|
||||
|
||||
|
||||
[addPageNumbers.selectText]
|
||||
1 = "Select PDF file:"
|
||||
@@ -439,7 +442,9 @@ fullscreen = "Fullscreen"
|
||||
[settings.general.updates]
|
||||
title = "Software Updates"
|
||||
description = "Check for updates and view version information"
|
||||
currentVersion = "Current Version"
|
||||
currentBackendVersion = "Current Backend Version"
|
||||
currentFrontendVersion = "Current Frontend Version"
|
||||
versionMismatch = "Warning: A mismatch has been detected between the client version and the AppConfig version. Using different versions can lead to compatibility issues, errors, and security risks. Please ensure that server and client are using the same version."
|
||||
latestVersion = "Latest Version"
|
||||
checkForUpdates = "Check for Updates"
|
||||
viewDetails = "View Details"
|
||||
@@ -690,257 +695,257 @@ workbenchSlide = "Workspace panel"
|
||||
workspace = "Workspace"
|
||||
|
||||
[home.multiTool]
|
||||
tags = "multiple,tools"
|
||||
tags = "multiple,tools,multi-tool,all-in-one,swiss army,page organizer,page editor,edit pages,manage pages,organize,reorganize"
|
||||
title = "PDF Multi Tool"
|
||||
desc = "Merge, Rotate, Rearrange, Split, and Remove pages"
|
||||
|
||||
[home.merge]
|
||||
tags = "combine,join,unite"
|
||||
tags = "combine,join,unite,merge,merge PDFs,combine PDFs,join PDFs,concatenate,append,stitch,combine files,join files,merge documents"
|
||||
title = "Merge"
|
||||
desc = "Easily merge multiple PDFs into one."
|
||||
|
||||
[home.split]
|
||||
tags = "divide,separate,break"
|
||||
tags = "divide,separate,break,split,extract pages,separate pages,divide document,break apart,separate files,unbind,split by page,divide by chapter"
|
||||
title = "Split"
|
||||
desc = "Split PDFs into multiple documents"
|
||||
|
||||
[home.rotate]
|
||||
tags = "turn,flip,orient"
|
||||
tags = "turn,flip,orient,rotate,orientation,landscape,portrait,90 degrees,180 degrees,clockwise,anticlockwise,counter-clockwise,fix orientation"
|
||||
title = "Rotate"
|
||||
desc = "Easily rotate your PDFs."
|
||||
|
||||
[home.convert]
|
||||
tags = "transform,change"
|
||||
tags = "transform,change,convert,PDF to Word,PDF to Excel,PDF to image,Word to PDF,Excel to PDF,PowerPoint to PDF,HTML to PDF,export,import,file conversion,format change,save as"
|
||||
title = "Convert"
|
||||
desc = "Convert files between different formats"
|
||||
|
||||
[home.pdfOrganiser]
|
||||
tags = "organize,rearrange,reorder"
|
||||
tags = "organize,rearrange,reorder,organise,arrange pages,sort,move pages,delete pages,remove pages,page management,page organizer,page organiser,resequence"
|
||||
title = "Organise"
|
||||
desc = "Remove/Rearrange pages in any order"
|
||||
|
||||
[home.addImage]
|
||||
tags = "insert,embed,place"
|
||||
tags = "insert,embed,place,add image,insert image,place image,embed image,add photo,add picture,add logo,graphics,insert picture,place photo,PNG,JPG,JPEG"
|
||||
title = "Add image"
|
||||
desc = "Adds a image onto a set location on the PDF"
|
||||
|
||||
[home.addAttachments]
|
||||
tags = "embed,attach,include"
|
||||
tags = "embed,attach,include,attachments,attach files,embed files,include files,add files,file attachment,associated files,supplementary files"
|
||||
title = "Add Attachments"
|
||||
desc = "Add or remove embedded files (attachments) to/from a PDF"
|
||||
|
||||
[home.watermark]
|
||||
tags = "stamp,mark,overlay"
|
||||
tags = "stamp,mark,overlay,watermark,branding,logo,confidential,draft,copyright,trademark,text overlay,image overlay,background text"
|
||||
title = "Add Watermark"
|
||||
desc = "Add a custom watermark to your PDF document."
|
||||
|
||||
[home.removePassword]
|
||||
tags = "unlock"
|
||||
tags = "unlock,remove password,unlock PDF,decrypt,remove encryption,unprotect,open protected PDF,password removal,unlock protected,disable password,remove security,remove owner password"
|
||||
title = "Remove Password"
|
||||
desc = "Remove password protection from your PDF document."
|
||||
|
||||
[home.compress]
|
||||
tags = "shrink,reduce,optimize"
|
||||
tags = "shrink,reduce,optimize,compress,smaller,downsize,file size,reduce size,minimize,make smaller,decrease size,optimize size"
|
||||
title = "Compress"
|
||||
desc = "Compress PDFs to reduce their file size."
|
||||
|
||||
[home.unlockPDFForms]
|
||||
tags = "unlock,enable,edit"
|
||||
tags = "unlock,enable,edit,unlock forms,enable forms,editable forms,remove read only,make editable,unlock fields,enable editing,form fields,fillable,unprotect forms"
|
||||
title = "Unlock PDF Forms"
|
||||
desc = "Remove read-only property of form fields in a PDF document."
|
||||
|
||||
[home.changeMetadata]
|
||||
tags = "edit,modify,update"
|
||||
tags = "edit,modify,update,metadata,properties,document properties,author,title,subject,keywords,creator,producer,info,document info,file properties"
|
||||
title = "Change Metadata"
|
||||
desc = "Change/Remove/Add metadata from a PDF document"
|
||||
|
||||
[home.ocr]
|
||||
tags = "extract,scan"
|
||||
tags = "extract,scan,OCR,optical character recognition,text recognition,scan to text,image to text,scanned document,searchable PDF,make searchable,extract text,recognize text,read scanned"
|
||||
title = "OCR / Cleanup scans"
|
||||
desc = "Cleanup scans and detects text from images within a PDF and re-adds it as text."
|
||||
|
||||
[home.extractImages]
|
||||
tags = "pull,save,export"
|
||||
tags = "pull,save,export,extract images,get images,save images,export images,extract photos,extract pictures,pull images,download images,rip images,extract graphics,save photos"
|
||||
title = "Extract Images"
|
||||
desc = "Extracts all images from a PDF and saves them to zip"
|
||||
|
||||
[home.scannerImageSplit]
|
||||
tags = "detect,split,photos"
|
||||
tags = "detect,split,photos,auto detect,detect photos,split photos,separate photos,split scanned images,multiple photos,auto split,photo detection,image detection,scan separation"
|
||||
title = "Detect & Split Scanned Photos"
|
||||
desc = "Detect and split scanned photos into separate pages"
|
||||
|
||||
[home.sign]
|
||||
tags = "signature,autograph"
|
||||
tags = "signature,autograph,e-sign,electronic signature,digital signature,sign document,approval,signoff,authorize,endorse,ink signature,handwriting"
|
||||
title = "Sign"
|
||||
desc = "Adds signature to PDF by drawing, text or image"
|
||||
|
||||
[home.annotate]
|
||||
tags = "annotate,highlight,draw"
|
||||
tags = "annotate,highlight,draw,markup,comment,notes,review,redline,feedback,markup tools,sticky notes,shapes,arrows,text box,freehand"
|
||||
title = "Annotate"
|
||||
desc = "Highlight, draw, add notes and shapes in the viewer"
|
||||
|
||||
[home.flatten]
|
||||
tags = "simplify,remove,interactive"
|
||||
tags = "simplify,remove,interactive,flatten,flatten form,remove form fields,make static,finalize form,lock form,disable editing,convert to image,non-editable"
|
||||
title = "Flatten"
|
||||
desc = "Remove all interactive elements and forms from a PDF"
|
||||
|
||||
[home.certSign]
|
||||
tags = "authenticate,PEM,P12,official,encrypt,sign,certificate,PKCS12,JKS,server,manual,auto"
|
||||
tags = "authenticate,PEM,P12,official,encrypt,sign,certificate,PKCS12,JKS,server,manual,auto,digital certificate,certificate signature,PKI,cryptographic signature,trusted signature"
|
||||
title = "Sign with Certificate"
|
||||
desc = "Signs a PDF with a Certificate/Key (PEM/P12)"
|
||||
|
||||
[home.repair]
|
||||
tags = "fix,restore"
|
||||
tags = "fix,restore,repair,fix PDF,fix broken,fix corrupt,repair PDF,repair corrupt,broken PDF,corrupt PDF,damaged PDF,recover,fix errors,PDF won't open,can't open PDF,PDF errors,troubleshoot,restore PDF,rebuild,corrupted"
|
||||
title = "Repair"
|
||||
desc = "Tries to repair a corrupt/broken PDF"
|
||||
|
||||
[home.removeBlanks]
|
||||
tags = "delete,clean,empty"
|
||||
tags = "delete,clean,empty,remove blank,delete blank pages,empty pages,white pages,remove empty,clean up,cleanup blank"
|
||||
title = "Remove Blank pages"
|
||||
desc = "Detects and removes blank pages from a document"
|
||||
|
||||
[home.removeAnnotations]
|
||||
tags = "delete,clean,strip"
|
||||
tags = "delete,clean,strip,remove annotations,remove comments,delete comments,remove markup,remove highlights,clean annotations,strip comments,remove notes,delete markup,clear comments"
|
||||
title = "Remove Annotations"
|
||||
desc = "Removes all comments/annotations from a PDF"
|
||||
|
||||
[home.compare]
|
||||
tags = "difference"
|
||||
tags = "difference,compare,diff,compare PDFs,compare documents,find differences,show differences,changes,what changed,track changes,revisions,version compare,side by side,contrast,delta"
|
||||
title = "Compare"
|
||||
desc = "Compares and shows the differences between 2 PDF Documents"
|
||||
|
||||
[home.removeCertSign]
|
||||
tags = "remove,delete,unlock"
|
||||
tags = "remove,delete,unlock,remove certificate,remove signature,delete signature,unsigned,remove digital signature,strip signature,remove cert,unsign"
|
||||
title = "Remove Certificate Sign"
|
||||
desc = "Remove certificate signature from PDF"
|
||||
|
||||
[home.pageLayout]
|
||||
tags = "layout,arrange,combine"
|
||||
tags = "layout,arrange,combine,N-up,2-up,4-up,multiple per page,pages per sheet,layout pages,tile,grid layout,multi-page layout,combine on page,handout"
|
||||
title = "Multi-Page Layout"
|
||||
desc = "Merge multiple pages of a PDF document into a single page"
|
||||
|
||||
[home.bookletImposition]
|
||||
tags = "booklet,print,binding"
|
||||
tags = "booklet,print,binding,imposition,booklet printing,saddle stitch,fold,pamphlet,brochure,print booklet,duplex,two-sided,signature,book layout,page imposition,print layout"
|
||||
title = "Booklet Imposition"
|
||||
desc = "Create booklets with proper page ordering and multi-page layout for printing and binding"
|
||||
|
||||
[home.scalePages]
|
||||
tags = "resize,adjust,scale"
|
||||
tags = "resize,adjust,scale,page size,resize page,scale page,change size,adjust size,enlarge,shrink page,fit to page,A4,letter size"
|
||||
title = "Adjust page size/scale"
|
||||
desc = "Change the size/scale of a page and/or its contents."
|
||||
|
||||
[home.addPageNumbers]
|
||||
tags = "number,pagination,count"
|
||||
tags = "number,pagination,count,add page numbers,page numbering,page numbers,footer,header,number pages,sequential,pagination tool"
|
||||
title = "Add Page Numbers"
|
||||
desc = "Add Page numbers throughout a document in a set location"
|
||||
|
||||
[home.autoRename]
|
||||
tags = "auto-detect,header-based,organize,relabel"
|
||||
tags = "auto-detect,header-based,organize,relabel,auto rename,automatic rename,smart rename,rename by content,filename,file naming,detect title"
|
||||
title = "Auto Rename PDF File"
|
||||
desc = "Auto renames a PDF file based on its detected header"
|
||||
|
||||
[home.adjustContrast]
|
||||
tags = "contrast,brightness,saturation"
|
||||
tags = "contrast,brightness,saturation,adjust colors,color correction,enhance,lighten,darken,improve quality,color balance,hue,vibrance"
|
||||
title = "Adjust Colours/Contrast"
|
||||
desc = "Adjust Colors/Contrast, Saturation and Brightness of a PDF"
|
||||
|
||||
[home.crop]
|
||||
tags = "trim,cut,resize"
|
||||
tags = "trim,cut,resize,crop,crop PDF,trim PDF,trim margins,remove margins,cut edges,trim borders,remove white space,crop pages,trim pages,reduce margins,set margins"
|
||||
title = "Crop PDF"
|
||||
desc = "Crop a PDF to reduce its size (maintains text!)"
|
||||
|
||||
[home.autoSplitPDF]
|
||||
tags = "auto,split,QR"
|
||||
tags = "auto,split,QR,auto split,QR code,QR split,barcode,automatic split,divider page,separator page,scan divider,batch scanning"
|
||||
title = "Auto Split Pages"
|
||||
desc = "Auto Split Scanned PDF with physical scanned page splitter QR Code"
|
||||
|
||||
[home.sanitize]
|
||||
tags = "clean,purge,remove"
|
||||
tags = "clean,purge,remove,sanitize,sanitise,remove scripts,remove javascript,remove metadata,strip metadata,security,clean document,remove hidden data,privacy"
|
||||
title = "Sanitise"
|
||||
desc = "Remove potentially harmful elements from PDF files"
|
||||
|
||||
[home.getPdfInfo]
|
||||
tags = "info,metadata,details"
|
||||
tags = "info,metadata,details,PDF info,document info,properties,file info,get info,show info,view properties,document properties,statistics,page count,file details,inspect"
|
||||
title = "Get ALL Info on PDF"
|
||||
desc = "Grabs any and all information possible on PDFs"
|
||||
|
||||
[home.pdfToSinglePage]
|
||||
tags = "combine,merge,single"
|
||||
tags = "combine,merge,single,single page,one page,merge to single,combine all,stitch pages,concatenate vertical,long page,poster"
|
||||
title = "PDF to Single Large Page"
|
||||
desc = "Merges all PDF pages into one large single page"
|
||||
|
||||
[home.showJS]
|
||||
tags = "javascript,code,script"
|
||||
tags = "javascript,code,script,show javascript,show JS,find javascript,detect javascript,view javascript,embedded scripts,malware,security,inspect,debug"
|
||||
title = "Show Javascript"
|
||||
desc = "Searches and displays any JS injected into a PDF"
|
||||
|
||||
[home.redact]
|
||||
tags = "censor,blackout,hide"
|
||||
tags = "censor,blackout,hide,redact,redaction,black out,block out,remove sensitive,hide text,privacy,confidential,GDPR,PII,sensitive data,permanently remove,cover up,legal redaction"
|
||||
title = "Redact"
|
||||
desc = "Redacts (blacks out) a PDF based on selected text, drawn shapes and/or selected page(s)"
|
||||
|
||||
[home.splitBySections]
|
||||
tags = "split,sections,divide"
|
||||
tags = "split,sections,divide,split by sections,grid split,divide pages,split into sections,cut pages,divide grid,section split,horizontal split,vertical split"
|
||||
title = "Split PDF by Sections"
|
||||
desc = "Divide each page of a PDF into smaller horizontal and vertical sections"
|
||||
|
||||
[home.addStamp]
|
||||
tags = "stamp,mark,seal"
|
||||
tags = "stamp,mark,seal,approved,rejected,confidential,stamp tool,rubber stamp,date stamp,approval stamp,received,void,copy,original"
|
||||
title = "Add Stamp to PDF"
|
||||
desc = "Add text or add image stamps at set locations"
|
||||
|
||||
[home.removeImage]
|
||||
tags = "remove,delete,clean"
|
||||
tags = "remove,delete,clean,remove image,delete image,strip images,remove pictures,delete photos,clean images,reduce size,remove graphics"
|
||||
title = "Remove image"
|
||||
desc = "Remove image from PDF to reduce file size"
|
||||
|
||||
[home.splitByChapters]
|
||||
tags = "split,chapters,structure"
|
||||
tags = "split,chapters,structure,split by chapters,split by bookmarks,bookmarks,outline,table of contents,TOC split,chapter split,divide by sections"
|
||||
title = "Split PDF by Chapters"
|
||||
desc = "Split a PDF into multiple files based on its chapter structure."
|
||||
|
||||
[home.validateSignature]
|
||||
tags = "validate,verify,certificate"
|
||||
tags = "validate,verify,certificate,validate signature,verify signature,check signature,digital signature,certificate verification,signature validation,authentic,trust,signed,verify certificate"
|
||||
title = "Validate PDF Signature"
|
||||
desc = "Verify digital signatures and certificates in PDF documents"
|
||||
|
||||
[home.swagger]
|
||||
tags = "API,documentation,test"
|
||||
tags = "API,documentation,test,swagger,API docs,REST API,endpoints,developer,API reference,API testing,OpenAPI,integration,developer docs"
|
||||
title = "API Documentation"
|
||||
desc = "View API documentation and test endpoints"
|
||||
|
||||
[home.scannerEffect]
|
||||
tags = "scan,simulate,create"
|
||||
tags = "scan,simulate,create,fake scan,look scanned,scanner effect,make look scanned,photocopy effect,simulate scanner,realistic scan"
|
||||
title = "Scanner Effect"
|
||||
desc = "Create a PDF that looks like it was scanned"
|
||||
|
||||
[home.editTableOfContents]
|
||||
tags = "bookmarks,contents,edit"
|
||||
tags = "bookmarks,contents,edit,table of contents,TOC,outline,navigation,chapters,sections,add bookmarks,edit bookmarks,PDF outline"
|
||||
title = "Edit Table of Contents"
|
||||
desc = "Add or edit bookmarks and table of contents in PDF documents"
|
||||
|
||||
[home.manageCertificates]
|
||||
tags = "certificates,import,export"
|
||||
tags = "certificates,import,export,manage certificates,digital certificates,certificate management,PFX,P12,keystore,import certificate,export certificate,certificate store,PKI"
|
||||
title = "Manage Certificates"
|
||||
desc = "Import, export, or delete digital certificate files used for signing PDFs."
|
||||
|
||||
[home.read]
|
||||
tags = "view,open,display"
|
||||
tags = "view,open,display,read,viewer,PDF viewer,PDF reader,open PDF,view PDF,display PDF,preview,browse"
|
||||
title = "Read"
|
||||
desc = "View and annotate PDFs. Highlight text, draw, or insert comments for review and collaboration."
|
||||
|
||||
[home.reorganizePages]
|
||||
tags = "rearrange,reorder,organize"
|
||||
tags = "rearrange,reorder,organize,reorganize,move pages,page order,sort pages,arrange pages,shuffle,resequence"
|
||||
title = "Reorganize Pages"
|
||||
desc = "Rearrange, duplicate, or delete PDF pages with visual drag-and-drop control."
|
||||
|
||||
[home.extractPages]
|
||||
tags = "pull,select,copy"
|
||||
tags = "pull,select,copy,extract,extract pages,get pages,pull out,save pages,export pages,copy pages,select pages,specific pages"
|
||||
title = "Extract Pages"
|
||||
desc = "Extract specific pages from a PDF document"
|
||||
|
||||
[home.removePages]
|
||||
tags = "delete,extract,exclude"
|
||||
tags = "delete,extract,exclude,remove pages,delete pages,remove page,delete page,exclude pages,take out pages,discard pages,drop pages"
|
||||
title = "Remove Pages"
|
||||
desc = "Remove specific pages from a PDF document"
|
||||
|
||||
@@ -950,50 +955,57 @@ title = "Auto Split by Size/Count"
|
||||
desc = "Automatically split PDFs by file size or page count"
|
||||
|
||||
[home.replaceColor]
|
||||
tags = "replace color,invert color,color replacement,swap colors,change color,invert,negative,color swap,find and replace color,convert color,color change"
|
||||
title = "Replace & Invert Colour"
|
||||
desc = "Replace or invert colours in PDF documents"
|
||||
|
||||
[home.devApi]
|
||||
tags = "API,development,documentation"
|
||||
tags = "API,development,documentation,developer,REST,integration,endpoints,programmatic,automation,scripting"
|
||||
title = "API"
|
||||
desc = "Link to API documentation"
|
||||
|
||||
[home.devFolderScanning]
|
||||
tags = "automation,folder,scanning"
|
||||
tags = "automation,folder,scanning,watch folder,hot folder,automatic processing,batch,monitor folder,auto process,folder monitoring"
|
||||
title = "Automated Folder Scanning"
|
||||
desc = "Link to automated folder scanning guide"
|
||||
|
||||
[home.devSsoGuide]
|
||||
tags = "SSO,single sign-on,authentication,SAML,OAuth,OIDC,login,enterprise,identity provider,IdP"
|
||||
title = "SSO Guide"
|
||||
desc = "Link to SSO guide"
|
||||
|
||||
[home.devAirgapped]
|
||||
tags = "air-gapped,offline,isolated,no internet,disconnected,secure,network isolation,standalone"
|
||||
title = "Air-gapped Setup"
|
||||
desc = "Link to air-gapped setup guide"
|
||||
|
||||
[home.addPassword]
|
||||
tags = "encrypt,password,lock,secure,protect,security,encryption,safeguard,confidential,private,restrict access"
|
||||
title = "Add Password"
|
||||
desc = "Add password protection and restrictions to PDF files"
|
||||
|
||||
[home.changePermissions]
|
||||
tags = "permissions,restrictions,rights,access control,allow,deny,printing,copying,editing,modify permissions,security settings,user rights"
|
||||
title = "Change Permissions"
|
||||
desc = "Change document restrictions and permissions"
|
||||
|
||||
[home.automate]
|
||||
tags = "workflow,sequence,automation"
|
||||
tags = "workflow,sequence,automation,automate,batch,batch processing,pipeline,chain,multi-step,recurring,scheduled,automatic,process multiple,bulk operations"
|
||||
title = "Automate"
|
||||
desc = "Build multi-step workflows by chaining together PDF actions. Ideal for recurring tasks."
|
||||
|
||||
[home.overlay-pdfs]
|
||||
tags = "overlay,combine,merge,layer,superimpose,overlay PDF,layer PDFs,combine PDFs,stack,overlay pages,background,foreground,composite"
|
||||
desc = "Overlay one PDF on top of another"
|
||||
title = "Overlay PDFs"
|
||||
|
||||
[home.pdfTextEditor]
|
||||
tags = "edit text,modify text,change text,edit content,update text,rewrite,correct,amend,redline,revise,text editor,content editor"
|
||||
title = "PDF Text Editor"
|
||||
desc = "Edit existing text and images inside PDFs"
|
||||
|
||||
[home.addText]
|
||||
tags = "text,annotation,label"
|
||||
tags = "text,annotation,label,add text,insert text,place text,text box,add label,add caption,type on PDF,write on PDF,add words,add note,text overlay,typewriter"
|
||||
title = "Add Text"
|
||||
desc = "Add custom text anywhere in your PDF"
|
||||
|
||||
@@ -3553,6 +3565,39 @@ imageSize = "Image Size"
|
||||
margin = "Margin"
|
||||
positionAndFormatting = "Position & Formatting"
|
||||
quickPosition = "Select a position on the page to place the stamp."
|
||||
preview = "Preview:"
|
||||
useTemplate = "Use Template"
|
||||
selectTemplate = "Select a template..."
|
||||
stampTextDescription = "Use dynamic variables below. Use @@ for literal @. Use \\n for new lines."
|
||||
dynamicVariables = "Dynamic Variables"
|
||||
clickToExpand = "Click to expand"
|
||||
variablesHelp = "Click on any variable to insert it into your stamp text. Use @@ for literal @."
|
||||
dateTimeVars = "Date & Time"
|
||||
dateDesc = "Current date"
|
||||
timeDesc = "Current time"
|
||||
datetimeDesc = "Date and time combined"
|
||||
customDateDesc = "Custom format"
|
||||
yearMonthDayDesc = "Individual date parts"
|
||||
pageVars = "Page Information"
|
||||
pageNumberDesc = "Current page number"
|
||||
totalPagesDesc = "Total number of pages"
|
||||
fileVars = "File Information"
|
||||
filenameDesc = "Filename without extension"
|
||||
filenameFullDesc = "Filename with extension"
|
||||
metadataVars = "Document Metadata"
|
||||
metadataDesc = "From PDF document properties"
|
||||
otherVars = "Other"
|
||||
uuidDesc = "Short unique identifier (8 chars)"
|
||||
examples = "Examples"
|
||||
multiLine = "multi-line"
|
||||
|
||||
[AddStampRequest.template]
|
||||
pageNumberFooter = "Page Number Footer"
|
||||
dateHeader = "Date Header"
|
||||
europeanDate = "European Date"
|
||||
timestamp = "Timestamp"
|
||||
draftWatermark = "Draft Watermark"
|
||||
custom = "Custom"
|
||||
|
||||
[AddStampRequest.error]
|
||||
failed = "An error occurred while adding stamp to the PDF."
|
||||
@@ -4472,10 +4517,18 @@ description = "Configure custom file system paths for pipeline processing and ex
|
||||
[admin.settings.general.customPaths.pipeline]
|
||||
label = "Pipeline Directories"
|
||||
|
||||
[admin.settings.general.customPaths.pipeline.pipelineDir]
|
||||
label = "Pipeline Directory"
|
||||
description = "Base directory for pipeline resources (leave empty for default: /pipeline)"
|
||||
|
||||
[admin.settings.general.customPaths.pipeline.watchedFoldersDir]
|
||||
label = "Watched Folders Directory"
|
||||
description = "Directory where pipeline monitors for incoming PDFs (leave empty for default: /pipeline/watchedFolders)"
|
||||
|
||||
[admin.settings.general.customPaths.pipeline.watchedFoldersDirs]
|
||||
label = "Watched Folders Directories"
|
||||
description = "Directories where pipeline monitors for incoming PDFs (one per line or comma-separated; leave empty for default: /pipeline/watchedFolders)"
|
||||
|
||||
[admin.settings.general.customPaths.pipeline.finishedFoldersDir]
|
||||
label = "Finished Folders Directory"
|
||||
description = "Directory where processed PDFs are outputted (leave empty for default: /pipeline/finishedFolders)"
|
||||
@@ -4527,6 +4580,13 @@ description = "Maximum number of failed login attempts before account lockout"
|
||||
label = "Login Reset Time (minutes)"
|
||||
description = "Time before failed login attempts are reset"
|
||||
|
||||
[admin.settings.security.xFrameOptions]
|
||||
label = "X-Frame-Options"
|
||||
description = "Controls whether the application can be embedded in iframes"
|
||||
deny = "Deny (Prevents all framing)"
|
||||
sameorigin = "Same Origin (Allow framing from same domain)"
|
||||
disabled = "Disabled (No X-Frame-Options header)"
|
||||
|
||||
[admin.settings.security.csrfDisabled]
|
||||
label = "Disable CSRF Protection"
|
||||
description = "Disable Cross-Site Request Forgery protection (not recommended)"
|
||||
|
||||
@@ -439,7 +439,9 @@ fullscreen = "Pantalla completa"
|
||||
[settings.general.updates]
|
||||
title = "Actualizaciones de software"
|
||||
description = "Compruebe actualizaciones y vea la información de versión"
|
||||
currentVersion = "Versión actual"
|
||||
currentBackendVersion = "Current Backend Version"
|
||||
currentFrontendVersion = "Current Frontend Version"
|
||||
versionMismatch = "Warning: A mismatch has been detected between the client version and the AppConfig version. Using different versions can lead to compatibility issues, errors, and security risks. Please ensure that server and client are using the same version."
|
||||
latestVersion = "Última versión"
|
||||
checkForUpdates = "Buscar actualizaciones"
|
||||
viewDetails = "Ver detalles"
|
||||
@@ -950,6 +952,7 @@ title = "Auto dividir por tamaño/conteo"
|
||||
desc = "Divide un solo PDF en múltiples documentos según su tamaño, número de páginas, o número de documento"
|
||||
|
||||
[home.replaceColor]
|
||||
tags = "replace color,invert color,color replacement,swap colors,change color,invert,negative,color swap,find and replace color,convert color,color change"
|
||||
title = "Reemplazar e Invertir Color"
|
||||
desc = "Reemplace o invierta colores en documentos PDF"
|
||||
|
||||
@@ -964,18 +967,22 @@ title = "Escaneo Automatizado de Carpetas"
|
||||
desc = "Enlace a la guía de escaneo automatizado de carpetas"
|
||||
|
||||
[home.devSsoGuide]
|
||||
tags = "SSO,single sign-on,authentication,SAML,OAuth,OIDC,login,enterprise,identity provider,IdP"
|
||||
title = "Guía de SSO"
|
||||
desc = "Enlace a la guía de SSO"
|
||||
|
||||
[home.devAirgapped]
|
||||
tags = "air-gapped,offline,isolated,no internet,disconnected,secure,network isolation,standalone"
|
||||
title = "Configuración Aislada"
|
||||
desc = "Enlace a la guía de configuración aislada"
|
||||
|
||||
[home.addPassword]
|
||||
tags = "encrypt,password,lock,secure,protect,security,encryption,safeguard,confidential,private,restrict access"
|
||||
title = "Proteger con contraseña"
|
||||
desc = "Cifrar documento PDF con contraseña"
|
||||
|
||||
[home.changePermissions]
|
||||
tags = "permissions,restrictions,rights,access control,allow,deny,printing,copying,editing,modify permissions,security settings,user rights"
|
||||
title = "Cambiar permisos"
|
||||
desc = "Modificar restricciones y permisos del documento"
|
||||
|
||||
@@ -985,10 +992,12 @@ title = "Automatizar"
|
||||
desc = "Crear flujos de trabajo de múltiples pasos encadenando acciones de PDF. Ideal para tareas recurrentes."
|
||||
|
||||
[home.overlay-pdfs]
|
||||
tags = "overlay,combine,merge,layer,superimpose,overlay PDF,layer PDFs,combine PDFs,stack,overlay pages,background,foreground,composite"
|
||||
desc = "Superponer PDFs encima de otro PDF"
|
||||
title = "Superponer PDFs"
|
||||
|
||||
[home.pdfTextEditor]
|
||||
tags = "edit text,modify text,change text,edit content,update text,rewrite,correct,amend,redline,revise,text editor,content editor"
|
||||
title = "Editor de texto PDF"
|
||||
desc = "Revise y edite exportaciones JSON de Stirling PDF con edición de texto agrupada y regeneración de PDF"
|
||||
|
||||
@@ -3553,6 +3562,31 @@ imageSize = "Tamaño de la imagen"
|
||||
margin = "Margen"
|
||||
positionAndFormatting = "Posición y formato"
|
||||
quickPosition = "Selecciona una posición en la página para colocar el sello."
|
||||
clickToExpand = "Click to expand"
|
||||
customDateDesc = "Custom format"
|
||||
dateDesc = "Current date"
|
||||
dateTimeVars = "Date & Time"
|
||||
datetimeDesc = "Date and time combined"
|
||||
dynamicVariables = "Dynamic Variables"
|
||||
examples = "Examples"
|
||||
fileVars = "File Information"
|
||||
filenameDesc = "Filename without extension"
|
||||
filenameFullDesc = "Filename with extension"
|
||||
metadataDesc = "From PDF document properties"
|
||||
metadataVars = "Document Metadata"
|
||||
multiLine = "multi-line"
|
||||
otherVars = "Other"
|
||||
pageNumberDesc = "Current page number"
|
||||
pageVars = "Page Information"
|
||||
preview = "Preview:"
|
||||
selectTemplate = "Select a template..."
|
||||
stampTextDescription = "Use dynamic variables below. Use @@ for literal @. Use \\n for new lines."
|
||||
timeDesc = "Current time"
|
||||
totalPagesDesc = "Total number of pages"
|
||||
useTemplate = "Use Template"
|
||||
uuidDesc = "Short unique identifier (8 chars)"
|
||||
variablesHelp = "Click on any variable to insert it into your stamp text. Use @@ for literal @."
|
||||
yearMonthDayDesc = "Individual date parts"
|
||||
|
||||
[AddStampRequest.error]
|
||||
failed = "Se produjo un error al añadir el sello al PDF."
|
||||
@@ -3560,6 +3594,14 @@ failed = "Se produjo un error al añadir el sello al PDF."
|
||||
[AddStampRequest.results]
|
||||
title = "Resultados del sello"
|
||||
|
||||
[AddStampRequest.template]
|
||||
custom = "Custom"
|
||||
dateHeader = "Date Header"
|
||||
draftWatermark = "Draft Watermark"
|
||||
europeanDate = "European Date"
|
||||
pageNumberFooter = "Page Number Footer"
|
||||
timestamp = "Timestamp"
|
||||
|
||||
[removeImagePdf]
|
||||
tags = "Eliminar imagen,Operaciones de página,Back end,Backend"
|
||||
|
||||
@@ -4526,6 +4568,13 @@ description = "Número máximo de intentos fallidos antes de bloquear la cuenta"
|
||||
label = "Tiempo de restablecimiento del inicio de sesión (minutos)"
|
||||
description = "Tiempo antes de que se restablezcan los intentos fallidos de inicio de sesión"
|
||||
|
||||
[admin.settings.security.xFrameOptions]
|
||||
label = "X-Frame-Options"
|
||||
description = "Controls whether the application can be embedded in iframes"
|
||||
deny = "Deny (Prevents all framing)"
|
||||
sameorigin = "Same Origin (Allow framing from same domain)"
|
||||
disabled = "Disabled (No X-Frame-Options header)"
|
||||
|
||||
[admin.settings.security.csrfDisabled]
|
||||
label = "Desactivar la protección CSRF"
|
||||
description = "Desactivar la protección contra Cross-Site Request Forgery (no recomendado)"
|
||||
|
||||
@@ -439,7 +439,9 @@ fullscreen = "Pantaila osoa"
|
||||
[settings.general.updates]
|
||||
title = "Software eguneratzeak"
|
||||
description = "Egiaztatu eguneratzeak eta ikusi bertsio-informazioa"
|
||||
currentVersion = "Uneko bertsioa"
|
||||
currentBackendVersion = "Current Backend Version"
|
||||
currentFrontendVersion = "Current Frontend Version"
|
||||
versionMismatch = "Warning: A mismatch has been detected between the client version and the AppConfig version. Using different versions can lead to compatibility issues, errors, and security risks. Please ensure that server and client are using the same version."
|
||||
latestVersion = "Azken bertsioa"
|
||||
checkForUpdates = "Egiaztatu eguneratzeak"
|
||||
viewDetails = "Xehetasunak ikusi"
|
||||
@@ -950,6 +952,7 @@ title = "Autom. zatitu tamaina/kop."
|
||||
desc = "Split a single PDF into multiple documents based on size, page count, or document count"
|
||||
|
||||
[home.replaceColor]
|
||||
tags = "replace color,invert color,color replacement,swap colors,change color,invert,negative,color swap,find and replace color,convert color,color change"
|
||||
title = "Ordeztu eta inbertitu kolorea"
|
||||
desc = "Ordeztu edo alderantzikatu koloreak PDF dokumentuetan"
|
||||
|
||||
@@ -964,18 +967,22 @@ title = "Karpeta eskaneatze autom."
|
||||
desc = "Esteka karpeta eskaneatze automatizatuaren gidara"
|
||||
|
||||
[home.devSsoGuide]
|
||||
tags = "SSO,single sign-on,authentication,SAML,OAuth,OIDC,login,enterprise,identity provider,IdP"
|
||||
title = "SSO gida"
|
||||
desc = "Esteka SSO gidara"
|
||||
|
||||
[home.devAirgapped]
|
||||
tags = "air-gapped,offline,isolated,no internet,disconnected,secure,network isolation,standalone"
|
||||
title = "Sare isolatuko konfigurazioa"
|
||||
desc = "Esteka sare isolatutako konfigurazio gidara"
|
||||
|
||||
[home.addPassword]
|
||||
tags = "encrypt,password,lock,secure,protect,security,encryption,safeguard,confidential,private,restrict access"
|
||||
title = "Gehitu pasahitza"
|
||||
desc = "Enkriptatu PDF dokumentua pasahitz batekin"
|
||||
|
||||
[home.changePermissions]
|
||||
tags = "permissions,restrictions,rights,access control,allow,deny,printing,copying,editing,modify permissions,security settings,user rights"
|
||||
title = "Aldatu baimenak"
|
||||
desc = "Aldatu dokumentuaren murrizketak eta baimenak"
|
||||
|
||||
@@ -985,10 +992,12 @@ title = "Automatizatu"
|
||||
desc = "Eraiki hainbat pausotako workflowak PDF ekintzak kateatuz. Egokia zeregin errepikakorretarako."
|
||||
|
||||
[home.overlay-pdfs]
|
||||
tags = "overlay,combine,merge,layer,superimpose,overlay PDF,layer PDFs,combine PDFs,stack,overlay pages,background,foreground,composite"
|
||||
desc = "Overlays PDFs on-top of another PDF"
|
||||
title = "Gainjarri PDFak"
|
||||
|
||||
[home.pdfTextEditor]
|
||||
tags = "edit text,modify text,change text,edit content,update text,rewrite,correct,amend,redline,revise,text editor,content editor"
|
||||
title = "PDF testu-editorea"
|
||||
desc = "Berrikusi eta editatu Stirling PDF JSON esportazioak taldekatutako testu-edizioarekin eta PDF birsorkuntzarekin"
|
||||
|
||||
@@ -3553,6 +3562,31 @@ imageSize = "Irudiaren tamaina"
|
||||
margin = "Marjina"
|
||||
positionAndFormatting = "Kokapena eta formatua"
|
||||
quickPosition = "Hautatu orrian zigiloa kokatzeko posizio bat."
|
||||
clickToExpand = "Click to expand"
|
||||
customDateDesc = "Custom format"
|
||||
dateDesc = "Current date"
|
||||
dateTimeVars = "Date & Time"
|
||||
datetimeDesc = "Date and time combined"
|
||||
dynamicVariables = "Dynamic Variables"
|
||||
examples = "Examples"
|
||||
fileVars = "File Information"
|
||||
filenameDesc = "Filename without extension"
|
||||
filenameFullDesc = "Filename with extension"
|
||||
metadataDesc = "From PDF document properties"
|
||||
metadataVars = "Document Metadata"
|
||||
multiLine = "multi-line"
|
||||
otherVars = "Other"
|
||||
pageNumberDesc = "Current page number"
|
||||
pageVars = "Page Information"
|
||||
preview = "Preview:"
|
||||
selectTemplate = "Select a template..."
|
||||
stampTextDescription = "Use dynamic variables below. Use @@ for literal @. Use \\n for new lines."
|
||||
timeDesc = "Current time"
|
||||
totalPagesDesc = "Total number of pages"
|
||||
useTemplate = "Use Template"
|
||||
uuidDesc = "Short unique identifier (8 chars)"
|
||||
variablesHelp = "Click on any variable to insert it into your stamp text. Use @@ for literal @."
|
||||
yearMonthDayDesc = "Individual date parts"
|
||||
|
||||
[AddStampRequest.error]
|
||||
failed = "Errore bat gertatu da zigilua PDFari gehitzean."
|
||||
@@ -3560,6 +3594,14 @@ failed = "Errore bat gertatu da zigilua PDFari gehitzean."
|
||||
[AddStampRequest.results]
|
||||
title = "Zigiluaren emaitzak"
|
||||
|
||||
[AddStampRequest.template]
|
||||
custom = "Custom"
|
||||
dateHeader = "Date Header"
|
||||
draftWatermark = "Draft Watermark"
|
||||
europeanDate = "European Date"
|
||||
pageNumberFooter = "Page Number Footer"
|
||||
timestamp = "Timestamp"
|
||||
|
||||
[removeImagePdf]
|
||||
tags = "Irudia kendu,Orrialde eragiketak,Back end,server side"
|
||||
|
||||
@@ -4526,6 +4568,13 @@ description = "Kontua blokeatu aurretik huts egindako saio-saiakeren gehienezko
|
||||
label = "Saio-hasieraren berrezartze denbora (minutuak)"
|
||||
description = "Huts egindako saio-saiakerak berrezarri aurreko denbora"
|
||||
|
||||
[admin.settings.security.xFrameOptions]
|
||||
label = "X-Frame-Options"
|
||||
description = "Controls whether the application can be embedded in iframes"
|
||||
deny = "Deny (Prevents all framing)"
|
||||
sameorigin = "Same Origin (Allow framing from same domain)"
|
||||
disabled = "Disabled (No X-Frame-Options header)"
|
||||
|
||||
[admin.settings.security.csrfDisabled]
|
||||
label = "CSRF babesa desgaitu"
|
||||
description = "Desgaitu Cross-Site Request Forgery babesa (ez da gomendatzen)"
|
||||
|
||||
@@ -439,7 +439,9 @@ fullscreen = "تمامصفحه"
|
||||
[settings.general.updates]
|
||||
title = "بهروزرسانی نرمافزار"
|
||||
description = "بررسی بهروزرسانی و مشاهده اطلاعات نسخه"
|
||||
currentVersion = "نسخه فعلی"
|
||||
currentBackendVersion = "Current Backend Version"
|
||||
currentFrontendVersion = "Current Frontend Version"
|
||||
versionMismatch = "Warning: A mismatch has been detected between the client version and the AppConfig version. Using different versions can lead to compatibility issues, errors, and security risks. Please ensure that server and client are using the same version."
|
||||
latestVersion = "آخرین نسخه"
|
||||
checkForUpdates = "بررسی بهروزرسانی"
|
||||
viewDetails = "مشاهده جزئیات"
|
||||
@@ -950,6 +952,7 @@ title = "تقسیم خودکار بر اساس اندازه/تعداد"
|
||||
desc = "تقسیم یک PDF به چند سند بر اساس اندازه، تعداد صفحات، یا تعداد اسناد"
|
||||
|
||||
[home.replaceColor]
|
||||
tags = "replace color,invert color,color replacement,swap colors,change color,invert,negative,color swap,find and replace color,convert color,color change"
|
||||
title = "جایگزینی و معکوس کردن رنگ"
|
||||
desc = "جایگزینی یا معکوس کردن رنگها در اسناد PDF"
|
||||
|
||||
@@ -964,18 +967,22 @@ title = "اسکن خودکار پوشه"
|
||||
desc = "پیوند به راهنمای اسکن خودکار پوشه"
|
||||
|
||||
[home.devSsoGuide]
|
||||
tags = "SSO,single sign-on,authentication,SAML,OAuth,OIDC,login,enterprise,identity provider,IdP"
|
||||
title = "راهنمای SSO"
|
||||
desc = "پیوند به راهنمای SSO"
|
||||
|
||||
[home.devAirgapped]
|
||||
tags = "air-gapped,offline,isolated,no internet,disconnected,secure,network isolation,standalone"
|
||||
title = "راهاندازی Air-gapped"
|
||||
desc = "پیوند به راهنمای راهاندازی Air-gapped"
|
||||
|
||||
[home.addPassword]
|
||||
tags = "encrypt,password,lock,secure,protect,security,encryption,safeguard,confidential,private,restrict access"
|
||||
title = "افزودن رمز عبور"
|
||||
desc = "رمزگذاری سند PDF شما با رمز عبور."
|
||||
|
||||
[home.changePermissions]
|
||||
tags = "permissions,restrictions,rights,access control,allow,deny,printing,copying,editing,modify permissions,security settings,user rights"
|
||||
title = "تغییر مجوزها"
|
||||
desc = "تغییر محدودیتها و مجوزهای سند"
|
||||
|
||||
@@ -985,10 +992,12 @@ title = "اتوماسیون"
|
||||
desc = "ساخت گردشکارهای چندمرحلهای با زنجیره کردن اقدامات PDF. مناسب برای کارهای تکرارشونده."
|
||||
|
||||
[home.overlay-pdfs]
|
||||
tags = "overlay,combine,merge,layer,superimpose,overlay PDF,layer PDFs,combine PDFs,stack,overlay pages,background,foreground,composite"
|
||||
desc = "PDFها را بر روی PDF دیگری همپوشانی میکند"
|
||||
title = "همپوشانی PDFها"
|
||||
|
||||
[home.pdfTextEditor]
|
||||
tags = "edit text,modify text,change text,edit content,update text,rewrite,correct,amend,redline,revise,text editor,content editor"
|
||||
title = "ویرایشگر متن PDF"
|
||||
desc = "بازبینی و ویرایش خروجیهای JSON Stirling PDF با ویرایش گروهی متن و بازتولید PDF"
|
||||
|
||||
@@ -3553,6 +3562,31 @@ imageSize = "اندازه تصویر"
|
||||
margin = "حاشیه"
|
||||
positionAndFormatting = "موقعیت و قالببندی"
|
||||
quickPosition = "یک موقعیت روی صفحه برای قرار دادن مهر انتخاب کنید."
|
||||
clickToExpand = "Click to expand"
|
||||
customDateDesc = "Custom format"
|
||||
dateDesc = "Current date"
|
||||
dateTimeVars = "Date & Time"
|
||||
datetimeDesc = "Date and time combined"
|
||||
dynamicVariables = "Dynamic Variables"
|
||||
examples = "Examples"
|
||||
fileVars = "File Information"
|
||||
filenameDesc = "Filename without extension"
|
||||
filenameFullDesc = "Filename with extension"
|
||||
metadataDesc = "From PDF document properties"
|
||||
metadataVars = "Document Metadata"
|
||||
multiLine = "multi-line"
|
||||
otherVars = "Other"
|
||||
pageNumberDesc = "Current page number"
|
||||
pageVars = "Page Information"
|
||||
preview = "Preview:"
|
||||
selectTemplate = "Select a template..."
|
||||
stampTextDescription = "Use dynamic variables below. Use @@ for literal @. Use \\n for new lines."
|
||||
timeDesc = "Current time"
|
||||
totalPagesDesc = "Total number of pages"
|
||||
useTemplate = "Use Template"
|
||||
uuidDesc = "Short unique identifier (8 chars)"
|
||||
variablesHelp = "Click on any variable to insert it into your stamp text. Use @@ for literal @."
|
||||
yearMonthDayDesc = "Individual date parts"
|
||||
|
||||
[AddStampRequest.error]
|
||||
failed = "هنگام افزودن مهر به PDF خطایی رخ داد."
|
||||
@@ -3560,6 +3594,14 @@ failed = "هنگام افزودن مهر به PDF خطایی رخ داد."
|
||||
[AddStampRequest.results]
|
||||
title = "نتایج مهر"
|
||||
|
||||
[AddStampRequest.template]
|
||||
custom = "Custom"
|
||||
dateHeader = "Date Header"
|
||||
draftWatermark = "Draft Watermark"
|
||||
europeanDate = "European Date"
|
||||
pageNumberFooter = "Page Number Footer"
|
||||
timestamp = "Timestamp"
|
||||
|
||||
[removeImagePdf]
|
||||
tags = "حذف تصویر، عملیات صفحه، سرور"
|
||||
|
||||
@@ -4526,6 +4568,13 @@ description = "حداکثر تعداد تلاش ناموفق ورود قبل ا
|
||||
label = "زمان بازنشانی ورود (دقیقه)"
|
||||
description = "مدتی که پس از آن تلاشهای ناموفق ورود بازنشانی میشوند"
|
||||
|
||||
[admin.settings.security.xFrameOptions]
|
||||
label = "X-Frame-Options"
|
||||
description = "Controls whether the application can be embedded in iframes"
|
||||
deny = "Deny (Prevents all framing)"
|
||||
sameorigin = "Same Origin (Allow framing from same domain)"
|
||||
disabled = "Disabled (No X-Frame-Options header)"
|
||||
|
||||
[admin.settings.security.csrfDisabled]
|
||||
label = "غیرفعال کردن محافظت CSRF"
|
||||
description = "غیرفعال کردن محافظت Cross-Site Request Forgery (توصیه نمیشود)"
|
||||
|
||||
@@ -439,7 +439,9 @@ fullscreen = "Plein écran"
|
||||
[settings.general.updates]
|
||||
title = "Mises à jour logicielles"
|
||||
description = "Rechercher des mises à jour et voir les informations de version"
|
||||
currentVersion = "Version actuelle"
|
||||
currentBackendVersion = "Current Backend Version"
|
||||
currentFrontendVersion = "Current Frontend Version"
|
||||
versionMismatch = "Warning: A mismatch has been detected between the client version and the AppConfig version. Using different versions can lead to compatibility issues, errors, and security risks. Please ensure that server and client are using the same version."
|
||||
latestVersion = "Dernière version"
|
||||
checkForUpdates = "Rechercher des mises à jour"
|
||||
viewDetails = "Voir les détails"
|
||||
@@ -950,6 +952,7 @@ title = "Scinder auto taille/pages"
|
||||
desc = "Séparer un PDF unique en plusieurs documents en fonction de la taille, du nombre de pages ou du nombre de documents."
|
||||
|
||||
[home.replaceColor]
|
||||
tags = "replace color,invert color,color replacement,swap colors,change color,invert,negative,color swap,find and replace color,convert color,color change"
|
||||
title = "Remplacer & inverser couleurs"
|
||||
desc = "Remplacer ou inverser les couleurs dans les documents PDF"
|
||||
|
||||
@@ -964,18 +967,22 @@ title = "Scan auto de dossiers"
|
||||
desc = "Lien vers le guide d’analyse de dossier automatisée"
|
||||
|
||||
[home.devSsoGuide]
|
||||
tags = "SSO,single sign-on,authentication,SAML,OAuth,OIDC,login,enterprise,identity provider,IdP"
|
||||
title = "Guide SSO"
|
||||
desc = "Lien vers le guide SSO"
|
||||
|
||||
[home.devAirgapped]
|
||||
tags = "air-gapped,offline,isolated,no internet,disconnected,secure,network isolation,standalone"
|
||||
title = "Installation isolée"
|
||||
desc = "Lien vers le guide d’installation isolée (air-gapped)"
|
||||
|
||||
[home.addPassword]
|
||||
tags = "encrypt,password,lock,secure,protect,security,encryption,safeguard,confidential,private,restrict access"
|
||||
title = "Ajouter un mot de passe"
|
||||
desc = "Chiffrez votre PDF avec un mot de passe."
|
||||
|
||||
[home.changePermissions]
|
||||
tags = "permissions,restrictions,rights,access control,allow,deny,printing,copying,editing,modify permissions,security settings,user rights"
|
||||
title = "Modifier les permissions"
|
||||
desc = "Modifier les restrictions et permissions du document"
|
||||
|
||||
@@ -985,10 +992,12 @@ title = "Automatiser"
|
||||
desc = "Créez des workflows multi-étapes en enchaînant des actions PDF. Idéal pour les tâches récurrentes."
|
||||
|
||||
[home.overlay-pdfs]
|
||||
tags = "overlay,combine,merge,layer,superimpose,overlay PDF,layer PDFs,combine PDFs,stack,overlay pages,background,foreground,composite"
|
||||
desc = "Superposer un PDF sur un autre"
|
||||
title = "Superposer des PDF"
|
||||
|
||||
[home.pdfTextEditor]
|
||||
tags = "edit text,modify text,change text,edit content,update text,rewrite,correct,amend,redline,revise,text editor,content editor"
|
||||
title = "Éditeur de texte PDF"
|
||||
desc = "Afficher et modifier les exports JSON de Stirling PDF avec édition de texte groupée et régénération du PDF"
|
||||
|
||||
@@ -3553,6 +3562,31 @@ imageSize = "Taille de l’image"
|
||||
margin = "Marge"
|
||||
positionAndFormatting = "Position et mise en forme"
|
||||
quickPosition = "Sélectionnez une position sur la page pour placer le tampon."
|
||||
clickToExpand = "Click to expand"
|
||||
customDateDesc = "Custom format"
|
||||
dateDesc = "Current date"
|
||||
dateTimeVars = "Date & Time"
|
||||
datetimeDesc = "Date and time combined"
|
||||
dynamicVariables = "Dynamic Variables"
|
||||
examples = "Examples"
|
||||
fileVars = "File Information"
|
||||
filenameDesc = "Filename without extension"
|
||||
filenameFullDesc = "Filename with extension"
|
||||
metadataDesc = "From PDF document properties"
|
||||
metadataVars = "Document Metadata"
|
||||
multiLine = "multi-line"
|
||||
otherVars = "Other"
|
||||
pageNumberDesc = "Current page number"
|
||||
pageVars = "Page Information"
|
||||
preview = "Preview:"
|
||||
selectTemplate = "Select a template..."
|
||||
stampTextDescription = "Use dynamic variables below. Use @@ for literal @. Use \\n for new lines."
|
||||
timeDesc = "Current time"
|
||||
totalPagesDesc = "Total number of pages"
|
||||
useTemplate = "Use Template"
|
||||
uuidDesc = "Short unique identifier (8 chars)"
|
||||
variablesHelp = "Click on any variable to insert it into your stamp text. Use @@ for literal @."
|
||||
yearMonthDayDesc = "Individual date parts"
|
||||
|
||||
[AddStampRequest.error]
|
||||
failed = "Une erreur s’est produite lors de l’ajout du tampon au PDF."
|
||||
@@ -3560,6 +3594,14 @@ failed = "Une erreur s’est produite lors de l’ajout du tampon au PDF."
|
||||
[AddStampRequest.results]
|
||||
title = "Résultats du tampon"
|
||||
|
||||
[AddStampRequest.template]
|
||||
custom = "Custom"
|
||||
dateHeader = "Date Header"
|
||||
draftWatermark = "Draft Watermark"
|
||||
europeanDate = "European Date"
|
||||
pageNumberFooter = "Page Number Footer"
|
||||
timestamp = "Timestamp"
|
||||
|
||||
[removeImagePdf]
|
||||
tags = "Images,Remove Image,Page operations,Back end,server side"
|
||||
|
||||
@@ -4526,6 +4568,13 @@ description = "Nombre maximal de tentatives de connexion échouées avant le ver
|
||||
label = "Délai de réinitialisation (minutes)"
|
||||
description = "Délai avant la réinitialisation du compteur de tentatives de connexion échouées"
|
||||
|
||||
[admin.settings.security.xFrameOptions]
|
||||
label = "X-Frame-Options"
|
||||
description = "Controls whether the application can be embedded in iframes"
|
||||
deny = "Deny (Prevents all framing)"
|
||||
sameorigin = "Same Origin (Allow framing from same domain)"
|
||||
disabled = "Disabled (No X-Frame-Options header)"
|
||||
|
||||
[admin.settings.security.csrfDisabled]
|
||||
label = "Désactiver la protection CSRF"
|
||||
description = "Désactiver la protection contre la falsification de requête intersites (non recommandé)"
|
||||
|
||||
@@ -439,7 +439,9 @@ fullscreen = "Lánscáileán"
|
||||
[settings.general.updates]
|
||||
title = "Nuashonruithe Bogearraí"
|
||||
description = "Seiceáil le haghaidh nuashonruithe agus féach faisnéis leagain"
|
||||
currentVersion = "Leagan Reatha"
|
||||
currentBackendVersion = "Current Backend Version"
|
||||
currentFrontendVersion = "Current Frontend Version"
|
||||
versionMismatch = "Warning: A mismatch has been detected between the client version and the AppConfig version. Using different versions can lead to compatibility issues, errors, and security risks. Please ensure that server and client are using the same version."
|
||||
latestVersion = "Leagan is Déanaí"
|
||||
checkForUpdates = "Seiceáil le haghaidh Nuashonruithe"
|
||||
viewDetails = "Féach Sonraí"
|
||||
@@ -950,6 +952,7 @@ title = "Scoilt auto: méid/líon"
|
||||
desc = "Scoilt PDF amháin i ndoiciméid iolracha bunaithe ar mhéid, líon na leathanach, nó comhaireamh doiciméad"
|
||||
|
||||
[home.replaceColor]
|
||||
tags = "replace color,invert color,color replacement,swap colors,change color,invert,negative,color swap,find and replace color,convert color,color change"
|
||||
title = "Ionadaigh & Inbhéartaigh Dath"
|
||||
desc = "Ionadaigh nó inbhéartaigh dathanna i gcáipéisí PDF"
|
||||
|
||||
@@ -964,18 +967,22 @@ title = "Scanadh Fillteán Uathoibríoch"
|
||||
desc = "Nasc le treoir scantha fillteán uathoibrithe"
|
||||
|
||||
[home.devSsoGuide]
|
||||
tags = "SSO,single sign-on,authentication,SAML,OAuth,OIDC,login,enterprise,identity provider,IdP"
|
||||
title = "Treoir SSO"
|
||||
desc = "Nasc le treoir SSO"
|
||||
|
||||
[home.devAirgapped]
|
||||
tags = "air-gapped,offline,isolated,no internet,disconnected,secure,network isolation,standalone"
|
||||
title = "Socrú Air-gapped"
|
||||
desc = "Nasc le treoir socraithe Air-gapped"
|
||||
|
||||
[home.addPassword]
|
||||
tags = "encrypt,password,lock,secure,protect,security,encryption,safeguard,confidential,private,restrict access"
|
||||
title = "Cuir Pasfhocal leis"
|
||||
desc = "Criptigh do dhoiciméad PDF le focal faire."
|
||||
|
||||
[home.changePermissions]
|
||||
tags = "permissions,restrictions,rights,access control,allow,deny,printing,copying,editing,modify permissions,security settings,user rights"
|
||||
title = "Athrú Ceadanna"
|
||||
desc = "Athraigh srianta agus ceadanna cáipéise"
|
||||
|
||||
@@ -985,10 +992,12 @@ title = "Uathoibrigh"
|
||||
desc = "Tóg sreafaí oibre ilchéime trí ghníomhartha PDF a nascadh le chéile. Foirfe do thascanna athfhillteacha."
|
||||
|
||||
[home.overlay-pdfs]
|
||||
tags = "overlay,combine,merge,layer,superimpose,overlay PDF,layer PDFs,combine PDFs,stack,overlay pages,background,foreground,composite"
|
||||
desc = "Forleagain PDF ar bharr PDF eile"
|
||||
title = "Forleagan PDF"
|
||||
|
||||
[home.pdfTextEditor]
|
||||
tags = "edit text,modify text,change text,edit content,update text,rewrite,correct,amend,redline,revise,text editor,content editor"
|
||||
title = "Eagarthóir Téacs PDF"
|
||||
desc = "Cuir téacs agus íomhánna atá ann cheana in eagar laistigh de PDFanna"
|
||||
|
||||
@@ -3553,6 +3562,31 @@ imageSize = "Méid Íomhá"
|
||||
margin = "Imeall"
|
||||
positionAndFormatting = "Suíomh & Formáidiú"
|
||||
quickPosition = "Roghnaigh suíomh ar an leathanach le stampa a chur."
|
||||
clickToExpand = "Click to expand"
|
||||
customDateDesc = "Custom format"
|
||||
dateDesc = "Current date"
|
||||
dateTimeVars = "Date & Time"
|
||||
datetimeDesc = "Date and time combined"
|
||||
dynamicVariables = "Dynamic Variables"
|
||||
examples = "Examples"
|
||||
fileVars = "File Information"
|
||||
filenameDesc = "Filename without extension"
|
||||
filenameFullDesc = "Filename with extension"
|
||||
metadataDesc = "From PDF document properties"
|
||||
metadataVars = "Document Metadata"
|
||||
multiLine = "multi-line"
|
||||
otherVars = "Other"
|
||||
pageNumberDesc = "Current page number"
|
||||
pageVars = "Page Information"
|
||||
preview = "Preview:"
|
||||
selectTemplate = "Select a template..."
|
||||
stampTextDescription = "Use dynamic variables below. Use @@ for literal @. Use \\n for new lines."
|
||||
timeDesc = "Current time"
|
||||
totalPagesDesc = "Total number of pages"
|
||||
useTemplate = "Use Template"
|
||||
uuidDesc = "Short unique identifier (8 chars)"
|
||||
variablesHelp = "Click on any variable to insert it into your stamp text. Use @@ for literal @."
|
||||
yearMonthDayDesc = "Individual date parts"
|
||||
|
||||
[AddStampRequest.error]
|
||||
failed = "Tharla earráid agus stampa á chur leis an PDF."
|
||||
@@ -3560,6 +3594,14 @@ failed = "Tharla earráid agus stampa á chur leis an PDF."
|
||||
[AddStampRequest.results]
|
||||
title = "Torthaí Stampa"
|
||||
|
||||
[AddStampRequest.template]
|
||||
custom = "Custom"
|
||||
dateHeader = "Date Header"
|
||||
draftWatermark = "Draft Watermark"
|
||||
europeanDate = "European Date"
|
||||
pageNumberFooter = "Page Number Footer"
|
||||
timestamp = "Timestamp"
|
||||
|
||||
[removeImagePdf]
|
||||
tags = "Bain Íomhá, Oibríochtaí Leathanaigh, Cúl, taobh an fhreastalaí"
|
||||
|
||||
@@ -4526,6 +4568,13 @@ description = "Uasmhéid iarrachtaí logála isteach teipthe sula gcuirtear an c
|
||||
label = "Am Athshocraithe Logála Isteach (nóiméid)"
|
||||
description = "Am sula n‑athshocraítear iarrachtaí logála isteach teipthe"
|
||||
|
||||
[admin.settings.security.xFrameOptions]
|
||||
label = "X-Frame-Options"
|
||||
description = "Controls whether the application can be embedded in iframes"
|
||||
deny = "Deny (Prevents all framing)"
|
||||
sameorigin = "Same Origin (Allow framing from same domain)"
|
||||
disabled = "Disabled (No X-Frame-Options header)"
|
||||
|
||||
[admin.settings.security.csrfDisabled]
|
||||
label = "Díchumasaigh Cosaint CSRF"
|
||||
description = "Díchumasaigh cosaint Cross-Site Request Forgery (ní mholtar)"
|
||||
|
||||
@@ -439,7 +439,9 @@ fullscreen = "फुलस्क्रीन"
|
||||
[settings.general.updates]
|
||||
title = "सॉफ़्टवेयर अपडेट्स"
|
||||
description = "अपडेट्स जाँचें और वर्ज़न जानकारी देखें"
|
||||
currentVersion = "वर्तमान संस्करण"
|
||||
currentBackendVersion = "Current Backend Version"
|
||||
currentFrontendVersion = "Current Frontend Version"
|
||||
versionMismatch = "Warning: A mismatch has been detected between the client version and the AppConfig version. Using different versions can lead to compatibility issues, errors, and security risks. Please ensure that server and client are using the same version."
|
||||
latestVersion = "नवीनतम संस्करण"
|
||||
checkForUpdates = "अपडेट्स जाँचें"
|
||||
viewDetails = "विवरण देखें"
|
||||
@@ -950,6 +952,7 @@ title = "आकार/गिनती से ऑटो बाँटें"
|
||||
desc = "एक PDF को आकार, पृष्ठ संख्या, या दस्तावेज़ संख्या के आधार पर कई दस्तावेज़ों में विभाजित करें"
|
||||
|
||||
[home.replaceColor]
|
||||
tags = "replace color,invert color,color replacement,swap colors,change color,invert,negative,color swap,find and replace color,convert color,color change"
|
||||
title = "रंग बदलें/उलटें"
|
||||
desc = "PDF दस्तावेज़ों में रंगों को प्रतिस्थापित या उलटें"
|
||||
|
||||
@@ -964,18 +967,22 @@ title = "स्वचालित फ़ोल्डर स्कैनिंग
|
||||
desc = "स्वचालित फ़ोल्डर स्कैनिंग गाइड के लिए लिंक"
|
||||
|
||||
[home.devSsoGuide]
|
||||
tags = "SSO,single sign-on,authentication,SAML,OAuth,OIDC,login,enterprise,identity provider,IdP"
|
||||
title = "SSO गाइड"
|
||||
desc = "SSO गाइड के लिए लिंक"
|
||||
|
||||
[home.devAirgapped]
|
||||
tags = "air-gapped,offline,isolated,no internet,disconnected,secure,network isolation,standalone"
|
||||
title = "एयर-गैप्ड सेटअप"
|
||||
desc = "एयर-गैप्ड सेटअप गाइड के लिए लिंक"
|
||||
|
||||
[home.addPassword]
|
||||
tags = "encrypt,password,lock,secure,protect,security,encryption,safeguard,confidential,private,restrict access"
|
||||
title = "पासवर्ड जोड़ें"
|
||||
desc = "पासवर्ड के साथ अपने PDF दस्तावेज को एन्क्रिप्ट करें।"
|
||||
|
||||
[home.changePermissions]
|
||||
tags = "permissions,restrictions,rights,access control,allow,deny,printing,copying,editing,modify permissions,security settings,user rights"
|
||||
title = "अनुमतियां बदलें"
|
||||
desc = "दस्तावेज़ प्रतिबंध और अनुमतियाँ बदलें"
|
||||
|
||||
@@ -985,10 +992,12 @@ title = "स्वचालित करें"
|
||||
desc = "PDF क्रियाओं को जोड़कर बहु-चरणीय वर्कफ़्लो बनाएँ। बार-बार होने वाले कार्यों के लिए उपयुक्त।"
|
||||
|
||||
[home.overlay-pdfs]
|
||||
tags = "overlay,combine,merge,layer,superimpose,overlay PDF,layer PDFs,combine PDFs,stack,overlay pages,background,foreground,composite"
|
||||
desc = "PDF को दूसरी PDF के ऊपर ओवरले करें"
|
||||
title = "PDF ओवरले करें"
|
||||
|
||||
[home.pdfTextEditor]
|
||||
tags = "edit text,modify text,change text,edit content,update text,rewrite,correct,amend,redline,revise,text editor,content editor"
|
||||
title = "PDF टेक्स्ट एडिटर"
|
||||
desc = "ग्रुप्ड टेक्स्ट एडिटिंग और PDF पुनर्जनन के साथ Stirling PDF JSON एक्सपोर्ट की समीक्षा व संपादन करें"
|
||||
|
||||
@@ -3553,6 +3562,31 @@ imageSize = "छवि आकार"
|
||||
margin = "हाशिया"
|
||||
positionAndFormatting = "स्थिति और फ़ॉर्मैटिंग"
|
||||
quickPosition = "मुहर रखने के लिए पृष्ठ पर एक स्थान चुनें।"
|
||||
clickToExpand = "Click to expand"
|
||||
customDateDesc = "Custom format"
|
||||
dateDesc = "Current date"
|
||||
dateTimeVars = "Date & Time"
|
||||
datetimeDesc = "Date and time combined"
|
||||
dynamicVariables = "Dynamic Variables"
|
||||
examples = "Examples"
|
||||
fileVars = "File Information"
|
||||
filenameDesc = "Filename without extension"
|
||||
filenameFullDesc = "Filename with extension"
|
||||
metadataDesc = "From PDF document properties"
|
||||
metadataVars = "Document Metadata"
|
||||
multiLine = "multi-line"
|
||||
otherVars = "Other"
|
||||
pageNumberDesc = "Current page number"
|
||||
pageVars = "Page Information"
|
||||
preview = "Preview:"
|
||||
selectTemplate = "Select a template..."
|
||||
stampTextDescription = "Use dynamic variables below. Use @@ for literal @. Use \\n for new lines."
|
||||
timeDesc = "Current time"
|
||||
totalPagesDesc = "Total number of pages"
|
||||
useTemplate = "Use Template"
|
||||
uuidDesc = "Short unique identifier (8 chars)"
|
||||
variablesHelp = "Click on any variable to insert it into your stamp text. Use @@ for literal @."
|
||||
yearMonthDayDesc = "Individual date parts"
|
||||
|
||||
[AddStampRequest.error]
|
||||
failed = "PDF में मुहर जोड़ते समय त्रुटि हुई।"
|
||||
@@ -3560,6 +3594,14 @@ failed = "PDF में मुहर जोड़ते समय त्रु
|
||||
[AddStampRequest.results]
|
||||
title = "मुहर के परिणाम"
|
||||
|
||||
[AddStampRequest.template]
|
||||
custom = "Custom"
|
||||
dateHeader = "Date Header"
|
||||
draftWatermark = "Draft Watermark"
|
||||
europeanDate = "European Date"
|
||||
pageNumberFooter = "Page Number Footer"
|
||||
timestamp = "Timestamp"
|
||||
|
||||
[removeImagePdf]
|
||||
tags = "छवि हटाएं,पृष्ठ कार्य,बैक एंड,सर्वर साइड"
|
||||
|
||||
@@ -4526,6 +4568,13 @@ description = "खाते को लॉक करने से पहले
|
||||
label = "लॉगिन रीसेट समय (मिनट)"
|
||||
description = "वह समय जिसके बाद असफल लॉगिन प्रयास रीसेट हो जाते हैं"
|
||||
|
||||
[admin.settings.security.xFrameOptions]
|
||||
label = "X-Frame-Options"
|
||||
description = "Controls whether the application can be embedded in iframes"
|
||||
deny = "Deny (Prevents all framing)"
|
||||
sameorigin = "Same Origin (Allow framing from same domain)"
|
||||
disabled = "Disabled (No X-Frame-Options header)"
|
||||
|
||||
[admin.settings.security.csrfDisabled]
|
||||
label = "CSRF सुरक्षा निष्क्रिय करें"
|
||||
description = "Cross-Site Request Forgery सुरक्षा निष्क्रिय करें (अनुशंसित नहीं)"
|
||||
|
||||
@@ -439,7 +439,9 @@ fullscreen = "Cijeli zaslon"
|
||||
[settings.general.updates]
|
||||
title = "Ažuriranja softvera"
|
||||
description = "Provjerite ažuriranja i pogledajte informacije o verziji"
|
||||
currentVersion = "Trenutačna verzija"
|
||||
currentBackendVersion = "Current Backend Version"
|
||||
currentFrontendVersion = "Current Frontend Version"
|
||||
versionMismatch = "Warning: A mismatch has been detected between the client version and the AppConfig version. Using different versions can lead to compatibility issues, errors, and security risks. Please ensure that server and client are using the same version."
|
||||
latestVersion = "Najnovija verzija"
|
||||
checkForUpdates = "Provjeri ažuriranja"
|
||||
viewDetails = "Prikaži detalje"
|
||||
@@ -950,6 +952,7 @@ title = "Auto dijeli po veličini/broju"
|
||||
desc = "Podijelite jedan PDF na više dokumenata na temelju veličine, broja stranica ili broja dokumenata"
|
||||
|
||||
[home.replaceColor]
|
||||
tags = "replace color,invert color,color replacement,swap colors,change color,invert,negative,color swap,find and replace color,convert color,color change"
|
||||
title = "Zamijeni i invertiraj boju"
|
||||
desc = "Zamijenite ili invertirajte boje u PDF dokumentima"
|
||||
|
||||
@@ -964,18 +967,22 @@ title = "Auto skeniranje mapa"
|
||||
desc = "Poveznica na vodič za automatizirano skeniranje mapa"
|
||||
|
||||
[home.devSsoGuide]
|
||||
tags = "SSO,single sign-on,authentication,SAML,OAuth,OIDC,login,enterprise,identity provider,IdP"
|
||||
title = "SSO vodič"
|
||||
desc = "Poveznica na SSO vodič"
|
||||
|
||||
[home.devAirgapped]
|
||||
tags = "air-gapped,offline,isolated,no internet,disconnected,secure,network isolation,standalone"
|
||||
title = "Air-gapped postavljanje"
|
||||
desc = "Poveznica na vodič za air-gapped postavljanje"
|
||||
|
||||
[home.addPassword]
|
||||
tags = "encrypt,password,lock,secure,protect,security,encryption,safeguard,confidential,private,restrict access"
|
||||
title = "Dodaj lozinku"
|
||||
desc = "Šifrirajte svoj PDF dokument lozinkom.."
|
||||
|
||||
[home.changePermissions]
|
||||
tags = "permissions,restrictions,rights,access control,allow,deny,printing,copying,editing,modify permissions,security settings,user rights"
|
||||
title = "Promjena dopuštenja"
|
||||
desc = "Promijenite ograničenja dokumenta i dopuštenja"
|
||||
|
||||
@@ -985,10 +992,12 @@ title = "Automatiziraj"
|
||||
desc = "Izgradite višekoračne tijekove rada povezivanjem PDF radnji. Idealno za ponavljajuće zadatke."
|
||||
|
||||
[home.overlay-pdfs]
|
||||
tags = "overlay,combine,merge,layer,superimpose,overlay PDF,layer PDFs,combine PDFs,stack,overlay pages,background,foreground,composite"
|
||||
desc = "Preklapa PDF-ove na drugi PDF"
|
||||
title = "Preklapanje PDF-ova"
|
||||
|
||||
[home.pdfTextEditor]
|
||||
tags = "edit text,modify text,change text,edit content,update text,rewrite,correct,amend,redline,revise,text editor,content editor"
|
||||
title = "PDF uređivač teksta"
|
||||
desc = "Pregledajte i uredite Stirling PDF JSON izvoze s grupnim uređivanjem teksta i ponovnim generiranjem PDF-a"
|
||||
|
||||
@@ -3553,6 +3562,31 @@ imageSize = "Veličina slike"
|
||||
margin = "Margina"
|
||||
positionAndFormatting = "Položaj i oblikovanje"
|
||||
quickPosition = "Odaberite položaj na stranici za postavljanje pečata."
|
||||
clickToExpand = "Click to expand"
|
||||
customDateDesc = "Custom format"
|
||||
dateDesc = "Current date"
|
||||
dateTimeVars = "Date & Time"
|
||||
datetimeDesc = "Date and time combined"
|
||||
dynamicVariables = "Dynamic Variables"
|
||||
examples = "Examples"
|
||||
fileVars = "File Information"
|
||||
filenameDesc = "Filename without extension"
|
||||
filenameFullDesc = "Filename with extension"
|
||||
metadataDesc = "From PDF document properties"
|
||||
metadataVars = "Document Metadata"
|
||||
multiLine = "multi-line"
|
||||
otherVars = "Other"
|
||||
pageNumberDesc = "Current page number"
|
||||
pageVars = "Page Information"
|
||||
preview = "Preview:"
|
||||
selectTemplate = "Select a template..."
|
||||
stampTextDescription = "Use dynamic variables below. Use @@ for literal @. Use \\n for new lines."
|
||||
timeDesc = "Current time"
|
||||
totalPagesDesc = "Total number of pages"
|
||||
useTemplate = "Use Template"
|
||||
uuidDesc = "Short unique identifier (8 chars)"
|
||||
variablesHelp = "Click on any variable to insert it into your stamp text. Use @@ for literal @."
|
||||
yearMonthDayDesc = "Individual date parts"
|
||||
|
||||
[AddStampRequest.error]
|
||||
failed = "Došlo je do pogreške pri dodavanju pečata u PDF."
|
||||
@@ -3560,6 +3594,14 @@ failed = "Došlo je do pogreške pri dodavanju pečata u PDF."
|
||||
[AddStampRequest.results]
|
||||
title = "Rezultati pečata"
|
||||
|
||||
[AddStampRequest.template]
|
||||
custom = "Custom"
|
||||
dateHeader = "Date Header"
|
||||
draftWatermark = "Draft Watermark"
|
||||
europeanDate = "European Date"
|
||||
pageNumberFooter = "Page Number Footer"
|
||||
timestamp = "Timestamp"
|
||||
|
||||
[removeImagePdf]
|
||||
tags = "Ukloni sliku, Rad sa stranicama, Back end, server strana"
|
||||
|
||||
@@ -4526,6 +4568,13 @@ description = "Maksimalan broj neuspjelih pokušaja prijave prije zaključavanja
|
||||
label = "Vrijeme resetiranja prijave (minute)"
|
||||
description = "Vrijeme prije resetiranja neuspjelih pokušaja prijave"
|
||||
|
||||
[admin.settings.security.xFrameOptions]
|
||||
label = "X-Frame-Options"
|
||||
description = "Controls whether the application can be embedded in iframes"
|
||||
deny = "Deny (Prevents all framing)"
|
||||
sameorigin = "Same Origin (Allow framing from same domain)"
|
||||
disabled = "Disabled (No X-Frame-Options header)"
|
||||
|
||||
[admin.settings.security.csrfDisabled]
|
||||
label = "Onemogući zaštitu od CSRF-a"
|
||||
description = "Onemogući zaštitu od Cross-Site Request Forgery (ne preporučuje se)"
|
||||
|
||||
@@ -439,7 +439,9 @@ fullscreen = "Teljes képernyő"
|
||||
[settings.general.updates]
|
||||
title = "Szoftverfrissítések"
|
||||
description = "Frissítések keresése és verzióinformációk megtekintése"
|
||||
currentVersion = "Jelenlegi verzió"
|
||||
currentBackendVersion = "Current Backend Version"
|
||||
currentFrontendVersion = "Current Frontend Version"
|
||||
versionMismatch = "Warning: A mismatch has been detected between the client version and the AppConfig version. Using different versions can lead to compatibility issues, errors, and security risks. Please ensure that server and client are using the same version."
|
||||
latestVersion = "Legújabb verzió"
|
||||
checkForUpdates = "Frissítések keresése"
|
||||
viewDetails = "Részletek megtekintése"
|
||||
@@ -950,6 +952,7 @@ title = "Auto felosztás méret/darab"
|
||||
desc = "Egyetlen PDF felosztása több dokumentumra méret, oldalszám vagy dokumentumszám alapján"
|
||||
|
||||
[home.replaceColor]
|
||||
tags = "replace color,invert color,color replacement,swap colors,change color,invert,negative,color swap,find and replace color,convert color,color change"
|
||||
title = "Színek cseréje és invertálása"
|
||||
desc = "Színek cseréje vagy invertálása PDF dokumentumokban"
|
||||
|
||||
@@ -964,18 +967,22 @@ title = "Automatikus mappaszkennelés"
|
||||
desc = "Hivatkozás az automatikus mappaszkennelés útmutatójára"
|
||||
|
||||
[home.devSsoGuide]
|
||||
tags = "SSO,single sign-on,authentication,SAML,OAuth,OIDC,login,enterprise,identity provider,IdP"
|
||||
title = "SSO útmutató"
|
||||
desc = "Hivatkozás az SSO útmutatóra"
|
||||
|
||||
[home.devAirgapped]
|
||||
tags = "air-gapped,offline,isolated,no internet,disconnected,secure,network isolation,standalone"
|
||||
title = "Air-gapped beállítás"
|
||||
desc = "Hivatkozás az elszigetelt környezet beállítási útmutatójára"
|
||||
|
||||
[home.addPassword]
|
||||
tags = "encrypt,password,lock,secure,protect,security,encryption,safeguard,confidential,private,restrict access"
|
||||
title = "Jelszó hozzáadása"
|
||||
desc = "PDF dokumentum jelszavas védelme"
|
||||
|
||||
[home.changePermissions]
|
||||
tags = "permissions,restrictions,rights,access control,allow,deny,printing,copying,editing,modify permissions,security settings,user rights"
|
||||
title = "Jogosultságok módosítása"
|
||||
desc = "Dokumentumkorlátozások és jogosultságok módosítása"
|
||||
|
||||
@@ -985,10 +992,12 @@ title = "Automatizálás"
|
||||
desc = "Többlépéses munkafolyamatok összeállítása PDF műveletek összefűzésével. Ideális ismétlődő feladatokhoz."
|
||||
|
||||
[home.overlay-pdfs]
|
||||
tags = "overlay,combine,merge,layer,superimpose,overlay PDF,layer PDFs,combine PDFs,stack,overlay pages,background,foreground,composite"
|
||||
desc = "PDF-ek egymásra helyezése egy másik PDF-en"
|
||||
title = "PDF-ek egymásra helyezése"
|
||||
|
||||
[home.pdfTextEditor]
|
||||
tags = "edit text,modify text,change text,edit content,update text,rewrite,correct,amend,redline,revise,text editor,content editor"
|
||||
title = "PDF szövegszerkesztő"
|
||||
desc = "Nézze át és szerkessze a Stirling PDF JSON exportokat csoportosított szövegszerkesztéssel és PDF-újragenerálással"
|
||||
|
||||
@@ -3553,6 +3562,31 @@ imageSize = "Képméret"
|
||||
margin = "Margó"
|
||||
positionAndFormatting = "Pozíció és formázás"
|
||||
quickPosition = "Válasszon pozíciót az oldalon a bélyeg elhelyezéséhez."
|
||||
clickToExpand = "Click to expand"
|
||||
customDateDesc = "Custom format"
|
||||
dateDesc = "Current date"
|
||||
dateTimeVars = "Date & Time"
|
||||
datetimeDesc = "Date and time combined"
|
||||
dynamicVariables = "Dynamic Variables"
|
||||
examples = "Examples"
|
||||
fileVars = "File Information"
|
||||
filenameDesc = "Filename without extension"
|
||||
filenameFullDesc = "Filename with extension"
|
||||
metadataDesc = "From PDF document properties"
|
||||
metadataVars = "Document Metadata"
|
||||
multiLine = "multi-line"
|
||||
otherVars = "Other"
|
||||
pageNumberDesc = "Current page number"
|
||||
pageVars = "Page Information"
|
||||
preview = "Preview:"
|
||||
selectTemplate = "Select a template..."
|
||||
stampTextDescription = "Use dynamic variables below. Use @@ for literal @. Use \\n for new lines."
|
||||
timeDesc = "Current time"
|
||||
totalPagesDesc = "Total number of pages"
|
||||
useTemplate = "Use Template"
|
||||
uuidDesc = "Short unique identifier (8 chars)"
|
||||
variablesHelp = "Click on any variable to insert it into your stamp text. Use @@ for literal @."
|
||||
yearMonthDayDesc = "Individual date parts"
|
||||
|
||||
[AddStampRequest.error]
|
||||
failed = "Hiba történt a bélyeg hozzáadása közben a PDF-hez."
|
||||
@@ -3560,6 +3594,14 @@ failed = "Hiba történt a bélyeg hozzáadása közben a PDF-hez."
|
||||
[AddStampRequest.results]
|
||||
title = "Bélyegzés eredményei"
|
||||
|
||||
[AddStampRequest.template]
|
||||
custom = "Custom"
|
||||
dateHeader = "Date Header"
|
||||
draftWatermark = "Draft Watermark"
|
||||
europeanDate = "European Date"
|
||||
pageNumberFooter = "Page Number Footer"
|
||||
timestamp = "Timestamp"
|
||||
|
||||
[removeImagePdf]
|
||||
tags = "Képek eltávolítása,Oldalműveletek,Backend,szerver oldali"
|
||||
|
||||
@@ -4526,6 +4568,13 @@ description = "Sikertelen bejelentkezési kísérletek maximális száma fiókz
|
||||
label = "Visszaállítás ideje (perc)"
|
||||
description = "Idő, ami után a sikertelen bejelentkezési kísérletek számlálója lenullázódik"
|
||||
|
||||
[admin.settings.security.xFrameOptions]
|
||||
label = "X-Frame-Options"
|
||||
description = "Controls whether the application can be embedded in iframes"
|
||||
deny = "Deny (Prevents all framing)"
|
||||
sameorigin = "Same Origin (Allow framing from same domain)"
|
||||
disabled = "Disabled (No X-Frame-Options header)"
|
||||
|
||||
[admin.settings.security.csrfDisabled]
|
||||
label = "CSRF védelem letiltása"
|
||||
description = "Cross-Site Request Forgery védelem letiltása (nem ajánlott)"
|
||||
|
||||
@@ -439,7 +439,9 @@ fullscreen = "Layar penuh"
|
||||
[settings.general.updates]
|
||||
title = "Pembaruan Software"
|
||||
description = "Periksa pembaruan dan lihat informasi versi"
|
||||
currentVersion = "Versi Saat Ini"
|
||||
currentBackendVersion = "Current Backend Version"
|
||||
currentFrontendVersion = "Current Frontend Version"
|
||||
versionMismatch = "Warning: A mismatch has been detected between the client version and the AppConfig version. Using different versions can lead to compatibility issues, errors, and security risks. Please ensure that server and client are using the same version."
|
||||
latestVersion = "Versi Terbaru"
|
||||
checkForUpdates = "Periksa Pembaruan"
|
||||
viewDetails = "Lihat Detail"
|
||||
@@ -950,6 +952,7 @@ title = "Pisah otomatis ukuran/jumlah"
|
||||
desc = "Membagi satu PDF menjadi beberapa dokumen berdasarkan ukuran, jumlah halaman, atau jumlah dokumen"
|
||||
|
||||
[home.replaceColor]
|
||||
tags = "replace color,invert color,color replacement,swap colors,change color,invert,negative,color swap,find and replace color,convert color,color change"
|
||||
title = "Ganti & Balik Warna"
|
||||
desc = "Ganti atau balik warna dalam dokumen PDF"
|
||||
|
||||
@@ -964,18 +967,22 @@ title = "Pemindaian Folder Otomatis"
|
||||
desc = "Tautan ke panduan pemindaian folder otomatis"
|
||||
|
||||
[home.devSsoGuide]
|
||||
tags = "SSO,single sign-on,authentication,SAML,OAuth,OIDC,login,enterprise,identity provider,IdP"
|
||||
title = "Panduan SSO"
|
||||
desc = "Tautan ke panduan SSO"
|
||||
|
||||
[home.devAirgapped]
|
||||
tags = "air-gapped,offline,isolated,no internet,disconnected,secure,network isolation,standalone"
|
||||
title = "Penyiapan Air-gapped"
|
||||
desc = "Tautan ke panduan penyiapan air-gapped"
|
||||
|
||||
[home.addPassword]
|
||||
tags = "encrypt,password,lock,secure,protect,security,encryption,safeguard,confidential,private,restrict access"
|
||||
title = "Tambahkan Kata Sandi"
|
||||
desc = "Enkripsi dokumen PDF Anda dengan kata sandi."
|
||||
|
||||
[home.changePermissions]
|
||||
tags = "permissions,restrictions,rights,access control,allow,deny,printing,copying,editing,modify permissions,security settings,user rights"
|
||||
title = "Ganti Perizinan"
|
||||
desc = "Ubah pembatasan dan izin dokumen"
|
||||
|
||||
@@ -985,10 +992,12 @@ title = "Otomasi"
|
||||
desc = "Bangun alur kerja multi-langkah dengan merangkai tindakan PDF. Ideal untuk tugas berulang."
|
||||
|
||||
[home.overlay-pdfs]
|
||||
tags = "overlay,combine,merge,layer,superimpose,overlay PDF,layer PDFs,combine PDFs,stack,overlay pages,background,foreground,composite"
|
||||
desc = "Menumpuk PDF di atas PDF lain"
|
||||
title = "Tumpuk PDF"
|
||||
|
||||
[home.pdfTextEditor]
|
||||
tags = "edit text,modify text,change text,edit content,update text,rewrite,correct,amend,redline,revise,text editor,content editor"
|
||||
title = "Editor Teks PDF"
|
||||
desc = "Tinjau dan edit ekspor Stirling PDF JSON dengan pengeditan teks terkelompok dan pembuatan ulang PDF"
|
||||
|
||||
@@ -3553,6 +3562,31 @@ imageSize = "Ukuran Gambar"
|
||||
margin = "Margin"
|
||||
positionAndFormatting = "Posisi & Pemformatan"
|
||||
quickPosition = "Pilih posisi pada halaman untuk menempatkan stempel."
|
||||
clickToExpand = "Click to expand"
|
||||
customDateDesc = "Custom format"
|
||||
dateDesc = "Current date"
|
||||
dateTimeVars = "Date & Time"
|
||||
datetimeDesc = "Date and time combined"
|
||||
dynamicVariables = "Dynamic Variables"
|
||||
examples = "Examples"
|
||||
fileVars = "File Information"
|
||||
filenameDesc = "Filename without extension"
|
||||
filenameFullDesc = "Filename with extension"
|
||||
metadataDesc = "From PDF document properties"
|
||||
metadataVars = "Document Metadata"
|
||||
multiLine = "multi-line"
|
||||
otherVars = "Other"
|
||||
pageNumberDesc = "Current page number"
|
||||
pageVars = "Page Information"
|
||||
preview = "Preview:"
|
||||
selectTemplate = "Select a template..."
|
||||
stampTextDescription = "Use dynamic variables below. Use @@ for literal @. Use \\n for new lines."
|
||||
timeDesc = "Current time"
|
||||
totalPagesDesc = "Total number of pages"
|
||||
useTemplate = "Use Template"
|
||||
uuidDesc = "Short unique identifier (8 chars)"
|
||||
variablesHelp = "Click on any variable to insert it into your stamp text. Use @@ for literal @."
|
||||
yearMonthDayDesc = "Individual date parts"
|
||||
|
||||
[AddStampRequest.error]
|
||||
failed = "Terjadi kesalahan saat menambahkan stempel ke PDF."
|
||||
@@ -3560,6 +3594,14 @@ failed = "Terjadi kesalahan saat menambahkan stempel ke PDF."
|
||||
[AddStampRequest.results]
|
||||
title = "Hasil Stempel"
|
||||
|
||||
[AddStampRequest.template]
|
||||
custom = "Custom"
|
||||
dateHeader = "Date Header"
|
||||
draftWatermark = "Draft Watermark"
|
||||
europeanDate = "European Date"
|
||||
pageNumberFooter = "Page Number Footer"
|
||||
timestamp = "Timestamp"
|
||||
|
||||
[removeImagePdf]
|
||||
tags = "Hapus Gambar,Operasi Halaman,Backend,server side"
|
||||
|
||||
@@ -4526,6 +4568,13 @@ description = "Jumlah maksimum kegagalan login sebelum akun terkunci"
|
||||
label = "Waktu Reset Login (menit)"
|
||||
description = "Waktu sebelum upaya login yang gagal direset"
|
||||
|
||||
[admin.settings.security.xFrameOptions]
|
||||
label = "X-Frame-Options"
|
||||
description = "Controls whether the application can be embedded in iframes"
|
||||
deny = "Deny (Prevents all framing)"
|
||||
sameorigin = "Same Origin (Allow framing from same domain)"
|
||||
disabled = "Disabled (No X-Frame-Options header)"
|
||||
|
||||
[admin.settings.security.csrfDisabled]
|
||||
label = "Nonaktifkan Perlindungan CSRF"
|
||||
description = "Nonaktifkan perlindungan Cross-Site Request Forgery (tidak disarankan)"
|
||||
|
||||
@@ -439,7 +439,9 @@ fullscreen = "Schermo intero"
|
||||
[settings.general.updates]
|
||||
title = "Aggiornamenti software"
|
||||
description = "Controlla aggiornamenti e visualizza informazioni sulla versione"
|
||||
currentVersion = "Versione attuale"
|
||||
currentBackendVersion = "Current Backend Version"
|
||||
currentFrontendVersion = "Current Frontend Version"
|
||||
versionMismatch = "Warning: A mismatch has been detected between the client version and the AppConfig version. Using different versions can lead to compatibility issues, errors, and security risks. Please ensure that server and client are using the same version."
|
||||
latestVersion = "Ultima versione"
|
||||
checkForUpdates = "Controlla aggiornamenti"
|
||||
viewDetails = "Vedi dettagli"
|
||||
@@ -950,6 +952,7 @@ title = "Dividi auto per peso/pagine"
|
||||
desc = "Dividi un singolo PDF in più documenti in base alle dimensioni, al numero di pagine o al numero di documenti"
|
||||
|
||||
[home.replaceColor]
|
||||
tags = "replace color,invert color,color replacement,swap colors,change color,invert,negative,color swap,find and replace color,convert color,color change"
|
||||
title = "Sostituisci e inverti colore"
|
||||
desc = "Sostituisci o inverti i colori nei documenti PDF"
|
||||
|
||||
@@ -964,18 +967,22 @@ title = "Scansione automatica cartelle"
|
||||
desc = "Link alla guida per scansione cartelle automatizzata"
|
||||
|
||||
[home.devSsoGuide]
|
||||
tags = "SSO,single sign-on,authentication,SAML,OAuth,OIDC,login,enterprise,identity provider,IdP"
|
||||
title = "Guida SSO"
|
||||
desc = "Link alla guida SSO"
|
||||
|
||||
[home.devAirgapped]
|
||||
tags = "air-gapped,offline,isolated,no internet,disconnected,secure,network isolation,standalone"
|
||||
title = "Setup isolato (air‑gapped)"
|
||||
desc = "Link alla guida per setup air‑gapped"
|
||||
|
||||
[home.addPassword]
|
||||
tags = "encrypt,password,lock,secure,protect,security,encryption,safeguard,confidential,private,restrict access"
|
||||
title = "Aggiungi Password"
|
||||
desc = "Crittografa il tuo PDF con una password."
|
||||
|
||||
[home.changePermissions]
|
||||
tags = "permissions,restrictions,rights,access control,allow,deny,printing,copying,editing,modify permissions,security settings,user rights"
|
||||
title = "Cambia Permessi"
|
||||
desc = "Modifica restrizioni e permessi del documento"
|
||||
|
||||
@@ -985,10 +992,12 @@ title = "Automatizza"
|
||||
desc = "Crea flussi multi‑step concatenando azioni PDF. Ideale per attività ricorrenti."
|
||||
|
||||
[home.overlay-pdfs]
|
||||
tags = "overlay,combine,merge,layer,superimpose,overlay PDF,layer PDFs,combine PDFs,stack,overlay pages,background,foreground,composite"
|
||||
desc = "Sovrapponi un PDF sopra un altro"
|
||||
title = "Sovrapponi PDF"
|
||||
|
||||
[home.pdfTextEditor]
|
||||
tags = "edit text,modify text,change text,edit content,update text,rewrite,correct,amend,redline,revise,text editor,content editor"
|
||||
title = "Editor di testo PDF"
|
||||
desc = "Modifica testo e immagini esistenti nei PDF"
|
||||
|
||||
@@ -3553,6 +3562,31 @@ imageSize = "Dimensione immagine"
|
||||
margin = "Margine"
|
||||
positionAndFormatting = "Posizione e formattazione"
|
||||
quickPosition = "Seleziona una posizione sulla pagina in cui posizionare il timbro."
|
||||
clickToExpand = "Click to expand"
|
||||
customDateDesc = "Custom format"
|
||||
dateDesc = "Current date"
|
||||
dateTimeVars = "Date & Time"
|
||||
datetimeDesc = "Date and time combined"
|
||||
dynamicVariables = "Dynamic Variables"
|
||||
examples = "Examples"
|
||||
fileVars = "File Information"
|
||||
filenameDesc = "Filename without extension"
|
||||
filenameFullDesc = "Filename with extension"
|
||||
metadataDesc = "From PDF document properties"
|
||||
metadataVars = "Document Metadata"
|
||||
multiLine = "multi-line"
|
||||
otherVars = "Other"
|
||||
pageNumberDesc = "Current page number"
|
||||
pageVars = "Page Information"
|
||||
preview = "Preview:"
|
||||
selectTemplate = "Select a template..."
|
||||
stampTextDescription = "Use dynamic variables below. Use @@ for literal @. Use \\n for new lines."
|
||||
timeDesc = "Current time"
|
||||
totalPagesDesc = "Total number of pages"
|
||||
useTemplate = "Use Template"
|
||||
uuidDesc = "Short unique identifier (8 chars)"
|
||||
variablesHelp = "Click on any variable to insert it into your stamp text. Use @@ for literal @."
|
||||
yearMonthDayDesc = "Individual date parts"
|
||||
|
||||
[AddStampRequest.error]
|
||||
failed = "Si è verificato un errore durante l'aggiunta del timbro al PDF."
|
||||
@@ -3560,6 +3594,14 @@ failed = "Si è verificato un errore durante l'aggiunta del timbro al PDF."
|
||||
[AddStampRequest.results]
|
||||
title = "Risultati timbro"
|
||||
|
||||
[AddStampRequest.template]
|
||||
custom = "Custom"
|
||||
dateHeader = "Date Header"
|
||||
draftWatermark = "Draft Watermark"
|
||||
europeanDate = "European Date"
|
||||
pageNumberFooter = "Page Number Footer"
|
||||
timestamp = "Timestamp"
|
||||
|
||||
[removeImagePdf]
|
||||
tags = "Rimuovi immagine,operazioni sulla pagina,back-end,lato server"
|
||||
|
||||
@@ -4526,6 +4568,13 @@ description = "Numero massimo di tentativi di accesso falliti prima del blocco d
|
||||
label = "Tempo di reset accessi (minuti)"
|
||||
description = "Tempo prima che i tentativi di accesso falliti vengano azzerati"
|
||||
|
||||
[admin.settings.security.xFrameOptions]
|
||||
label = "X-Frame-Options"
|
||||
description = "Controls whether the application can be embedded in iframes"
|
||||
deny = "Deny (Prevents all framing)"
|
||||
sameorigin = "Same Origin (Allow framing from same domain)"
|
||||
disabled = "Disabled (No X-Frame-Options header)"
|
||||
|
||||
[admin.settings.security.csrfDisabled]
|
||||
label = "Disabilita protezione CSRF"
|
||||
description = "Disabilita la protezione Cross-Site Request Forgery (non raccomandato)"
|
||||
|
||||
@@ -439,7 +439,9 @@ fullscreen = "フルスクリーン"
|
||||
[settings.general.updates]
|
||||
title = "ソフトウェア更新"
|
||||
description = "更新の確認とバージョン情報の表示"
|
||||
currentVersion = "現在のバージョン"
|
||||
currentBackendVersion = "Current Backend Version"
|
||||
currentFrontendVersion = "Current Frontend Version"
|
||||
versionMismatch = "Warning: A mismatch has been detected between the client version and the AppConfig version. Using different versions can lead to compatibility issues, errors, and security risks. Please ensure that server and client are using the same version."
|
||||
latestVersion = "最新バージョン"
|
||||
checkForUpdates = "更新を確認"
|
||||
viewDetails = "詳細を表示"
|
||||
@@ -950,6 +952,7 @@ title = "サイズ・数による自動分割"
|
||||
desc = "サイズ・ページ数またはドキュメント数に基づいて、1つのPDFを複数のドキュメントに分割します。"
|
||||
|
||||
[home.replaceColor]
|
||||
tags = "replace color,invert color,color replacement,swap colors,change color,invert,negative,color swap,find and replace color,convert color,color change"
|
||||
title = "色の置換と反転"
|
||||
desc = "PDF 文書の色を置換または反転"
|
||||
|
||||
@@ -964,18 +967,22 @@ title = "自動フォルダスキャン"
|
||||
desc = "自動フォルダスキャン ガイドへのリンク"
|
||||
|
||||
[home.devSsoGuide]
|
||||
tags = "SSO,single sign-on,authentication,SAML,OAuth,OIDC,login,enterprise,identity provider,IdP"
|
||||
title = "SSO ガイド"
|
||||
desc = "SSO ガイドへのリンク"
|
||||
|
||||
[home.devAirgapped]
|
||||
tags = "air-gapped,offline,isolated,no internet,disconnected,secure,network isolation,standalone"
|
||||
title = "エアギャップ設定"
|
||||
desc = "エアギャップ環境のセットアップガイドへのリンク"
|
||||
|
||||
[home.addPassword]
|
||||
tags = "encrypt,password,lock,secure,protect,security,encryption,safeguard,confidential,private,restrict access"
|
||||
title = "パスワードの追加"
|
||||
desc = "PDFをパスワードで暗号化します。"
|
||||
|
||||
[home.changePermissions]
|
||||
tags = "permissions,restrictions,rights,access control,allow,deny,printing,copying,editing,modify permissions,security settings,user rights"
|
||||
title = "権限の変更"
|
||||
desc = "文書の制限と権限を変更"
|
||||
|
||||
@@ -985,10 +992,12 @@ title = "自動化"
|
||||
desc = "PDF アクションを連結して複数ステップのワークフローを構築。繰り返し作業に最適です。"
|
||||
|
||||
[home.overlay-pdfs]
|
||||
tags = "overlay,combine,merge,layer,superimpose,overlay PDF,layer PDFs,combine PDFs,stack,overlay pages,background,foreground,composite"
|
||||
desc = "1つのPDFを別のPDFの上に重ねます"
|
||||
title = "PDFを重ね合わせ"
|
||||
|
||||
[home.pdfTextEditor]
|
||||
tags = "edit text,modify text,change text,edit content,update text,rewrite,correct,amend,redline,revise,text editor,content editor"
|
||||
title = "PDFテキストエディター"
|
||||
desc = "グループ化されたテキスト編集とPDF再生成で、Stirling PDF の JSON エクスポートをレビュー・編集します。"
|
||||
|
||||
@@ -3553,6 +3562,31 @@ imageSize = "画像サイズ"
|
||||
margin = "余白"
|
||||
positionAndFormatting = "位置と書式"
|
||||
quickPosition = "ページ上の配置位置を選択してください。"
|
||||
clickToExpand = "Click to expand"
|
||||
customDateDesc = "Custom format"
|
||||
dateDesc = "Current date"
|
||||
dateTimeVars = "Date & Time"
|
||||
datetimeDesc = "Date and time combined"
|
||||
dynamicVariables = "Dynamic Variables"
|
||||
examples = "Examples"
|
||||
fileVars = "File Information"
|
||||
filenameDesc = "Filename without extension"
|
||||
filenameFullDesc = "Filename with extension"
|
||||
metadataDesc = "From PDF document properties"
|
||||
metadataVars = "Document Metadata"
|
||||
multiLine = "multi-line"
|
||||
otherVars = "Other"
|
||||
pageNumberDesc = "Current page number"
|
||||
pageVars = "Page Information"
|
||||
preview = "Preview:"
|
||||
selectTemplate = "Select a template..."
|
||||
stampTextDescription = "Use dynamic variables below. Use @@ for literal @. Use \\n for new lines."
|
||||
timeDesc = "Current time"
|
||||
totalPagesDesc = "Total number of pages"
|
||||
useTemplate = "Use Template"
|
||||
uuidDesc = "Short unique identifier (8 chars)"
|
||||
variablesHelp = "Click on any variable to insert it into your stamp text. Use @@ for literal @."
|
||||
yearMonthDayDesc = "Individual date parts"
|
||||
|
||||
[AddStampRequest.error]
|
||||
failed = "PDF にスタンプを追加中にエラーが発生しました。"
|
||||
@@ -3560,6 +3594,14 @@ failed = "PDF にスタンプを追加中にエラーが発生しました。"
|
||||
[AddStampRequest.results]
|
||||
title = "スタンプ結果"
|
||||
|
||||
[AddStampRequest.template]
|
||||
custom = "Custom"
|
||||
dateHeader = "Date Header"
|
||||
draftWatermark = "Draft Watermark"
|
||||
europeanDate = "European Date"
|
||||
pageNumberFooter = "Page Number Footer"
|
||||
timestamp = "Timestamp"
|
||||
|
||||
[removeImagePdf]
|
||||
tags = "画像削除,ページ操作,バックエンド,サーバー側"
|
||||
|
||||
@@ -4526,6 +4568,13 @@ description = "アカウントロックまでの最大失敗回数"
|
||||
label = "ログインリセット時間(分)"
|
||||
description = "失敗回数がリセットされるまでの時間"
|
||||
|
||||
[admin.settings.security.xFrameOptions]
|
||||
label = "X-Frame-Options"
|
||||
description = "Controls whether the application can be embedded in iframes"
|
||||
deny = "Deny (Prevents all framing)"
|
||||
sameorigin = "Same Origin (Allow framing from same domain)"
|
||||
disabled = "Disabled (No X-Frame-Options header)"
|
||||
|
||||
[admin.settings.security.csrfDisabled]
|
||||
label = "CSRF 保護を無効化"
|
||||
description = "クロスサイトリクエストフォージェリ保護を無効化(非推奨)"
|
||||
|
||||
@@ -439,7 +439,9 @@ fullscreen = "전체 화면"
|
||||
[settings.general.updates]
|
||||
title = "소프트웨어 업데이트"
|
||||
description = "업데이트 확인 및 버전 정보 보기"
|
||||
currentVersion = "현재 버전"
|
||||
currentBackendVersion = "Current Backend Version"
|
||||
currentFrontendVersion = "Current Frontend Version"
|
||||
versionMismatch = "Warning: A mismatch has been detected between the client version and the AppConfig version. Using different versions can lead to compatibility issues, errors, and security risks. Please ensure that server and client are using the same version."
|
||||
latestVersion = "최신 버전"
|
||||
checkForUpdates = "업데이트 확인"
|
||||
viewDetails = "자세히 보기"
|
||||
@@ -950,6 +952,7 @@ title = "크기/개수별 자동 분할"
|
||||
desc = "단일 PDF를 크기, 페이지 수 또는 문서 수를 기준으로 여러 문서로 분할"
|
||||
|
||||
[home.replaceColor]
|
||||
tags = "replace color,invert color,color replacement,swap colors,change color,invert,negative,color swap,find and replace color,convert color,color change"
|
||||
title = "색상 교체 및 반전"
|
||||
desc = "PDF 문서의 색상을 교체하거나 반전합니다."
|
||||
|
||||
@@ -964,18 +967,22 @@ title = "자동 폴더 스캔"
|
||||
desc = "자동 폴더 스캔 가이드로 이동"
|
||||
|
||||
[home.devSsoGuide]
|
||||
tags = "SSO,single sign-on,authentication,SAML,OAuth,OIDC,login,enterprise,identity provider,IdP"
|
||||
title = "SSO 가이드"
|
||||
desc = "SSO 가이드로 이동"
|
||||
|
||||
[home.devAirgapped]
|
||||
tags = "air-gapped,offline,isolated,no internet,disconnected,secure,network isolation,standalone"
|
||||
title = "격리 환경 설정"
|
||||
desc = "격리 환경 설정 가이드로 이동"
|
||||
|
||||
[home.addPassword]
|
||||
tags = "encrypt,password,lock,secure,protect,security,encryption,safeguard,confidential,private,restrict access"
|
||||
title = "비밀번호 추가"
|
||||
desc = "PDF 문서를 비밀번호로 암호화합니다."
|
||||
|
||||
[home.changePermissions]
|
||||
tags = "permissions,restrictions,rights,access control,allow,deny,printing,copying,editing,modify permissions,security settings,user rights"
|
||||
title = "권한 변경"
|
||||
desc = "문서 제한 및 권한 변경"
|
||||
|
||||
@@ -985,10 +992,12 @@ title = "자동화"
|
||||
desc = "PDF 작업을 연결하여 다단계 워크플로를 구성하세요. 반복 작업에 이상적입니다."
|
||||
|
||||
[home.overlay-pdfs]
|
||||
tags = "overlay,combine,merge,layer,superimpose,overlay PDF,layer PDFs,combine PDFs,stack,overlay pages,background,foreground,composite"
|
||||
desc = "PDF를 다른 PDF 위에 오버레이"
|
||||
title = "PDF 오버레이"
|
||||
|
||||
[home.pdfTextEditor]
|
||||
tags = "edit text,modify text,change text,edit content,update text,rewrite,correct,amend,redline,revise,text editor,content editor"
|
||||
title = "PDF 텍스트 편집기"
|
||||
desc = "그룹화된 텍스트 편집과 PDF 재생성으로 Stirling PDF의 JSON 내보내기를 검토하고 편집하세요"
|
||||
|
||||
@@ -3553,6 +3562,31 @@ imageSize = "이미지 크기"
|
||||
margin = "여백"
|
||||
positionAndFormatting = "위치 및 서식"
|
||||
quickPosition = "페이지에서 스탬프 위치를 선택하세요."
|
||||
clickToExpand = "Click to expand"
|
||||
customDateDesc = "Custom format"
|
||||
dateDesc = "Current date"
|
||||
dateTimeVars = "Date & Time"
|
||||
datetimeDesc = "Date and time combined"
|
||||
dynamicVariables = "Dynamic Variables"
|
||||
examples = "Examples"
|
||||
fileVars = "File Information"
|
||||
filenameDesc = "Filename without extension"
|
||||
filenameFullDesc = "Filename with extension"
|
||||
metadataDesc = "From PDF document properties"
|
||||
metadataVars = "Document Metadata"
|
||||
multiLine = "multi-line"
|
||||
otherVars = "Other"
|
||||
pageNumberDesc = "Current page number"
|
||||
pageVars = "Page Information"
|
||||
preview = "Preview:"
|
||||
selectTemplate = "Select a template..."
|
||||
stampTextDescription = "Use dynamic variables below. Use @@ for literal @. Use \\n for new lines."
|
||||
timeDesc = "Current time"
|
||||
totalPagesDesc = "Total number of pages"
|
||||
useTemplate = "Use Template"
|
||||
uuidDesc = "Short unique identifier (8 chars)"
|
||||
variablesHelp = "Click on any variable to insert it into your stamp text. Use @@ for literal @."
|
||||
yearMonthDayDesc = "Individual date parts"
|
||||
|
||||
[AddStampRequest.error]
|
||||
failed = "PDF에 스탬프를 추가하는 중 오류가 발생했습니다."
|
||||
@@ -3560,6 +3594,14 @@ failed = "PDF에 스탬프를 추가하는 중 오류가 발생했습니다."
|
||||
[AddStampRequest.results]
|
||||
title = "스탬프 결과"
|
||||
|
||||
[AddStampRequest.template]
|
||||
custom = "Custom"
|
||||
dateHeader = "Date Header"
|
||||
draftWatermark = "Draft Watermark"
|
||||
europeanDate = "European Date"
|
||||
pageNumberFooter = "Page Number Footer"
|
||||
timestamp = "Timestamp"
|
||||
|
||||
[removeImagePdf]
|
||||
tags = "이미지 제거,페이지 작업,백엔드,서버 사이드"
|
||||
|
||||
@@ -4526,6 +4568,13 @@ description = "계정 잠금 전 허용되는 최대 로그인 실패 횟수"
|
||||
label = "로그인 재설정 시간(분)"
|
||||
description = "로그인 실패 횟수가 재설정되기까지의 시간"
|
||||
|
||||
[admin.settings.security.xFrameOptions]
|
||||
label = "X-Frame-Options"
|
||||
description = "Controls whether the application can be embedded in iframes"
|
||||
deny = "Deny (Prevents all framing)"
|
||||
sameorigin = "Same Origin (Allow framing from same domain)"
|
||||
disabled = "Disabled (No X-Frame-Options header)"
|
||||
|
||||
[admin.settings.security.csrfDisabled]
|
||||
label = "CSRF 보호 비활성화"
|
||||
description = "교차 사이트 요청 위조 보호를 비활성화합니다(권장하지 않음)"
|
||||
|
||||
@@ -439,7 +439,9 @@ fullscreen = "ഫുൾസ്ക്രീൻ"
|
||||
[settings.general.updates]
|
||||
title = "സോഫ്റ്റ്വെയർ അപ്ഡേറ്റുകൾ"
|
||||
description = "അപ്ഡേറ്റുകൾ പരിശോധിക്കുകയും പതിപ്പിന്റെ വിവരങ്ങൾ കാണുകയും ചെയ്യുക"
|
||||
currentVersion = "ഇപ്പോഴത്തെ പതിപ്പ്"
|
||||
currentBackendVersion = "Current Backend Version"
|
||||
currentFrontendVersion = "Current Frontend Version"
|
||||
versionMismatch = "Warning: A mismatch has been detected between the client version and the AppConfig version. Using different versions can lead to compatibility issues, errors, and security risks. Please ensure that server and client are using the same version."
|
||||
latestVersion = "പുതിയ പതിപ്പ്"
|
||||
checkForUpdates = "അപ്ഡേറ്റുകൾ പരിശോധിക്കുക"
|
||||
viewDetails = "വിശദാംശങ്ങൾ കാണുക"
|
||||
@@ -950,6 +952,7 @@ title = "സൈസ്/കൗണ്ട് ഓട്ടോ സ്പ്ലിറ
|
||||
desc = "ഫയൽ വലുപ്പം അല്ലെങ്കിൽ പേജ് എണ്ണം പ്രകാരം PDF-കൾ സ്വയം വിഭജിക്കുക"
|
||||
|
||||
[home.replaceColor]
|
||||
tags = "replace color,invert color,color replacement,swap colors,change color,invert,negative,color swap,find and replace color,convert color,color change"
|
||||
title = "നിറം മാറ്റുക / ഇൻവേർട്ട്"
|
||||
desc = "PDF ഡോക്യുമെന്റുകളിൽ നിറങ്ങൾ പകരംവെക്കുകയോ ഇൻവേർട്ട് ചെയ്യുകയോ ചെയ്യുക"
|
||||
|
||||
@@ -964,18 +967,22 @@ title = "ഓട്ടോമേറ്റഡ് ഫോൾഡർ സ്കാനി
|
||||
desc = "ഓട്ടോമേറ്റഡ് ഫോൾഡർ സ്കാനിംഗ് ഗൈഡിലേക്കുള്ള ലിങ്ക്"
|
||||
|
||||
[home.devSsoGuide]
|
||||
tags = "SSO,single sign-on,authentication,SAML,OAuth,OIDC,login,enterprise,identity provider,IdP"
|
||||
title = "SSO ഗൈഡ്"
|
||||
desc = "SSO ഗൈഡിലേക്കുള്ള ലിങ്ക്"
|
||||
|
||||
[home.devAirgapped]
|
||||
tags = "air-gapped,offline,isolated,no internet,disconnected,secure,network isolation,standalone"
|
||||
title = "Air-gapped സെറ്റപ്പ്"
|
||||
desc = "എയർ-ഗ്യാപ്ഡ് സെറ്റപ്പ് ഗൈഡിലേക്കുള്ള ലിങ്ക്"
|
||||
|
||||
[home.addPassword]
|
||||
tags = "encrypt,password,lock,secure,protect,security,encryption,safeguard,confidential,private,restrict access"
|
||||
title = "പാസ്വേഡ് ചേർക്കുക"
|
||||
desc = "നിങ്ങളുടെ PDF പ്രമാണം ഒരു പാസ്വേഡ് ഉപയോഗിച്ച് എൻക്രിപ്റ്റ് ചെയ്യുക."
|
||||
|
||||
[home.changePermissions]
|
||||
tags = "permissions,restrictions,rights,access control,allow,deny,printing,copying,editing,modify permissions,security settings,user rights"
|
||||
title = "അനുമതികൾ മാറ്റുക"
|
||||
desc = "ഡോക്യുമെന്റ് നിയന്ത്രണങ്ങളും അനുമതികളും മാറ്റുക"
|
||||
|
||||
@@ -985,10 +992,12 @@ title = "ഓട്ടോമേറ്റ്"
|
||||
desc = "PDF പ്രവർത്തനങ്ങൾ ബന്ധിപ്പിച്ച് മൾട്ടി-സ്റ്റെപ്പ് വർക്ഫ്ലോകൾ നിർമ്മിക്കുക. ആവർത്തിക്കുന്ന ജോലികൾക്ക് അനുയോജ്യം."
|
||||
|
||||
[home.overlay-pdfs]
|
||||
tags = "overlay,combine,merge,layer,superimpose,overlay PDF,layer PDFs,combine PDFs,stack,overlay pages,background,foreground,composite"
|
||||
desc = "മറ്റൊരു PDF-ന് മുകളിൽ PDF-കൾ ഓവർലേ ചെയ്യുന്നു"
|
||||
title = "PDF-കൾ ഓവർലേ ചെയ്യുക"
|
||||
|
||||
[home.pdfTextEditor]
|
||||
tags = "edit text,modify text,change text,edit content,update text,rewrite,correct,amend,redline,revise,text editor,content editor"
|
||||
title = "PDF ടെക്സ്റ്റ് എഡിറ്റർ"
|
||||
desc = "ഗ്രൂപ്പുചെയ്ത ടെക്സ്റ്റ് എഡിറ്റിംഗിനോടും PDF വീണ്ടും സൃഷ്ടിക്കുന്നതോടും കൂടി Stirling PDF JSON എക്സ്പോർട്ടുകൾ റിവ്യൂ ചെയ്ത് എഡിറ്റ് ചെയ്യുക"
|
||||
|
||||
@@ -3553,6 +3562,31 @@ imageSize = "ഇമേജ് വലിപ്പം"
|
||||
margin = "മാർജിൻ"
|
||||
positionAndFormatting = "സ്ഥാനം & ഫോർമാറ്റിംഗ്"
|
||||
quickPosition = "സ്റ്റാമ്പ് വയ്ക്കാൻ പേജിലെ ഒരു സ്ഥാനം തിരഞ്ഞെടുക്കുക."
|
||||
clickToExpand = "Click to expand"
|
||||
customDateDesc = "Custom format"
|
||||
dateDesc = "Current date"
|
||||
dateTimeVars = "Date & Time"
|
||||
datetimeDesc = "Date and time combined"
|
||||
dynamicVariables = "Dynamic Variables"
|
||||
examples = "Examples"
|
||||
fileVars = "File Information"
|
||||
filenameDesc = "Filename without extension"
|
||||
filenameFullDesc = "Filename with extension"
|
||||
metadataDesc = "From PDF document properties"
|
||||
metadataVars = "Document Metadata"
|
||||
multiLine = "multi-line"
|
||||
otherVars = "Other"
|
||||
pageNumberDesc = "Current page number"
|
||||
pageVars = "Page Information"
|
||||
preview = "Preview:"
|
||||
selectTemplate = "Select a template..."
|
||||
stampTextDescription = "Use dynamic variables below. Use @@ for literal @. Use \\n for new lines."
|
||||
timeDesc = "Current time"
|
||||
totalPagesDesc = "Total number of pages"
|
||||
useTemplate = "Use Template"
|
||||
uuidDesc = "Short unique identifier (8 chars)"
|
||||
variablesHelp = "Click on any variable to insert it into your stamp text. Use @@ for literal @."
|
||||
yearMonthDayDesc = "Individual date parts"
|
||||
|
||||
[AddStampRequest.error]
|
||||
failed = "PDF-ലേക്ക് സ്റ്റാമ്പ് ചേർക്കുന്നതിനിടെ പിശക് സംഭവിച്ചു."
|
||||
@@ -3560,6 +3594,14 @@ failed = "PDF-ലേക്ക് സ്റ്റാമ്പ് ചേർക്
|
||||
[AddStampRequest.results]
|
||||
title = "സ്റ്റാമ്പ് ഫലങ്ങൾ"
|
||||
|
||||
[AddStampRequest.template]
|
||||
custom = "Custom"
|
||||
dateHeader = "Date Header"
|
||||
draftWatermark = "Draft Watermark"
|
||||
europeanDate = "European Date"
|
||||
pageNumberFooter = "Page Number Footer"
|
||||
timestamp = "Timestamp"
|
||||
|
||||
[removeImagePdf]
|
||||
tags = "ചിത്രം നീക്കം ചെയ്യുക,പേജ് പ്രവർത്തനങ്ങൾ,ബാക്ക് എൻഡ്,സെർവർ സൈഡ്"
|
||||
|
||||
@@ -4526,6 +4568,13 @@ description = "അക്കൗണ്ട് ലോക്കാകുന്നത
|
||||
label = "ലോഗിൻ റീസെറ്റ് സമയം (മിനിറ്റ്)"
|
||||
description = "പരാജയപ്പെട്ട ലോഗിൻ ശ്രമങ്ങൾ റീസെറ്റ് ചെയ്യുന്നതിന് മുമ്പുള്ള സമയം"
|
||||
|
||||
[admin.settings.security.xFrameOptions]
|
||||
label = "X-Frame-Options"
|
||||
description = "Controls whether the application can be embedded in iframes"
|
||||
deny = "Deny (Prevents all framing)"
|
||||
sameorigin = "Same Origin (Allow framing from same domain)"
|
||||
disabled = "Disabled (No X-Frame-Options header)"
|
||||
|
||||
[admin.settings.security.csrfDisabled]
|
||||
label = "CSRF സംരക്ഷണം അപ്രാപ്തമാക്കുക"
|
||||
description = "Cross-Site Request Forgery സംരക്ഷണം അപ്രാപ്തമാക്കുക (ശുപാർശ ചെയ്യുന്നതല്ല)"
|
||||
|
||||
@@ -439,7 +439,9 @@ fullscreen = "Volledig scherm"
|
||||
[settings.general.updates]
|
||||
title = "Software-updates"
|
||||
description = "Controleer op updates en bekijk versie-informatie"
|
||||
currentVersion = "Huidige versie"
|
||||
currentBackendVersion = "Current Backend Version"
|
||||
currentFrontendVersion = "Current Frontend Version"
|
||||
versionMismatch = "Warning: A mismatch has been detected between the client version and the AppConfig version. Using different versions can lead to compatibility issues, errors, and security risks. Please ensure that server and client are using the same version."
|
||||
latestVersion = "Laatste versie"
|
||||
checkForUpdates = "Op updates controleren"
|
||||
viewDetails = "Details bekijken"
|
||||
@@ -950,6 +952,7 @@ title = "Automatisch splitsen op grootte/aantal"
|
||||
desc = "Splits een enkele PDF in meerdere documenten op basis van grootte, aantal pagina's of aantal documenten"
|
||||
|
||||
[home.replaceColor]
|
||||
tags = "replace color,invert color,color replacement,swap colors,change color,invert,negative,color swap,find and replace color,convert color,color change"
|
||||
title = "Kleur vervangen en inverteren"
|
||||
desc = "Kleuren in PDF-documenten vervangen of inverteren"
|
||||
|
||||
@@ -964,18 +967,22 @@ title = "Geautomatiseerd mappenscannen"
|
||||
desc = "Link naar handleiding voor geautomatiseerd mappenscannen"
|
||||
|
||||
[home.devSsoGuide]
|
||||
tags = "SSO,single sign-on,authentication,SAML,OAuth,OIDC,login,enterprise,identity provider,IdP"
|
||||
title = "SSO-gids"
|
||||
desc = "Link naar SSO-gids"
|
||||
|
||||
[home.devAirgapped]
|
||||
tags = "air-gapped,offline,isolated,no internet,disconnected,secure,network isolation,standalone"
|
||||
title = "Air-gapped-installatie"
|
||||
desc = "Link naar handleiding voor air-gapped-installatie"
|
||||
|
||||
[home.addPassword]
|
||||
tags = "encrypt,password,lock,secure,protect,security,encryption,safeguard,confidential,private,restrict access"
|
||||
title = "Wachtwoord toevoegen"
|
||||
desc = "Versleutel uw PDF-document met een wachtwoord."
|
||||
|
||||
[home.changePermissions]
|
||||
tags = "permissions,restrictions,rights,access control,allow,deny,printing,copying,editing,modify permissions,security settings,user rights"
|
||||
title = "Rechten wijzigen"
|
||||
desc = "Documentbeperkingen en machtigingen wijzigen"
|
||||
|
||||
@@ -985,10 +992,12 @@ title = "Automatiseren"
|
||||
desc = "Bouw workflows met meerdere stappen door PDF-acties te koppelen. Ideaal voor terugkerende taken."
|
||||
|
||||
[home.overlay-pdfs]
|
||||
tags = "overlay,combine,merge,layer,superimpose,overlay PDF,layer PDFs,combine PDFs,stack,overlay pages,background,foreground,composite"
|
||||
desc = "Plaatst PDF's over een andere PDF heen"
|
||||
title = "PDF's overlappen"
|
||||
|
||||
[home.pdfTextEditor]
|
||||
tags = "edit text,modify text,change text,edit content,update text,rewrite,correct,amend,redline,revise,text editor,content editor"
|
||||
title = "PDF-teksteditor"
|
||||
desc = "Bewerk bestaande tekst en afbeeldingen in PDF's"
|
||||
|
||||
@@ -3553,6 +3562,31 @@ imageSize = "Afbeeldingsgrootte"
|
||||
margin = "Marge"
|
||||
positionAndFormatting = "Positie & opmaak"
|
||||
quickPosition = "Selecteer een positie op de pagina om de stempel te plaatsen."
|
||||
clickToExpand = "Click to expand"
|
||||
customDateDesc = "Custom format"
|
||||
dateDesc = "Current date"
|
||||
dateTimeVars = "Date & Time"
|
||||
datetimeDesc = "Date and time combined"
|
||||
dynamicVariables = "Dynamic Variables"
|
||||
examples = "Examples"
|
||||
fileVars = "File Information"
|
||||
filenameDesc = "Filename without extension"
|
||||
filenameFullDesc = "Filename with extension"
|
||||
metadataDesc = "From PDF document properties"
|
||||
metadataVars = "Document Metadata"
|
||||
multiLine = "multi-line"
|
||||
otherVars = "Other"
|
||||
pageNumberDesc = "Current page number"
|
||||
pageVars = "Page Information"
|
||||
preview = "Preview:"
|
||||
selectTemplate = "Select a template..."
|
||||
stampTextDescription = "Use dynamic variables below. Use @@ for literal @. Use \\n for new lines."
|
||||
timeDesc = "Current time"
|
||||
totalPagesDesc = "Total number of pages"
|
||||
useTemplate = "Use Template"
|
||||
uuidDesc = "Short unique identifier (8 chars)"
|
||||
variablesHelp = "Click on any variable to insert it into your stamp text. Use @@ for literal @."
|
||||
yearMonthDayDesc = "Individual date parts"
|
||||
|
||||
[AddStampRequest.error]
|
||||
failed = "Er is een fout opgetreden bij het toevoegen van een stempel aan de PDF."
|
||||
@@ -3560,6 +3594,14 @@ failed = "Er is een fout opgetreden bij het toevoegen van een stempel aan de PDF
|
||||
[AddStampRequest.results]
|
||||
title = "Stempelresultaten"
|
||||
|
||||
[AddStampRequest.template]
|
||||
custom = "Custom"
|
||||
dateHeader = "Date Header"
|
||||
draftWatermark = "Draft Watermark"
|
||||
europeanDate = "European Date"
|
||||
pageNumberFooter = "Page Number Footer"
|
||||
timestamp = "Timestamp"
|
||||
|
||||
[removeImagePdf]
|
||||
tags = "Afbeelding verwijderen, Paginabewerkingen, Achterkant, Serverkant"
|
||||
|
||||
@@ -4526,6 +4568,13 @@ description = "Maximaal aantal mislukte inlogpogingen voordat het account wordt
|
||||
label = "Resetperiode voor inloggen (minuten)"
|
||||
description = "Tijd voordat mislukte inlogpogingen worden gereset"
|
||||
|
||||
[admin.settings.security.xFrameOptions]
|
||||
label = "X-Frame-Options"
|
||||
description = "Controls whether the application can be embedded in iframes"
|
||||
deny = "Deny (Prevents all framing)"
|
||||
sameorigin = "Same Origin (Allow framing from same domain)"
|
||||
disabled = "Disabled (No X-Frame-Options header)"
|
||||
|
||||
[admin.settings.security.csrfDisabled]
|
||||
label = "CSRF-bescherming uitschakelen"
|
||||
description = "Cross-Site Request Forgery-bescherming uitschakelen (niet aanbevolen)"
|
||||
|
||||
@@ -439,7 +439,9 @@ fullscreen = "Fullskjerm"
|
||||
[settings.general.updates]
|
||||
title = "Programvareoppdateringer"
|
||||
description = "Se etter oppdateringer og vis versjonsinformasjon"
|
||||
currentVersion = "Nåværende versjon"
|
||||
currentBackendVersion = "Current Backend Version"
|
||||
currentFrontendVersion = "Current Frontend Version"
|
||||
versionMismatch = "Warning: A mismatch has been detected between the client version and the AppConfig version. Using different versions can lead to compatibility issues, errors, and security risks. Please ensure that server and client are using the same version."
|
||||
latestVersion = "Siste versjon"
|
||||
checkForUpdates = "Søk etter oppdateringer"
|
||||
viewDetails = "Vis detaljer"
|
||||
@@ -950,6 +952,7 @@ title = "Auto-del størrelse/antall"
|
||||
desc = "Del en enkelt PDF i flere dokumenter basert på størrelse, antall sider eller dokumenter"
|
||||
|
||||
[home.replaceColor]
|
||||
tags = "replace color,invert color,color replacement,swap colors,change color,invert,negative,color swap,find and replace color,convert color,color change"
|
||||
title = "Erstatt og inverter farger"
|
||||
desc = "Erstatt eller inverter farger i PDF-dokumenter"
|
||||
|
||||
@@ -964,18 +967,22 @@ title = "Automatisert mappeskanning"
|
||||
desc = "Lenke til veiledning for automatisert mappeskanning"
|
||||
|
||||
[home.devSsoGuide]
|
||||
tags = "SSO,single sign-on,authentication,SAML,OAuth,OIDC,login,enterprise,identity provider,IdP"
|
||||
title = "SSO-veiledning"
|
||||
desc = "Lenke til SSO-veiledning"
|
||||
|
||||
[home.devAirgapped]
|
||||
tags = "air-gapped,offline,isolated,no internet,disconnected,secure,network isolation,standalone"
|
||||
title = "Luftgap-oppsett"
|
||||
desc = "Lenke til veiledning for luftgap-oppsett"
|
||||
|
||||
[home.addPassword]
|
||||
tags = "encrypt,password,lock,secure,protect,security,encryption,safeguard,confidential,private,restrict access"
|
||||
title = "Legg til Passord"
|
||||
desc = "Krypter din PDF-dokument med et passord."
|
||||
|
||||
[home.changePermissions]
|
||||
tags = "permissions,restrictions,rights,access control,allow,deny,printing,copying,editing,modify permissions,security settings,user rights"
|
||||
title = "Endre tillatelser"
|
||||
desc = "Endre dokumentbegrensninger og tillatelser"
|
||||
|
||||
@@ -985,10 +992,12 @@ title = "Automatiser"
|
||||
desc = "Bygg flertrinns arbeidsflyter ved å lenke sammen PDF-handlinger. Ideelt for gjentakende oppgaver."
|
||||
|
||||
[home.overlay-pdfs]
|
||||
tags = "overlay,combine,merge,layer,superimpose,overlay PDF,layer PDFs,combine PDFs,stack,overlay pages,background,foreground,composite"
|
||||
desc = "Legger PDF-er over hverandre"
|
||||
title = "Overlay PDF-er"
|
||||
|
||||
[home.pdfTextEditor]
|
||||
tags = "edit text,modify text,change text,edit content,update text,rewrite,correct,amend,redline,revise,text editor,content editor"
|
||||
title = "PDF-tekstredigerer"
|
||||
desc = "Gå gjennom og rediger Stirling PDF JSON-eksporter med gruppert tekstredigering og regenerering av PDF"
|
||||
|
||||
@@ -3553,6 +3562,31 @@ imageSize = "Bildestørrelse"
|
||||
margin = "Marg"
|
||||
positionAndFormatting = "Plassering og formatering"
|
||||
quickPosition = "Velg en posisjon på siden for å plassere stempelet."
|
||||
clickToExpand = "Click to expand"
|
||||
customDateDesc = "Custom format"
|
||||
dateDesc = "Current date"
|
||||
dateTimeVars = "Date & Time"
|
||||
datetimeDesc = "Date and time combined"
|
||||
dynamicVariables = "Dynamic Variables"
|
||||
examples = "Examples"
|
||||
fileVars = "File Information"
|
||||
filenameDesc = "Filename without extension"
|
||||
filenameFullDesc = "Filename with extension"
|
||||
metadataDesc = "From PDF document properties"
|
||||
metadataVars = "Document Metadata"
|
||||
multiLine = "multi-line"
|
||||
otherVars = "Other"
|
||||
pageNumberDesc = "Current page number"
|
||||
pageVars = "Page Information"
|
||||
preview = "Preview:"
|
||||
selectTemplate = "Select a template..."
|
||||
stampTextDescription = "Use dynamic variables below. Use @@ for literal @. Use \\n for new lines."
|
||||
timeDesc = "Current time"
|
||||
totalPagesDesc = "Total number of pages"
|
||||
useTemplate = "Use Template"
|
||||
uuidDesc = "Short unique identifier (8 chars)"
|
||||
variablesHelp = "Click on any variable to insert it into your stamp text. Use @@ for literal @."
|
||||
yearMonthDayDesc = "Individual date parts"
|
||||
|
||||
[AddStampRequest.error]
|
||||
failed = "Det oppstod en feil under tillegg av stempel til PDF-en."
|
||||
@@ -3560,6 +3594,14 @@ failed = "Det oppstod en feil under tillegg av stempel til PDF-en."
|
||||
[AddStampRequest.results]
|
||||
title = "Stempelresultater"
|
||||
|
||||
[AddStampRequest.template]
|
||||
custom = "Custom"
|
||||
dateHeader = "Date Header"
|
||||
draftWatermark = "Draft Watermark"
|
||||
europeanDate = "European Date"
|
||||
pageNumberFooter = "Page Number Footer"
|
||||
timestamp = "Timestamp"
|
||||
|
||||
[removeImagePdf]
|
||||
tags = "Fjern Bilde,Sideoperasjoner,Backend,serverside"
|
||||
|
||||
@@ -4526,6 +4568,13 @@ description = "Maksimalt antall mislykkede innloggingsforsøk før kontolåsing"
|
||||
label = "Tilbakestillingstid for innlogging (minutter)"
|
||||
description = "Tid før mislykkede innloggingsforsøk nullstilles"
|
||||
|
||||
[admin.settings.security.xFrameOptions]
|
||||
label = "X-Frame-Options"
|
||||
description = "Controls whether the application can be embedded in iframes"
|
||||
deny = "Deny (Prevents all framing)"
|
||||
sameorigin = "Same Origin (Allow framing from same domain)"
|
||||
disabled = "Disabled (No X-Frame-Options header)"
|
||||
|
||||
[admin.settings.security.csrfDisabled]
|
||||
label = "Deaktiver CSRF-beskyttelse"
|
||||
description = "Deaktiver Cross-Site Request Forgery-beskyttelse (anbefales ikke)"
|
||||
|
||||
@@ -439,7 +439,9 @@ fullscreen = "Pełny ekran"
|
||||
[settings.general.updates]
|
||||
title = "Aktualizacje oprogramowania"
|
||||
description = "Sprawdź aktualizacje i informacje o wersji"
|
||||
currentVersion = "Bieżąca wersja"
|
||||
currentBackendVersion = "Current Backend Version"
|
||||
currentFrontendVersion = "Current Frontend Version"
|
||||
versionMismatch = "Warning: A mismatch has been detected between the client version and the AppConfig version. Using different versions can lead to compatibility issues, errors, and security risks. Please ensure that server and client are using the same version."
|
||||
latestVersion = "Najnowsza wersja"
|
||||
checkForUpdates = "Sprawdź aktualizacje"
|
||||
viewDetails = "Pokaż szczegóły"
|
||||
@@ -950,6 +952,7 @@ title = "Podziel (Rozmiar/Ilość stron)"
|
||||
desc = "Rozdziela dokument PDF na wiele dokumentów bazując na podanym rozmiarze, ilości stron bądź ilości dokumentów"
|
||||
|
||||
[home.replaceColor]
|
||||
tags = "replace color,invert color,color replacement,swap colors,change color,invert,negative,color swap,find and replace color,convert color,color change"
|
||||
title = "Zastąp i odwróć kolor"
|
||||
desc = "Zastępuj lub odwracaj kolory w dokumentach PDF"
|
||||
|
||||
@@ -964,18 +967,22 @@ title = "Auto skan folderów"
|
||||
desc = "Link do przewodnika automatycznego skanowania folderów"
|
||||
|
||||
[home.devSsoGuide]
|
||||
tags = "SSO,single sign-on,authentication,SAML,OAuth,OIDC,login,enterprise,identity provider,IdP"
|
||||
title = "Przewodnik SSO"
|
||||
desc = "Link do przewodnika SSO"
|
||||
|
||||
[home.devAirgapped]
|
||||
tags = "air-gapped,offline,isolated,no internet,disconnected,secure,network isolation,standalone"
|
||||
title = "Konfiguracja odizolowana"
|
||||
desc = "Link do przewodnika konfiguracji odizolowanej"
|
||||
|
||||
[home.addPassword]
|
||||
tags = "encrypt,password,lock,secure,protect,security,encryption,safeguard,confidential,private,restrict access"
|
||||
title = "Dodaj hasło"
|
||||
desc = "Zaszyfruj dokument PDF za pomocą hasła."
|
||||
|
||||
[home.changePermissions]
|
||||
tags = "permissions,restrictions,rights,access control,allow,deny,printing,copying,editing,modify permissions,security settings,user rights"
|
||||
title = "Zmień uprawnienia"
|
||||
desc = "Zmień ograniczenia i uprawnienia dokumentu"
|
||||
|
||||
@@ -985,10 +992,12 @@ title = "Automatyzuj"
|
||||
desc = "Buduj wieloetapowe przepływy, łącząc akcje PDF. Idealne do powtarzających się zadań."
|
||||
|
||||
[home.overlay-pdfs]
|
||||
tags = "overlay,combine,merge,layer,superimpose,overlay PDF,layer PDFs,combine PDFs,stack,overlay pages,background,foreground,composite"
|
||||
desc = "Nakłada dokumenty PDF na siebie"
|
||||
title = "Nałóż PDFa"
|
||||
|
||||
[home.pdfTextEditor]
|
||||
tags = "edit text,modify text,change text,edit content,update text,rewrite,correct,amend,redline,revise,text editor,content editor"
|
||||
title = "Edytor tekstu PDF"
|
||||
desc = "Przeglądaj i edytuj eksporty JSON z Stirling PDF z grupową edycją tekstu i ponowną generacją PDF"
|
||||
|
||||
@@ -3553,6 +3562,31 @@ imageSize = "Rozmiar obrazu"
|
||||
margin = "Margines"
|
||||
positionAndFormatting = "Pozycja i formatowanie"
|
||||
quickPosition = "Wybierz pozycję na stronie, aby umieścić stempel."
|
||||
clickToExpand = "Click to expand"
|
||||
customDateDesc = "Custom format"
|
||||
dateDesc = "Current date"
|
||||
dateTimeVars = "Date & Time"
|
||||
datetimeDesc = "Date and time combined"
|
||||
dynamicVariables = "Dynamic Variables"
|
||||
examples = "Examples"
|
||||
fileVars = "File Information"
|
||||
filenameDesc = "Filename without extension"
|
||||
filenameFullDesc = "Filename with extension"
|
||||
metadataDesc = "From PDF document properties"
|
||||
metadataVars = "Document Metadata"
|
||||
multiLine = "multi-line"
|
||||
otherVars = "Other"
|
||||
pageNumberDesc = "Current page number"
|
||||
pageVars = "Page Information"
|
||||
preview = "Preview:"
|
||||
selectTemplate = "Select a template..."
|
||||
stampTextDescription = "Use dynamic variables below. Use @@ for literal @. Use \\n for new lines."
|
||||
timeDesc = "Current time"
|
||||
totalPagesDesc = "Total number of pages"
|
||||
useTemplate = "Use Template"
|
||||
uuidDesc = "Short unique identifier (8 chars)"
|
||||
variablesHelp = "Click on any variable to insert it into your stamp text. Use @@ for literal @."
|
||||
yearMonthDayDesc = "Individual date parts"
|
||||
|
||||
[AddStampRequest.error]
|
||||
failed = "Wystąpił błąd podczas dodawania stempla do PDF."
|
||||
@@ -3560,6 +3594,14 @@ failed = "Wystąpił błąd podczas dodawania stempla do PDF."
|
||||
[AddStampRequest.results]
|
||||
title = "Wyniki dodawania stempla"
|
||||
|
||||
[AddStampRequest.template]
|
||||
custom = "Custom"
|
||||
dateHeader = "Date Header"
|
||||
draftWatermark = "Draft Watermark"
|
||||
europeanDate = "European Date"
|
||||
pageNumberFooter = "Page Number Footer"
|
||||
timestamp = "Timestamp"
|
||||
|
||||
[removeImagePdf]
|
||||
tags = "Usuń obraz, operacje na stronie, back-end, strona serwera"
|
||||
|
||||
@@ -4526,6 +4568,13 @@ description = "Maksymalna liczba nieudanych prób logowania przed zablokowaniem
|
||||
label = "Czas resetu prób logowania (minuty)"
|
||||
description = "Czas, po którym licznik nieudanych prób logowania jest resetowany"
|
||||
|
||||
[admin.settings.security.xFrameOptions]
|
||||
label = "X-Frame-Options"
|
||||
description = "Controls whether the application can be embedded in iframes"
|
||||
deny = "Deny (Prevents all framing)"
|
||||
sameorigin = "Same Origin (Allow framing from same domain)"
|
||||
disabled = "Disabled (No X-Frame-Options header)"
|
||||
|
||||
[admin.settings.security.csrfDisabled]
|
||||
label = "Wyłącz ochronę CSRF"
|
||||
description = "Wyłącz ochronę przed Cross-Site Request Forgery (niezalecane)"
|
||||
|
||||
@@ -439,7 +439,9 @@ fullscreen = "Tela cheia"
|
||||
[settings.general.updates]
|
||||
title = "Atualizações de software"
|
||||
description = "Verifique atualizações e veja informações da versão"
|
||||
currentVersion = "Versão atual"
|
||||
currentBackendVersion = "Current Backend Version"
|
||||
currentFrontendVersion = "Current Frontend Version"
|
||||
versionMismatch = "Warning: A mismatch has been detected between the client version and the AppConfig version. Using different versions can lead to compatibility issues, errors, and security risks. Please ensure that server and client are using the same version."
|
||||
latestVersion = "Última versão"
|
||||
checkForUpdates = "Verificar atualizações"
|
||||
viewDetails = "Ver detalhes"
|
||||
@@ -950,6 +952,7 @@ title = "Divisão Manual do PDF"
|
||||
desc = "Divida um PDF em vários, com base no tamanho, contagem de páginas ou contagem de documentos."
|
||||
|
||||
[home.replaceColor]
|
||||
tags = "replace color,invert color,color replacement,swap colors,change color,invert,negative,color swap,find and replace color,convert color,color change"
|
||||
title = "Substituir e inverter cor"
|
||||
desc = "Substituir ou inverter cores em documentos PDF"
|
||||
|
||||
@@ -964,18 +967,22 @@ title = "Varredura automática de pasta"
|
||||
desc = "Link para o guia de varredura automática de pastas"
|
||||
|
||||
[home.devSsoGuide]
|
||||
tags = "SSO,single sign-on,authentication,SAML,OAuth,OIDC,login,enterprise,identity provider,IdP"
|
||||
title = "Guia de SSO"
|
||||
desc = "Link para o guia de SSO"
|
||||
|
||||
[home.devAirgapped]
|
||||
tags = "air-gapped,offline,isolated,no internet,disconnected,secure,network isolation,standalone"
|
||||
title = "Configuração Air-gapped"
|
||||
desc = "Link para o guia de configuração isolada (air-gapped)"
|
||||
|
||||
[home.addPassword]
|
||||
tags = "encrypt,password,lock,secure,protect,security,encryption,safeguard,confidential,private,restrict access"
|
||||
title = "Proteger PDF"
|
||||
desc = "Criptografar seu PDF com uma senha podendo realizar alterações de permissões."
|
||||
|
||||
[home.changePermissions]
|
||||
tags = "permissions,restrictions,rights,access control,allow,deny,printing,copying,editing,modify permissions,security settings,user rights"
|
||||
title = "Alterar Permissões"
|
||||
desc = "Alterar restrições e permissões do documento"
|
||||
|
||||
@@ -985,10 +992,12 @@ title = "Automatizar"
|
||||
desc = "Crie fluxos de trabalho de várias etapas encadeando ações de PDF. Ideal para tarefas recorrentes."
|
||||
|
||||
[home.overlay-pdfs]
|
||||
tags = "overlay,combine,merge,layer,superimpose,overlay PDF,layer PDFs,combine PDFs,stack,overlay pages,background,foreground,composite"
|
||||
desc = "Sobrepor um PDF sobre outro"
|
||||
title = "Sobrepor PDFs"
|
||||
|
||||
[home.pdfTextEditor]
|
||||
tags = "edit text,modify text,change text,edit content,update text,rewrite,correct,amend,redline,revise,text editor,content editor"
|
||||
title = "Editor de texto de PDF"
|
||||
desc = "Revise e edite exportações JSON do Stirling PDF com edição de texto agrupada e regeneração do PDF"
|
||||
|
||||
@@ -3553,6 +3562,31 @@ imageSize = "Tamanho da imagem"
|
||||
margin = "Margem"
|
||||
positionAndFormatting = "Posição e formatação"
|
||||
quickPosition = "Selecione uma posição na página para colocar o carimbo."
|
||||
clickToExpand = "Click to expand"
|
||||
customDateDesc = "Custom format"
|
||||
dateDesc = "Current date"
|
||||
dateTimeVars = "Date & Time"
|
||||
datetimeDesc = "Date and time combined"
|
||||
dynamicVariables = "Dynamic Variables"
|
||||
examples = "Examples"
|
||||
fileVars = "File Information"
|
||||
filenameDesc = "Filename without extension"
|
||||
filenameFullDesc = "Filename with extension"
|
||||
metadataDesc = "From PDF document properties"
|
||||
metadataVars = "Document Metadata"
|
||||
multiLine = "multi-line"
|
||||
otherVars = "Other"
|
||||
pageNumberDesc = "Current page number"
|
||||
pageVars = "Page Information"
|
||||
preview = "Preview:"
|
||||
selectTemplate = "Select a template..."
|
||||
stampTextDescription = "Use dynamic variables below. Use @@ for literal @. Use \\n for new lines."
|
||||
timeDesc = "Current time"
|
||||
totalPagesDesc = "Total number of pages"
|
||||
useTemplate = "Use Template"
|
||||
uuidDesc = "Short unique identifier (8 chars)"
|
||||
variablesHelp = "Click on any variable to insert it into your stamp text. Use @@ for literal @."
|
||||
yearMonthDayDesc = "Individual date parts"
|
||||
|
||||
[AddStampRequest.error]
|
||||
failed = "Ocorreu um erro ao adicionar o carimbo ao PDF."
|
||||
@@ -3560,6 +3594,14 @@ failed = "Ocorreu um erro ao adicionar o carimbo ao PDF."
|
||||
[AddStampRequest.results]
|
||||
title = "Resultados do carimbo"
|
||||
|
||||
[AddStampRequest.template]
|
||||
custom = "Custom"
|
||||
dateHeader = "Date Header"
|
||||
draftWatermark = "Draft Watermark"
|
||||
europeanDate = "European Date"
|
||||
pageNumberFooter = "Page Number Footer"
|
||||
timestamp = "Timestamp"
|
||||
|
||||
[removeImagePdf]
|
||||
tags = "Remover imagem,operações de página,back-end,lado do servidor"
|
||||
|
||||
@@ -4526,6 +4568,13 @@ description = "Número máximo de tentativas de login com falha antes do bloquei
|
||||
label = "Tempo para redefinir tentativas (minutos)"
|
||||
description = "Tempo antes que as tentativas de login com falha sejam redefinidas"
|
||||
|
||||
[admin.settings.security.xFrameOptions]
|
||||
label = "X-Frame-Options"
|
||||
description = "Controls whether the application can be embedded in iframes"
|
||||
deny = "Deny (Prevents all framing)"
|
||||
sameorigin = "Same Origin (Allow framing from same domain)"
|
||||
disabled = "Disabled (No X-Frame-Options header)"
|
||||
|
||||
[admin.settings.security.csrfDisabled]
|
||||
label = "Desativar proteção CSRF"
|
||||
description = "Desativar a proteção contra Cross-Site Request Forgery (não recomendado)"
|
||||
|
||||
@@ -439,7 +439,9 @@ fullscreen = "Ecrã inteiro"
|
||||
[settings.general.updates]
|
||||
title = "Atualizações de software"
|
||||
description = "Procurar atualizações e ver informações da versão"
|
||||
currentVersion = "Versão atual"
|
||||
currentBackendVersion = "Current Backend Version"
|
||||
currentFrontendVersion = "Current Frontend Version"
|
||||
versionMismatch = "Warning: A mismatch has been detected between the client version and the AppConfig version. Using different versions can lead to compatibility issues, errors, and security risks. Please ensure that server and client are using the same version."
|
||||
latestVersion = "Última versão"
|
||||
checkForUpdates = "Procurar atualizações"
|
||||
viewDetails = "Ver detalhes"
|
||||
@@ -950,6 +952,7 @@ title = "Auto-dividir por tamanho/n.º"
|
||||
desc = "Dividir um único PDF em múltiplos documentos baseado em tamanho, contagem de páginas, ou contagem de documentos"
|
||||
|
||||
[home.replaceColor]
|
||||
tags = "replace color,invert color,color replacement,swap colors,change color,invert,negative,color swap,find and replace color,convert color,color change"
|
||||
title = "Substituir e inverter cor"
|
||||
desc = "Substituir ou inverter cores em documentos PDF"
|
||||
|
||||
@@ -964,18 +967,22 @@ title = "Varrimento auto de pastas"
|
||||
desc = "Ligação para o guia de varrimento automático de pastas"
|
||||
|
||||
[home.devSsoGuide]
|
||||
tags = "SSO,single sign-on,authentication,SAML,OAuth,OIDC,login,enterprise,identity provider,IdP"
|
||||
title = "Guia de SSO"
|
||||
desc = "Ligação para o guia de SSO"
|
||||
|
||||
[home.devAirgapped]
|
||||
tags = "air-gapped,offline,isolated,no internet,disconnected,secure,network isolation,standalone"
|
||||
title = "Configuração Air-gapped"
|
||||
desc = "Ligação para o guia de configuração Air-gapped"
|
||||
|
||||
[home.addPassword]
|
||||
tags = "encrypt,password,lock,secure,protect,security,encryption,safeguard,confidential,private,restrict access"
|
||||
title = "Adicionar Palavra-passe"
|
||||
desc = "Encriptar o seu documento PDF com uma palavra-passe."
|
||||
|
||||
[home.changePermissions]
|
||||
tags = "permissions,restrictions,rights,access control,allow,deny,printing,copying,editing,modify permissions,security settings,user rights"
|
||||
title = "Alterar Permissões"
|
||||
desc = "Alterar restrições e permissões do documento"
|
||||
|
||||
@@ -985,10 +992,12 @@ title = "Automatizar"
|
||||
desc = "Crie fluxos de trabalho de vários passos encadeando ações de PDF. Ideal para tarefas recorrentes."
|
||||
|
||||
[home.overlay-pdfs]
|
||||
tags = "overlay,combine,merge,layer,superimpose,overlay PDF,layer PDFs,combine PDFs,stack,overlay pages,background,foreground,composite"
|
||||
desc = "Sobrepõe PDFs em cima de outro PDF"
|
||||
title = "Sobrepor PDFs"
|
||||
|
||||
[home.pdfTextEditor]
|
||||
tags = "edit text,modify text,change text,edit content,update text,rewrite,correct,amend,redline,revise,text editor,content editor"
|
||||
title = "Editor de texto PDF"
|
||||
desc = "Revise e edite exportações JSON do Stirling PDF com edição de texto agrupado e regeneração de PDF"
|
||||
|
||||
@@ -3553,6 +3562,31 @@ imageSize = "Tamanho da imagem"
|
||||
margin = "Margem"
|
||||
positionAndFormatting = "Posição e formatação"
|
||||
quickPosition = "Selecione uma posição na página para colocar o carimbo."
|
||||
clickToExpand = "Click to expand"
|
||||
customDateDesc = "Custom format"
|
||||
dateDesc = "Current date"
|
||||
dateTimeVars = "Date & Time"
|
||||
datetimeDesc = "Date and time combined"
|
||||
dynamicVariables = "Dynamic Variables"
|
||||
examples = "Examples"
|
||||
fileVars = "File Information"
|
||||
filenameDesc = "Filename without extension"
|
||||
filenameFullDesc = "Filename with extension"
|
||||
metadataDesc = "From PDF document properties"
|
||||
metadataVars = "Document Metadata"
|
||||
multiLine = "multi-line"
|
||||
otherVars = "Other"
|
||||
pageNumberDesc = "Current page number"
|
||||
pageVars = "Page Information"
|
||||
preview = "Preview:"
|
||||
selectTemplate = "Select a template..."
|
||||
stampTextDescription = "Use dynamic variables below. Use @@ for literal @. Use \\n for new lines."
|
||||
timeDesc = "Current time"
|
||||
totalPagesDesc = "Total number of pages"
|
||||
useTemplate = "Use Template"
|
||||
uuidDesc = "Short unique identifier (8 chars)"
|
||||
variablesHelp = "Click on any variable to insert it into your stamp text. Use @@ for literal @."
|
||||
yearMonthDayDesc = "Individual date parts"
|
||||
|
||||
[AddStampRequest.error]
|
||||
failed = "Ocorreu um erro ao adicionar o carimbo ao PDF."
|
||||
@@ -3560,6 +3594,14 @@ failed = "Ocorreu um erro ao adicionar o carimbo ao PDF."
|
||||
[AddStampRequest.results]
|
||||
title = "Resultados do carimbo"
|
||||
|
||||
[AddStampRequest.template]
|
||||
custom = "Custom"
|
||||
dateHeader = "Date Header"
|
||||
draftWatermark = "Draft Watermark"
|
||||
europeanDate = "European Date"
|
||||
pageNumberFooter = "Page Number Footer"
|
||||
timestamp = "Timestamp"
|
||||
|
||||
[removeImagePdf]
|
||||
tags = "Remover Imagem,operações de página,lado servidor"
|
||||
|
||||
@@ -4526,6 +4568,13 @@ description = "Número máximo de tentativas falhadas de início de sessão ante
|
||||
label = "Tempo de reposição do início de sessão (minutos)"
|
||||
description = "Tempo até que as tentativas falhadas de início de sessão sejam repostas"
|
||||
|
||||
[admin.settings.security.xFrameOptions]
|
||||
label = "X-Frame-Options"
|
||||
description = "Controls whether the application can be embedded in iframes"
|
||||
deny = "Deny (Prevents all framing)"
|
||||
sameorigin = "Same Origin (Allow framing from same domain)"
|
||||
disabled = "Disabled (No X-Frame-Options header)"
|
||||
|
||||
[admin.settings.security.csrfDisabled]
|
||||
label = "Desativar proteção CSRF"
|
||||
description = "Desativar proteção Cross-Site Request Forgery (não recomendado)"
|
||||
|
||||
@@ -439,7 +439,9 @@ fullscreen = "Ecran complet"
|
||||
[settings.general.updates]
|
||||
title = "Actualizări software"
|
||||
description = "Caută actualizări și vezi informații despre versiune"
|
||||
currentVersion = "Versiune curentă"
|
||||
currentBackendVersion = "Current Backend Version"
|
||||
currentFrontendVersion = "Current Frontend Version"
|
||||
versionMismatch = "Warning: A mismatch has been detected between the client version and the AppConfig version. Using different versions can lead to compatibility issues, errors, and security risks. Please ensure that server and client are using the same version."
|
||||
latestVersion = "Ultima versiune"
|
||||
checkForUpdates = "Caută actualizări"
|
||||
viewDetails = "Vezi detalii"
|
||||
@@ -950,6 +952,7 @@ title = "Auto-împărțire mărime/pagini"
|
||||
desc = "Împarte un singur PDF în mai multe documente bazat pe dimensiune, număr de pagini sau număr de documente"
|
||||
|
||||
[home.replaceColor]
|
||||
tags = "replace color,invert color,color replacement,swap colors,change color,invert,negative,color swap,find and replace color,convert color,color change"
|
||||
title = "Schimbă și inversează culori"
|
||||
desc = "Înlocuiți sau inversați culorile în documente PDF"
|
||||
|
||||
@@ -964,18 +967,22 @@ title = "Scanare automată foldere"
|
||||
desc = "Link către ghidul de scanare automată a folderelor"
|
||||
|
||||
[home.devSsoGuide]
|
||||
tags = "SSO,single sign-on,authentication,SAML,OAuth,OIDC,login,enterprise,identity provider,IdP"
|
||||
title = "Ghid SSO"
|
||||
desc = "Link către ghidul SSO"
|
||||
|
||||
[home.devAirgapped]
|
||||
tags = "air-gapped,offline,isolated,no internet,disconnected,secure,network isolation,standalone"
|
||||
title = "Configurare air-gapped"
|
||||
desc = "Link către ghidul de configurare izolată de rețea"
|
||||
|
||||
[home.addPassword]
|
||||
tags = "encrypt,password,lock,secure,protect,security,encryption,safeguard,confidential,private,restrict access"
|
||||
title = "Adaugă Parolă"
|
||||
desc = "Criptează documentul PDF cu o parolă."
|
||||
|
||||
[home.changePermissions]
|
||||
tags = "permissions,restrictions,rights,access control,allow,deny,printing,copying,editing,modify permissions,security settings,user rights"
|
||||
title = "Schimbă Permisiunile"
|
||||
desc = "Schimbați restricțiile și permisiunile documentului"
|
||||
|
||||
@@ -985,10 +992,12 @@ title = "Automatizare"
|
||||
desc = "Construiți fluxuri cu mai mulți pași legând acțiuni PDF. Ideal pentru sarcini recurente."
|
||||
|
||||
[home.overlay-pdfs]
|
||||
tags = "overlay,combine,merge,layer,superimpose,overlay PDF,layer PDFs,combine PDFs,stack,overlay pages,background,foreground,composite"
|
||||
desc = "Suprapune PDF-uri peste alt PDF"
|
||||
title = "Suprapune PDF-uri"
|
||||
|
||||
[home.pdfTextEditor]
|
||||
tags = "edit text,modify text,change text,edit content,update text,rewrite,correct,amend,redline,revise,text editor,content editor"
|
||||
title = "Editor text PDF"
|
||||
desc = "Revizuiește și editează exporturile JSON Stirling PDF cu editare de text grupată și regenerare PDF"
|
||||
|
||||
@@ -3553,6 +3562,31 @@ imageSize = "Dimensiunea imaginii"
|
||||
margin = "Margine"
|
||||
positionAndFormatting = "Poziție și formatare"
|
||||
quickPosition = "Selectați o poziție pe pagină pentru a plasa ștampila."
|
||||
clickToExpand = "Click to expand"
|
||||
customDateDesc = "Custom format"
|
||||
dateDesc = "Current date"
|
||||
dateTimeVars = "Date & Time"
|
||||
datetimeDesc = "Date and time combined"
|
||||
dynamicVariables = "Dynamic Variables"
|
||||
examples = "Examples"
|
||||
fileVars = "File Information"
|
||||
filenameDesc = "Filename without extension"
|
||||
filenameFullDesc = "Filename with extension"
|
||||
metadataDesc = "From PDF document properties"
|
||||
metadataVars = "Document Metadata"
|
||||
multiLine = "multi-line"
|
||||
otherVars = "Other"
|
||||
pageNumberDesc = "Current page number"
|
||||
pageVars = "Page Information"
|
||||
preview = "Preview:"
|
||||
selectTemplate = "Select a template..."
|
||||
stampTextDescription = "Use dynamic variables below. Use @@ for literal @. Use \\n for new lines."
|
||||
timeDesc = "Current time"
|
||||
totalPagesDesc = "Total number of pages"
|
||||
useTemplate = "Use Template"
|
||||
uuidDesc = "Short unique identifier (8 chars)"
|
||||
variablesHelp = "Click on any variable to insert it into your stamp text. Use @@ for literal @."
|
||||
yearMonthDayDesc = "Individual date parts"
|
||||
|
||||
[AddStampRequest.error]
|
||||
failed = "A apărut o eroare la adăugarea ștampilei în PDF."
|
||||
@@ -3560,6 +3594,14 @@ failed = "A apărut o eroare la adăugarea ștampilei în PDF."
|
||||
[AddStampRequest.results]
|
||||
title = "Rezultatele ștampilării"
|
||||
|
||||
[AddStampRequest.template]
|
||||
custom = "Custom"
|
||||
dateHeader = "Date Header"
|
||||
draftWatermark = "Draft Watermark"
|
||||
europeanDate = "European Date"
|
||||
pageNumberFooter = "Page Number Footer"
|
||||
timestamp = "Timestamp"
|
||||
|
||||
[removeImagePdf]
|
||||
tags = "Elimină Imagine,Operații pagină,Back end,server side"
|
||||
|
||||
@@ -4526,6 +4568,13 @@ description = "Numărul maxim de încercări eșuate înainte de blocarea contul
|
||||
label = "Timp resetare autentificare (minute)"
|
||||
description = "Timpul înainte de resetarea încercărilor eșuate"
|
||||
|
||||
[admin.settings.security.xFrameOptions]
|
||||
label = "X-Frame-Options"
|
||||
description = "Controls whether the application can be embedded in iframes"
|
||||
deny = "Deny (Prevents all framing)"
|
||||
sameorigin = "Same Origin (Allow framing from same domain)"
|
||||
disabled = "Disabled (No X-Frame-Options header)"
|
||||
|
||||
[admin.settings.security.csrfDisabled]
|
||||
label = "Dezactivează protecția CSRF"
|
||||
description = "Dezactivează protecția Cross-Site Request Forgery (nerecomandat)"
|
||||
|
||||
@@ -439,7 +439,9 @@ fullscreen = "Полноэкранный"
|
||||
[settings.general.updates]
|
||||
title = "Обновления ПО"
|
||||
description = "Проверка обновлений и сведения о версии"
|
||||
currentVersion = "Текущая версия"
|
||||
currentBackendVersion = "Current Backend Version"
|
||||
currentFrontendVersion = "Current Frontend Version"
|
||||
versionMismatch = "Warning: A mismatch has been detected between the client version and the AppConfig version. Using different versions can lead to compatibility issues, errors, and security risks. Please ensure that server and client are using the same version."
|
||||
latestVersion = "Последняя версия"
|
||||
checkForUpdates = "Проверить обновления"
|
||||
viewDetails = "Подробнее"
|
||||
@@ -950,6 +952,7 @@ title = "Авторазбить по размеру/стр."
|
||||
desc = "Разделяет один PDF на несколько документов на основе размера, количества страниц или количества документов"
|
||||
|
||||
[home.replaceColor]
|
||||
tags = "replace color,invert color,color replacement,swap colors,change color,invert,negative,color swap,find and replace color,convert color,color change"
|
||||
title = "Заменить и инвертировать цвет"
|
||||
desc = "Заменяйте или инвертируйте цвета в PDF-документах"
|
||||
|
||||
@@ -964,18 +967,22 @@ title = "Автосканирование папок"
|
||||
desc = "Ссылка на руководство по автоматическому сканированию папок"
|
||||
|
||||
[home.devSsoGuide]
|
||||
tags = "SSO,single sign-on,authentication,SAML,OAuth,OIDC,login,enterprise,identity provider,IdP"
|
||||
title = "Руководство по SSO"
|
||||
desc = "Ссылка на руководство по SSO"
|
||||
|
||||
[home.devAirgapped]
|
||||
tags = "air-gapped,offline,isolated,no internet,disconnected,secure,network isolation,standalone"
|
||||
title = "Изолированная установка"
|
||||
desc = "Ссылка на руководство по изолированной установке"
|
||||
|
||||
[home.addPassword]
|
||||
tags = "encrypt,password,lock,secure,protect,security,encryption,safeguard,confidential,private,restrict access"
|
||||
title = "Добавить пароль"
|
||||
desc = "Зашифруйте ваш PDF-документ паролем."
|
||||
|
||||
[home.changePermissions]
|
||||
tags = "permissions,restrictions,rights,access control,allow,deny,printing,copying,editing,modify permissions,security settings,user rights"
|
||||
title = "Изменить разрешения"
|
||||
desc = "Изменение ограничений и разрешений документа"
|
||||
|
||||
@@ -985,10 +992,12 @@ title = "Автоматизация"
|
||||
desc = "Создавайте многошаговые процессы, связывая PDF-действия. Идеально для повторяющихся задач."
|
||||
|
||||
[home.overlay-pdfs]
|
||||
tags = "overlay,combine,merge,layer,superimpose,overlay PDF,layer PDFs,combine PDFs,stack,overlay pages,background,foreground,composite"
|
||||
desc = "Наложить один PDF поверх другого"
|
||||
title = "Наложение PDF"
|
||||
|
||||
[home.pdfTextEditor]
|
||||
tags = "edit text,modify text,change text,edit content,update text,rewrite,correct,amend,redline,revise,text editor,content editor"
|
||||
title = "Редактор текста в PDF"
|
||||
desc = "Просмотр и редактирование экспортов Stirling PDF в JSON с групповым редактированием текста и регенерацией PDF"
|
||||
|
||||
@@ -3553,6 +3562,31 @@ imageSize = "Размер изображения"
|
||||
margin = "Отступ"
|
||||
positionAndFormatting = "Положение и форматирование"
|
||||
quickPosition = "Выберите положение на странице для размещения штампа."
|
||||
clickToExpand = "Click to expand"
|
||||
customDateDesc = "Custom format"
|
||||
dateDesc = "Current date"
|
||||
dateTimeVars = "Date & Time"
|
||||
datetimeDesc = "Date and time combined"
|
||||
dynamicVariables = "Dynamic Variables"
|
||||
examples = "Examples"
|
||||
fileVars = "File Information"
|
||||
filenameDesc = "Filename without extension"
|
||||
filenameFullDesc = "Filename with extension"
|
||||
metadataDesc = "From PDF document properties"
|
||||
metadataVars = "Document Metadata"
|
||||
multiLine = "multi-line"
|
||||
otherVars = "Other"
|
||||
pageNumberDesc = "Current page number"
|
||||
pageVars = "Page Information"
|
||||
preview = "Preview:"
|
||||
selectTemplate = "Select a template..."
|
||||
stampTextDescription = "Use dynamic variables below. Use @@ for literal @. Use \\n for new lines."
|
||||
timeDesc = "Current time"
|
||||
totalPagesDesc = "Total number of pages"
|
||||
useTemplate = "Use Template"
|
||||
uuidDesc = "Short unique identifier (8 chars)"
|
||||
variablesHelp = "Click on any variable to insert it into your stamp text. Use @@ for literal @."
|
||||
yearMonthDayDesc = "Individual date parts"
|
||||
|
||||
[AddStampRequest.error]
|
||||
failed = "Произошла ошибка при добавлении штампа в PDF."
|
||||
@@ -3560,6 +3594,14 @@ failed = "Произошла ошибка при добавлении штамп
|
||||
[AddStampRequest.results]
|
||||
title = "Результаты штампа"
|
||||
|
||||
[AddStampRequest.template]
|
||||
custom = "Custom"
|
||||
dateHeader = "Date Header"
|
||||
draftWatermark = "Draft Watermark"
|
||||
europeanDate = "European Date"
|
||||
pageNumberFooter = "Page Number Footer"
|
||||
timestamp = "Timestamp"
|
||||
|
||||
[removeImagePdf]
|
||||
tags = "Удаление изображения,операции со страницами,Серверная часть"
|
||||
|
||||
@@ -4526,6 +4568,13 @@ description = "Максимальное число неудачных попыт
|
||||
label = "Время сброса попыток (минуты)"
|
||||
description = "Время до сброса счетчика неудачных попыток входа"
|
||||
|
||||
[admin.settings.security.xFrameOptions]
|
||||
label = "X-Frame-Options"
|
||||
description = "Controls whether the application can be embedded in iframes"
|
||||
deny = "Deny (Prevents all framing)"
|
||||
sameorigin = "Same Origin (Allow framing from same domain)"
|
||||
disabled = "Disabled (No X-Frame-Options header)"
|
||||
|
||||
[admin.settings.security.csrfDisabled]
|
||||
label = "Отключить защиту CSRF"
|
||||
description = "Отключить защиту от межсайтовой подделки запросов (не рекомендуется)"
|
||||
|
||||
@@ -439,7 +439,9 @@ fullscreen = "Celá obrazovka"
|
||||
[settings.general.updates]
|
||||
title = "Aktualizácie softvéru"
|
||||
description = "Skontrolujte aktualizácie a zobrazte informácie o verzii"
|
||||
currentVersion = "Aktuálna verzia"
|
||||
currentBackendVersion = "Current Backend Version"
|
||||
currentFrontendVersion = "Current Frontend Version"
|
||||
versionMismatch = "Warning: A mismatch has been detected between the client version and the AppConfig version. Using different versions can lead to compatibility issues, errors, and security risks. Please ensure that server and client are using the same version."
|
||||
latestVersion = "Najnovšia verzia"
|
||||
checkForUpdates = "Skontrolovať aktualizácie"
|
||||
viewDetails = "Zobraziť podrobnosti"
|
||||
@@ -950,6 +952,7 @@ title = "Auto rozdeliť veľkosť/počet"
|
||||
desc = "Rozdelí jeden PDF na viacero dokumentov na základe veľkosti, počtu stránok alebo počtu dokumentov"
|
||||
|
||||
[home.replaceColor]
|
||||
tags = "replace color,invert color,color replacement,swap colors,change color,invert,negative,color swap,find and replace color,convert color,color change"
|
||||
title = "Nahradiť a invertovať farby"
|
||||
desc = "Nahradiť alebo invertovať farby v dokumentoch PDF"
|
||||
|
||||
@@ -964,18 +967,22 @@ title = "Auto skenovanie priečinkov"
|
||||
desc = "Odkaz na príručku k automatizovanému skenovaniu priečinkov"
|
||||
|
||||
[home.devSsoGuide]
|
||||
tags = "SSO,single sign-on,authentication,SAML,OAuth,OIDC,login,enterprise,identity provider,IdP"
|
||||
title = "SSO príručka"
|
||||
desc = "Odkaz na SSO príručku"
|
||||
|
||||
[home.devAirgapped]
|
||||
tags = "air-gapped,offline,isolated,no internet,disconnected,secure,network isolation,standalone"
|
||||
title = "Air-gapped nastavenie"
|
||||
desc = "Odkaz na príručku k air-gapped nastaveniu"
|
||||
|
||||
[home.addPassword]
|
||||
tags = "encrypt,password,lock,secure,protect,security,encryption,safeguard,confidential,private,restrict access"
|
||||
title = "Pridať heslo"
|
||||
desc = "Šifrovať váš PDF dokument heslom."
|
||||
|
||||
[home.changePermissions]
|
||||
tags = "permissions,restrictions,rights,access control,allow,deny,printing,copying,editing,modify permissions,security settings,user rights"
|
||||
title = "Zmeniť povolenia"
|
||||
desc = "Zmeniť obmedzenia a povolenia dokumentu"
|
||||
|
||||
@@ -985,10 +992,12 @@ title = "Automatizovať"
|
||||
desc = "Stavať viacstupňové pracovné postupy spájaním akcií PDF. Ideálne pre opakované úlohy."
|
||||
|
||||
[home.overlay-pdfs]
|
||||
tags = "overlay,combine,merge,layer,superimpose,overlay PDF,layer PDFs,combine PDFs,stack,overlay pages,background,foreground,composite"
|
||||
desc = "Prekrýva PDF súbory na iný PDF"
|
||||
title = "Prekrývanie PDF"
|
||||
|
||||
[home.pdfTextEditor]
|
||||
tags = "edit text,modify text,change text,edit content,update text,rewrite,correct,amend,redline,revise,text editor,content editor"
|
||||
title = "Editor textu PDF"
|
||||
desc = "Kontrolujte a upravujte Stirling PDF JSON exporty so skupinovými úpravami textu a opätovným vytvorením PDF"
|
||||
|
||||
@@ -3553,6 +3562,31 @@ imageSize = "Veľkosť obrázka"
|
||||
margin = "Okraj"
|
||||
positionAndFormatting = "Poloha a formátovanie"
|
||||
quickPosition = "Vyberte polohu na stránke pre umiestnenie pečiatky."
|
||||
clickToExpand = "Click to expand"
|
||||
customDateDesc = "Custom format"
|
||||
dateDesc = "Current date"
|
||||
dateTimeVars = "Date & Time"
|
||||
datetimeDesc = "Date and time combined"
|
||||
dynamicVariables = "Dynamic Variables"
|
||||
examples = "Examples"
|
||||
fileVars = "File Information"
|
||||
filenameDesc = "Filename without extension"
|
||||
filenameFullDesc = "Filename with extension"
|
||||
metadataDesc = "From PDF document properties"
|
||||
metadataVars = "Document Metadata"
|
||||
multiLine = "multi-line"
|
||||
otherVars = "Other"
|
||||
pageNumberDesc = "Current page number"
|
||||
pageVars = "Page Information"
|
||||
preview = "Preview:"
|
||||
selectTemplate = "Select a template..."
|
||||
stampTextDescription = "Use dynamic variables below. Use @@ for literal @. Use \\n for new lines."
|
||||
timeDesc = "Current time"
|
||||
totalPagesDesc = "Total number of pages"
|
||||
useTemplate = "Use Template"
|
||||
uuidDesc = "Short unique identifier (8 chars)"
|
||||
variablesHelp = "Click on any variable to insert it into your stamp text. Use @@ for literal @."
|
||||
yearMonthDayDesc = "Individual date parts"
|
||||
|
||||
[AddStampRequest.error]
|
||||
failed = "Počas pridávania pečiatky do PDF došlo k chybe."
|
||||
@@ -3560,6 +3594,14 @@ failed = "Počas pridávania pečiatky do PDF došlo k chybe."
|
||||
[AddStampRequest.results]
|
||||
title = "Výsledky pečiatky"
|
||||
|
||||
[AddStampRequest.template]
|
||||
custom = "Custom"
|
||||
dateHeader = "Date Header"
|
||||
draftWatermark = "Draft Watermark"
|
||||
europeanDate = "European Date"
|
||||
pageNumberFooter = "Page Number Footer"
|
||||
timestamp = "Timestamp"
|
||||
|
||||
[removeImagePdf]
|
||||
tags = "Odstrániť obrázok,Operácie so stranami,Back end,server side"
|
||||
|
||||
@@ -4526,6 +4568,13 @@ description = "Maximálny počet neúspešných pokusov o prihlásenie pred zabl
|
||||
label = "Reset prihlásenia (minúty)"
|
||||
description = "Čas, po ktorom sa zlyhané pokusy o prihlásenie vynulujú"
|
||||
|
||||
[admin.settings.security.xFrameOptions]
|
||||
label = "X-Frame-Options"
|
||||
description = "Controls whether the application can be embedded in iframes"
|
||||
deny = "Deny (Prevents all framing)"
|
||||
sameorigin = "Same Origin (Allow framing from same domain)"
|
||||
disabled = "Disabled (No X-Frame-Options header)"
|
||||
|
||||
[admin.settings.security.csrfDisabled]
|
||||
label = "Zakázať ochranu CSRF"
|
||||
description = "Zakázať ochranu proti Cross-Site Request Forgery (neodporúča sa)"
|
||||
|
||||
@@ -439,7 +439,9 @@ fullscreen = "Celozaslonski"
|
||||
[settings.general.updates]
|
||||
title = "Posodobitve programske opreme"
|
||||
description = "Preverite posodobitve in glejte informacije o različici"
|
||||
currentVersion = "Trenutna različica"
|
||||
currentBackendVersion = "Current Backend Version"
|
||||
currentFrontendVersion = "Current Frontend Version"
|
||||
versionMismatch = "Warning: A mismatch has been detected between the client version and the AppConfig version. Using different versions can lead to compatibility issues, errors, and security risks. Please ensure that server and client are using the same version."
|
||||
latestVersion = "Najnovejša različica"
|
||||
checkForUpdates = "Preveri posodobitve"
|
||||
viewDetails = "Poglej podrobnosti"
|
||||
@@ -950,6 +952,7 @@ title = "Samodejno razdeli po vel./št."
|
||||
desc = "Razdeli en PDF na več dokumentov glede na velikost, število strani ali število dokumentov"
|
||||
|
||||
[home.replaceColor]
|
||||
tags = "replace color,invert color,color replacement,swap colors,change color,invert,negative,color swap,find and replace color,convert color,color change"
|
||||
title = "Zamenjaj in invertiraj barve"
|
||||
desc = "Zamenjajte ali invertirajte barve v dokumentih PDF"
|
||||
|
||||
@@ -964,18 +967,22 @@ title = "Samodejno skeniranje map"
|
||||
desc = "Povezava do vodiča za avtomatizirano skeniranje map"
|
||||
|
||||
[home.devSsoGuide]
|
||||
tags = "SSO,single sign-on,authentication,SAML,OAuth,OIDC,login,enterprise,identity provider,IdP"
|
||||
title = "Vodič za SSO"
|
||||
desc = "Povezava do vodiča za SSO"
|
||||
|
||||
[home.devAirgapped]
|
||||
tags = "air-gapped,offline,isolated,no internet,disconnected,secure,network isolation,standalone"
|
||||
title = "Izolirana namestitev"
|
||||
desc = "Povezava do vodiča za namestitev v izoliranem omrežju"
|
||||
|
||||
[home.addPassword]
|
||||
tags = "encrypt,password,lock,secure,protect,security,encryption,safeguard,confidential,private,restrict access"
|
||||
title = "Dodaj geslo"
|
||||
desc = "Šifrirajte svoj dokument PDF z geslom."
|
||||
|
||||
[home.changePermissions]
|
||||
tags = "permissions,restrictions,rights,access control,allow,deny,printing,copying,editing,modify permissions,security settings,user rights"
|
||||
title = "Spremeni dovoljenja"
|
||||
desc = "Spremenite omejitve in dovoljenja dokumenta"
|
||||
|
||||
@@ -985,10 +992,12 @@ title = "Avtomatiziraj"
|
||||
desc = "Sestavite večkorakovne poteke z veriženjem dejanj PDF. Idealno za ponavljajoče se naloge."
|
||||
|
||||
[home.overlay-pdfs]
|
||||
tags = "overlay,combine,merge,layer,superimpose,overlay PDF,layer PDFs,combine PDFs,stack,overlay pages,background,foreground,composite"
|
||||
desc = "Prekriva PDF-je na vrhu drugega PDF-ja"
|
||||
title = "Prekrivanje PDF-jev"
|
||||
|
||||
[home.pdfTextEditor]
|
||||
tags = "edit text,modify text,change text,edit content,update text,rewrite,correct,amend,redline,revise,text editor,content editor"
|
||||
title = "Urejevalnik besedila PDF"
|
||||
desc = "Pregledujte in urejajte Stirling PDF JSON izvoze z urejanjem združenega besedila in ponovnim ustvarjanjem PDF"
|
||||
|
||||
@@ -3553,6 +3562,31 @@ imageSize = "Velikost slike"
|
||||
margin = "Rob"
|
||||
positionAndFormatting = "Položaj in oblikovanje"
|
||||
quickPosition = "Izberite položaj na strani za postavitev žiga."
|
||||
clickToExpand = "Click to expand"
|
||||
customDateDesc = "Custom format"
|
||||
dateDesc = "Current date"
|
||||
dateTimeVars = "Date & Time"
|
||||
datetimeDesc = "Date and time combined"
|
||||
dynamicVariables = "Dynamic Variables"
|
||||
examples = "Examples"
|
||||
fileVars = "File Information"
|
||||
filenameDesc = "Filename without extension"
|
||||
filenameFullDesc = "Filename with extension"
|
||||
metadataDesc = "From PDF document properties"
|
||||
metadataVars = "Document Metadata"
|
||||
multiLine = "multi-line"
|
||||
otherVars = "Other"
|
||||
pageNumberDesc = "Current page number"
|
||||
pageVars = "Page Information"
|
||||
preview = "Preview:"
|
||||
selectTemplate = "Select a template..."
|
||||
stampTextDescription = "Use dynamic variables below. Use @@ for literal @. Use \\n for new lines."
|
||||
timeDesc = "Current time"
|
||||
totalPagesDesc = "Total number of pages"
|
||||
useTemplate = "Use Template"
|
||||
uuidDesc = "Short unique identifier (8 chars)"
|
||||
variablesHelp = "Click on any variable to insert it into your stamp text. Use @@ for literal @."
|
||||
yearMonthDayDesc = "Individual date parts"
|
||||
|
||||
[AddStampRequest.error]
|
||||
failed = "Pri dodajanju žiga v PDF je prišlo do napake."
|
||||
@@ -3560,6 +3594,14 @@ failed = "Pri dodajanju žiga v PDF je prišlo do napake."
|
||||
[AddStampRequest.results]
|
||||
title = "Rezultati žiga"
|
||||
|
||||
[AddStampRequest.template]
|
||||
custom = "Custom"
|
||||
dateHeader = "Date Header"
|
||||
draftWatermark = "Draft Watermark"
|
||||
europeanDate = "European Date"
|
||||
pageNumberFooter = "Page Number Footer"
|
||||
timestamp = "Timestamp"
|
||||
|
||||
[removeImagePdf]
|
||||
tags = "Odstrani sliko,operacije strani,zadnja stran,strežniška stran"
|
||||
|
||||
@@ -4526,6 +4568,13 @@ description = "Največje število neuspelih poskusov prijave pred zaklepom raču
|
||||
label = "Čas ponastavitve prijave (minute)"
|
||||
description = "Čas do ponastavitve neuspelih poskusov prijave"
|
||||
|
||||
[admin.settings.security.xFrameOptions]
|
||||
label = "X-Frame-Options"
|
||||
description = "Controls whether the application can be embedded in iframes"
|
||||
deny = "Deny (Prevents all framing)"
|
||||
sameorigin = "Same Origin (Allow framing from same domain)"
|
||||
disabled = "Disabled (No X-Frame-Options header)"
|
||||
|
||||
[admin.settings.security.csrfDisabled]
|
||||
label = "Onemogoči zaščito CSRF"
|
||||
description = "Onemogoči zaščito pred ponarejanjem zahtev (ni priporočljivo)"
|
||||
|
||||
@@ -439,7 +439,9 @@ fullscreen = "Ceo ekran"
|
||||
[settings.general.updates]
|
||||
title = "Ažuriranja softvera"
|
||||
description = "Proverite ažuriranja i pogledajte informacije o verziji"
|
||||
currentVersion = "Trenutna verzija"
|
||||
currentBackendVersion = "Current Backend Version"
|
||||
currentFrontendVersion = "Current Frontend Version"
|
||||
versionMismatch = "Warning: A mismatch has been detected between the client version and the AppConfig version. Using different versions can lead to compatibility issues, errors, and security risks. Please ensure that server and client are using the same version."
|
||||
latestVersion = "Najnovija verzija"
|
||||
checkForUpdates = "Proveri ažuriranja"
|
||||
viewDetails = "Prikaži detalje"
|
||||
@@ -950,6 +952,7 @@ title = "Automatsko deljenje po veličini/broju"
|
||||
desc = "Deljenje jednog PDF-a na više na osnovu veličine, broja stranica ili broja dokumenata"
|
||||
|
||||
[home.replaceColor]
|
||||
tags = "replace color,invert color,color replacement,swap colors,change color,invert,negative,color swap,find and replace color,convert color,color change"
|
||||
title = "Zameni i invertiraj boju"
|
||||
desc = "Zamenite ili invertirajte boje u PDF dokumentima"
|
||||
|
||||
@@ -964,18 +967,22 @@ title = "Automatsko skeniranje fascikli"
|
||||
desc = "Link ka vodiču za automatsko skeniranje fascikli"
|
||||
|
||||
[home.devSsoGuide]
|
||||
tags = "SSO,single sign-on,authentication,SAML,OAuth,OIDC,login,enterprise,identity provider,IdP"
|
||||
title = "SSO vodič"
|
||||
desc = "Link ka SSO vodiču"
|
||||
|
||||
[home.devAirgapped]
|
||||
tags = "air-gapped,offline,isolated,no internet,disconnected,secure,network isolation,standalone"
|
||||
title = "Air-gapped podešavanje"
|
||||
desc = "Link ka vodiču za air-gapped podešavanje"
|
||||
|
||||
[home.addPassword]
|
||||
tags = "encrypt,password,lock,secure,protect,security,encryption,safeguard,confidential,private,restrict access"
|
||||
title = "Dodaj lozinku"
|
||||
desc = "Enkriptujte vaš PDF dokument lozinkom."
|
||||
|
||||
[home.changePermissions]
|
||||
tags = "permissions,restrictions,rights,access control,allow,deny,printing,copying,editing,modify permissions,security settings,user rights"
|
||||
title = "Promeni dozvole"
|
||||
desc = "Promenite ograničenja dokumenta i dozvole"
|
||||
|
||||
@@ -985,10 +992,12 @@ title = "Automatizuj"
|
||||
desc = "Gradite višekorake tokove rada povezivanjem PDF akcija. Idealno za ponavljajuće zadatke."
|
||||
|
||||
[home.overlay-pdfs]
|
||||
tags = "overlay,combine,merge,layer,superimpose,overlay PDF,layer PDFs,combine PDFs,stack,overlay pages,background,foreground,composite"
|
||||
desc = "Preklapa PDF-ove jedan preko drugog"
|
||||
title = "Preklapanje PDF-ova"
|
||||
|
||||
[home.pdfTextEditor]
|
||||
tags = "edit text,modify text,change text,edit content,update text,rewrite,correct,amend,redline,revise,text editor,content editor"
|
||||
title = "PDF uređivač teksta"
|
||||
desc = "Pregledajte i uređujte Stirling PDF JSON izvoze uz grupisano uređivanje teksta i ponovno generisanje PDF-a"
|
||||
|
||||
@@ -3553,6 +3562,31 @@ imageSize = "Veličina slike"
|
||||
margin = "Margina"
|
||||
positionAndFormatting = "Pozicija i formatiranje"
|
||||
quickPosition = "Izaberite poziciju na stranici za postavljanje pečata."
|
||||
clickToExpand = "Click to expand"
|
||||
customDateDesc = "Custom format"
|
||||
dateDesc = "Current date"
|
||||
dateTimeVars = "Date & Time"
|
||||
datetimeDesc = "Date and time combined"
|
||||
dynamicVariables = "Dynamic Variables"
|
||||
examples = "Examples"
|
||||
fileVars = "File Information"
|
||||
filenameDesc = "Filename without extension"
|
||||
filenameFullDesc = "Filename with extension"
|
||||
metadataDesc = "From PDF document properties"
|
||||
metadataVars = "Document Metadata"
|
||||
multiLine = "multi-line"
|
||||
otherVars = "Other"
|
||||
pageNumberDesc = "Current page number"
|
||||
pageVars = "Page Information"
|
||||
preview = "Preview:"
|
||||
selectTemplate = "Select a template..."
|
||||
stampTextDescription = "Use dynamic variables below. Use @@ for literal @. Use \\n for new lines."
|
||||
timeDesc = "Current time"
|
||||
totalPagesDesc = "Total number of pages"
|
||||
useTemplate = "Use Template"
|
||||
uuidDesc = "Short unique identifier (8 chars)"
|
||||
variablesHelp = "Click on any variable to insert it into your stamp text. Use @@ for literal @."
|
||||
yearMonthDayDesc = "Individual date parts"
|
||||
|
||||
[AddStampRequest.error]
|
||||
failed = "Došlo je do greške prilikom dodavanja pečata u PDF."
|
||||
@@ -3560,6 +3594,14 @@ failed = "Došlo je do greške prilikom dodavanja pečata u PDF."
|
||||
[AddStampRequest.results]
|
||||
title = "Rezultati pečata"
|
||||
|
||||
[AddStampRequest.template]
|
||||
custom = "Custom"
|
||||
dateHeader = "Date Header"
|
||||
draftWatermark = "Draft Watermark"
|
||||
europeanDate = "European Date"
|
||||
pageNumberFooter = "Page Number Footer"
|
||||
timestamp = "Timestamp"
|
||||
|
||||
[removeImagePdf]
|
||||
tags = "Ukloni sliku, Zahvati na stranici, Bekend,serverska strana"
|
||||
|
||||
@@ -4526,6 +4568,13 @@ description = "Maksimalan broj neuspelih pokušaja prijave pre zaključavanja na
|
||||
label = "Vreme resetovanja (minute)"
|
||||
description = "Vreme posle kog se neuspešni pokušaji prijave resetuju"
|
||||
|
||||
[admin.settings.security.xFrameOptions]
|
||||
label = "X-Frame-Options"
|
||||
description = "Controls whether the application can be embedded in iframes"
|
||||
deny = "Deny (Prevents all framing)"
|
||||
sameorigin = "Same Origin (Allow framing from same domain)"
|
||||
disabled = "Disabled (No X-Frame-Options header)"
|
||||
|
||||
[admin.settings.security.csrfDisabled]
|
||||
label = "Onemogući CSRF zaštitu"
|
||||
description = "Onemogući Cross-Site Request Forgery zaštitu (nije preporučeno)"
|
||||
|
||||
@@ -439,7 +439,9 @@ fullscreen = "Helskärm"
|
||||
[settings.general.updates]
|
||||
title = "Programuppdateringar"
|
||||
description = "Sök efter uppdateringar och visa versionsinfo"
|
||||
currentVersion = "Aktuell version"
|
||||
currentBackendVersion = "Current Backend Version"
|
||||
currentFrontendVersion = "Current Frontend Version"
|
||||
versionMismatch = "Warning: A mismatch has been detected between the client version and the AppConfig version. Using different versions can lead to compatibility issues, errors, and security risks. Please ensure that server and client are using the same version."
|
||||
latestVersion = "Senaste version"
|
||||
checkForUpdates = "Sök efter uppdateringar"
|
||||
viewDetails = "Visa detaljer"
|
||||
@@ -950,6 +952,7 @@ title = "Auto-dela efter storlek/antal"
|
||||
desc = "Dela en enda PDF till flera dokument baserat på storlek, sidantal eller dokumentantal"
|
||||
|
||||
[home.replaceColor]
|
||||
tags = "replace color,invert color,color replacement,swap colors,change color,invert,negative,color swap,find and replace color,convert color,color change"
|
||||
title = "Ersätt och invertera färg"
|
||||
desc = "Ersätt eller invertera färger i PDF‑dokument"
|
||||
|
||||
@@ -964,18 +967,22 @@ title = "Automatiserad mappskanning"
|
||||
desc = "Länk till guide för automatiserad mappskanning"
|
||||
|
||||
[home.devSsoGuide]
|
||||
tags = "SSO,single sign-on,authentication,SAML,OAuth,OIDC,login,enterprise,identity provider,IdP"
|
||||
title = "SSO‑guide"
|
||||
desc = "Länk till SSO‑guide"
|
||||
|
||||
[home.devAirgapped]
|
||||
tags = "air-gapped,offline,isolated,no internet,disconnected,secure,network isolation,standalone"
|
||||
title = "Isolerad installation"
|
||||
desc = "Länk till guide för isolerad installation"
|
||||
|
||||
[home.addPassword]
|
||||
tags = "encrypt,password,lock,secure,protect,security,encryption,safeguard,confidential,private,restrict access"
|
||||
title = "Lägg till lösenord"
|
||||
desc = "Kryptera ditt PDF-dokument med ett lösenord."
|
||||
|
||||
[home.changePermissions]
|
||||
tags = "permissions,restrictions,rights,access control,allow,deny,printing,copying,editing,modify permissions,security settings,user rights"
|
||||
title = "Ändra behörigheter"
|
||||
desc = "Ändra dokumentrestriktioner och behörigheter"
|
||||
|
||||
@@ -985,10 +992,12 @@ title = "Automatisera"
|
||||
desc = "Skapa flerstegade arbetsflöden genom att kedja ihop PDF‑åtgärder. Perfekt för återkommande uppgifter."
|
||||
|
||||
[home.overlay-pdfs]
|
||||
tags = "overlay,combine,merge,layer,superimpose,overlay PDF,layer PDFs,combine PDFs,stack,overlay pages,background,foreground,composite"
|
||||
desc = "Överlagrar PDF:er ovanpå en annan PDF"
|
||||
title = "Överlagra PDF:er"
|
||||
|
||||
[home.pdfTextEditor]
|
||||
tags = "edit text,modify text,change text,edit content,update text,rewrite,correct,amend,redline,revise,text editor,content editor"
|
||||
title = "PDF-textredigerare"
|
||||
desc = "Granska och redigera Stirling PDF JSON-exporter med grupperad textredigering och PDF-återgenerering"
|
||||
|
||||
@@ -3553,6 +3562,31 @@ imageSize = "Bildstorlek"
|
||||
margin = "Marginal"
|
||||
positionAndFormatting = "Position och formatering"
|
||||
quickPosition = "Välj en position på sidan för att placera stämpeln."
|
||||
clickToExpand = "Click to expand"
|
||||
customDateDesc = "Custom format"
|
||||
dateDesc = "Current date"
|
||||
dateTimeVars = "Date & Time"
|
||||
datetimeDesc = "Date and time combined"
|
||||
dynamicVariables = "Dynamic Variables"
|
||||
examples = "Examples"
|
||||
fileVars = "File Information"
|
||||
filenameDesc = "Filename without extension"
|
||||
filenameFullDesc = "Filename with extension"
|
||||
metadataDesc = "From PDF document properties"
|
||||
metadataVars = "Document Metadata"
|
||||
multiLine = "multi-line"
|
||||
otherVars = "Other"
|
||||
pageNumberDesc = "Current page number"
|
||||
pageVars = "Page Information"
|
||||
preview = "Preview:"
|
||||
selectTemplate = "Select a template..."
|
||||
stampTextDescription = "Use dynamic variables below. Use @@ for literal @. Use \\n for new lines."
|
||||
timeDesc = "Current time"
|
||||
totalPagesDesc = "Total number of pages"
|
||||
useTemplate = "Use Template"
|
||||
uuidDesc = "Short unique identifier (8 chars)"
|
||||
variablesHelp = "Click on any variable to insert it into your stamp text. Use @@ for literal @."
|
||||
yearMonthDayDesc = "Individual date parts"
|
||||
|
||||
[AddStampRequest.error]
|
||||
failed = "Ett fel inträffade när stämpeln skulle läggas till i PDF:en."
|
||||
@@ -3560,6 +3594,14 @@ failed = "Ett fel inträffade när stämpeln skulle läggas till i PDF:en."
|
||||
[AddStampRequest.results]
|
||||
title = "Resultat av stämpling"
|
||||
|
||||
[AddStampRequest.template]
|
||||
custom = "Custom"
|
||||
dateHeader = "Date Header"
|
||||
draftWatermark = "Draft Watermark"
|
||||
europeanDate = "European Date"
|
||||
pageNumberFooter = "Page Number Footer"
|
||||
timestamp = "Timestamp"
|
||||
|
||||
[removeImagePdf]
|
||||
tags = "Ta bort bild,Sidoperationer,Backend,serversida"
|
||||
|
||||
@@ -4526,6 +4568,13 @@ description = "Maximalt antal misslyckade inloggningsförsök innan kontot låse
|
||||
label = "Återställningstid för inloggning (minuter)"
|
||||
description = "Tid innan misslyckade inloggningsförsök nollställs"
|
||||
|
||||
[admin.settings.security.xFrameOptions]
|
||||
label = "X-Frame-Options"
|
||||
description = "Controls whether the application can be embedded in iframes"
|
||||
deny = "Deny (Prevents all framing)"
|
||||
sameorigin = "Same Origin (Allow framing from same domain)"
|
||||
disabled = "Disabled (No X-Frame-Options header)"
|
||||
|
||||
[admin.settings.security.csrfDisabled]
|
||||
label = "Inaktivera CSRF-skydd"
|
||||
description = "Inaktivera skydd mot Cross-Site Request Forgery (rekommenderas inte)"
|
||||
|
||||
@@ -439,7 +439,9 @@ fullscreen = "เต็มหน้าจอ"
|
||||
[settings.general.updates]
|
||||
title = "อัปเดตซอฟต์แวร์"
|
||||
description = "ตรวจสอบอัปเดตและดูข้อมูลเวอร์ชัน"
|
||||
currentVersion = "เวอร์ชันปัจจุบัน"
|
||||
currentBackendVersion = "Current Backend Version"
|
||||
currentFrontendVersion = "Current Frontend Version"
|
||||
versionMismatch = "Warning: A mismatch has been detected between the client version and the AppConfig version. Using different versions can lead to compatibility issues, errors, and security risks. Please ensure that server and client are using the same version."
|
||||
latestVersion = "เวอร์ชันล่าสุด"
|
||||
checkForUpdates = "ตรวจสอบอัปเดต"
|
||||
viewDetails = "ดูรายละเอียด"
|
||||
@@ -950,6 +952,7 @@ title = "แยกตามขนาด/จำนวน"
|
||||
desc = "แยก PDF เป็นเอกสารหลายฉบับตามขนาด จำนวนหน้า หรือจำนวนเอกสาร"
|
||||
|
||||
[home.replaceColor]
|
||||
tags = "replace color,invert color,color replacement,swap colors,change color,invert,negative,color swap,find and replace color,convert color,color change"
|
||||
title = "แทนที่และกลับสี"
|
||||
desc = "แทนที่หรือกลับสีในเอกสาร PDF"
|
||||
|
||||
@@ -964,18 +967,22 @@ title = "สแกน โฟลเดอร์ อัตโนมัติ"
|
||||
desc = "ลิงก์ไปยังคู่มือการสแกนโฟลเดอร์อัตโนมัติ"
|
||||
|
||||
[home.devSsoGuide]
|
||||
tags = "SSO,single sign-on,authentication,SAML,OAuth,OIDC,login,enterprise,identity provider,IdP"
|
||||
title = "คู่มือ SSO"
|
||||
desc = "ลิงก์ไปยังคู่มือ SSO"
|
||||
|
||||
[home.devAirgapped]
|
||||
tags = "air-gapped,offline,isolated,no internet,disconnected,secure,network isolation,standalone"
|
||||
title = "การตั้งค่า Air-gapped"
|
||||
desc = "ลิงก์ไปยังคู่มือการตั้งค่า Air-gapped"
|
||||
|
||||
[home.addPassword]
|
||||
tags = "encrypt,password,lock,secure,protect,security,encryption,safeguard,confidential,private,restrict access"
|
||||
title = "เพิ่มรหัสผ่าน"
|
||||
desc = "เข้ารหัสเอกสาร PDF ของคุณด้วยรหัสผ่าน"
|
||||
|
||||
[home.changePermissions]
|
||||
tags = "permissions,restrictions,rights,access control,allow,deny,printing,copying,editing,modify permissions,security settings,user rights"
|
||||
title = "เปลี่ยนสิทธิ์"
|
||||
desc = "เปลี่ยนข้อจำกัดและสิทธิ์ของเอกสาร"
|
||||
|
||||
@@ -985,10 +992,12 @@ title = "ทำให้อัตโนมัติ"
|
||||
desc = "สร้างเวิร์กโฟลว์หลายขั้นตอนโดยเชื่อมโยงการกระทำ PDF เข้าด้วยกัน เหมาะสำหรับงานที่เกิดซ้ำ"
|
||||
|
||||
[home.overlay-pdfs]
|
||||
tags = "overlay,combine,merge,layer,superimpose,overlay PDF,layer PDFs,combine PDFs,stack,overlay pages,background,foreground,composite"
|
||||
desc = "ซ้อนทับ PDF บน PDF อีกไฟล์หนึ่ง"
|
||||
title = "ซ้อนทับ PDF"
|
||||
|
||||
[home.pdfTextEditor]
|
||||
tags = "edit text,modify text,change text,edit content,update text,rewrite,correct,amend,redline,revise,text editor,content editor"
|
||||
title = "แก้ไขข้อความ PDF"
|
||||
desc = "ตรวจทานและแก้ไขไฟล์ JSON ที่ส่งออกจาก Stirling PDF ด้วยการแก้ไขข้อความแบบกลุ่มและการสร้าง PDF ใหม่"
|
||||
|
||||
@@ -3553,6 +3562,31 @@ imageSize = "ขนาดรูปภาพ"
|
||||
margin = "ระยะขอบ"
|
||||
positionAndFormatting = "ตำแหน่งและการจัดรูปแบบ"
|
||||
quickPosition = "เลือกตำแหน่งบนหน้าสำหรับวางตราประทับ"
|
||||
clickToExpand = "Click to expand"
|
||||
customDateDesc = "Custom format"
|
||||
dateDesc = "Current date"
|
||||
dateTimeVars = "Date & Time"
|
||||
datetimeDesc = "Date and time combined"
|
||||
dynamicVariables = "Dynamic Variables"
|
||||
examples = "Examples"
|
||||
fileVars = "File Information"
|
||||
filenameDesc = "Filename without extension"
|
||||
filenameFullDesc = "Filename with extension"
|
||||
metadataDesc = "From PDF document properties"
|
||||
metadataVars = "Document Metadata"
|
||||
multiLine = "multi-line"
|
||||
otherVars = "Other"
|
||||
pageNumberDesc = "Current page number"
|
||||
pageVars = "Page Information"
|
||||
preview = "Preview:"
|
||||
selectTemplate = "Select a template..."
|
||||
stampTextDescription = "Use dynamic variables below. Use @@ for literal @. Use \\n for new lines."
|
||||
timeDesc = "Current time"
|
||||
totalPagesDesc = "Total number of pages"
|
||||
useTemplate = "Use Template"
|
||||
uuidDesc = "Short unique identifier (8 chars)"
|
||||
variablesHelp = "Click on any variable to insert it into your stamp text. Use @@ for literal @."
|
||||
yearMonthDayDesc = "Individual date parts"
|
||||
|
||||
[AddStampRequest.error]
|
||||
failed = "เกิดข้อผิดพลาดขณะเพิ่มตราประทับลงใน PDF"
|
||||
@@ -3560,6 +3594,14 @@ failed = "เกิดข้อผิดพลาดขณะเพิ่มต
|
||||
[AddStampRequest.results]
|
||||
title = "ผลการประทับตรา"
|
||||
|
||||
[AddStampRequest.template]
|
||||
custom = "Custom"
|
||||
dateHeader = "Date Header"
|
||||
draftWatermark = "Draft Watermark"
|
||||
europeanDate = "European Date"
|
||||
pageNumberFooter = "Page Number Footer"
|
||||
timestamp = "Timestamp"
|
||||
|
||||
[removeImagePdf]
|
||||
tags = "ลบรูปภาพ,การจัดการหน้า,แบ็กเอนด์,ฝั่งเซิร์ฟเวอร์"
|
||||
|
||||
@@ -4526,6 +4568,13 @@ description = "จำนวนครั้งสูงสุดของกา
|
||||
label = "เวลาล้างจำนวนครั้ง (นาที)"
|
||||
description = "ระยะเวลาก่อนที่จะรีเซ็ตจำนวนครั้งที่เข้าสู่ระบบล้มเหลว"
|
||||
|
||||
[admin.settings.security.xFrameOptions]
|
||||
label = "X-Frame-Options"
|
||||
description = "Controls whether the application can be embedded in iframes"
|
||||
deny = "Deny (Prevents all framing)"
|
||||
sameorigin = "Same Origin (Allow framing from same domain)"
|
||||
disabled = "Disabled (No X-Frame-Options header)"
|
||||
|
||||
[admin.settings.security.csrfDisabled]
|
||||
label = "ปิดการป้องกัน CSRF"
|
||||
description = "ปิดการป้องกัน Cross-Site Request Forgery (ไม่แนะนำ)"
|
||||
|
||||
@@ -439,7 +439,9 @@ fullscreen = "Tam ekran"
|
||||
[settings.general.updates]
|
||||
title = "Yazılım Güncellemeleri"
|
||||
description = "Güncellemeleri kontrol edin ve sürüm bilgilerini görüntüleyin"
|
||||
currentVersion = "Geçerli Sürüm"
|
||||
currentBackendVersion = "Current Backend Version"
|
||||
currentFrontendVersion = "Current Frontend Version"
|
||||
versionMismatch = "Warning: A mismatch has been detected between the client version and the AppConfig version. Using different versions can lead to compatibility issues, errors, and security risks. Please ensure that server and client are using the same version."
|
||||
latestVersion = "En Son Sürüm"
|
||||
checkForUpdates = "Güncellemeleri Kontrol Et"
|
||||
viewDetails = "Ayrıntıları Görüntüle"
|
||||
@@ -950,6 +952,7 @@ title = "Otomatik Boyut/Sayıya Böl"
|
||||
desc = "Tek bir PDF'yi boyut, sayfa sayısı veya belge sayısına göre birden fazla belgeye bölün"
|
||||
|
||||
[home.replaceColor]
|
||||
tags = "replace color,invert color,color replacement,swap colors,change color,invert,negative,color swap,find and replace color,convert color,color change"
|
||||
title = "Rengi Değiştir & Ters Çevir"
|
||||
desc = "PDF belgelerindeki renkleri değiştirin veya tersine çevirin"
|
||||
|
||||
@@ -964,18 +967,22 @@ title = "Otomatik Klasör Tarama"
|
||||
desc = "Otomatik klasör tarama kılavuzuna bağlantı"
|
||||
|
||||
[home.devSsoGuide]
|
||||
tags = "SSO,single sign-on,authentication,SAML,OAuth,OIDC,login,enterprise,identity provider,IdP"
|
||||
title = "SSO Kılavuzu"
|
||||
desc = "SSO kılavuzuna bağlantı"
|
||||
|
||||
[home.devAirgapped]
|
||||
tags = "air-gapped,offline,isolated,no internet,disconnected,secure,network isolation,standalone"
|
||||
title = "Ağdan İzole Kurulum"
|
||||
desc = "Ağdan izole kurulum kılavuzuna bağlantı"
|
||||
|
||||
[home.addPassword]
|
||||
tags = "encrypt,password,lock,secure,protect,security,encryption,safeguard,confidential,private,restrict access"
|
||||
title = "Parola Ekle"
|
||||
desc = "PDF belgenizi bir parola ile şifreleyin."
|
||||
|
||||
[home.changePermissions]
|
||||
tags = "permissions,restrictions,rights,access control,allow,deny,printing,copying,editing,modify permissions,security settings,user rights"
|
||||
title = "İzinleri Değiştir"
|
||||
desc = "Belge kısıtlamalarını ve izinleri değiştirin"
|
||||
|
||||
@@ -985,10 +992,12 @@ title = "Otomatikleştir"
|
||||
desc = "PDF eylemlerini birbirine bağlayarak çok adımlı iş akışları oluşturun. Tekrarlayan görevler için idealdir."
|
||||
|
||||
[home.overlay-pdfs]
|
||||
tags = "overlay,combine,merge,layer,superimpose,overlay PDF,layer PDFs,combine PDFs,stack,overlay pages,background,foreground,composite"
|
||||
desc = "PDF'leri başka bir PDF'nin üzerine bindirir"
|
||||
title = "PDF'leri Bindirme"
|
||||
|
||||
[home.pdfTextEditor]
|
||||
tags = "edit text,modify text,change text,edit content,update text,rewrite,correct,amend,redline,revise,text editor,content editor"
|
||||
title = "PDF Metin Düzenleyici"
|
||||
desc = "Gruplu metin düzenleme ve PDF yeniden oluşturma ile Stirling PDF JSON dışa aktarımlarını gözden geçirin ve düzenleyin"
|
||||
|
||||
@@ -3553,6 +3562,31 @@ imageSize = "Görüntü Boyutu"
|
||||
margin = "Kenar Boşluğu"
|
||||
positionAndFormatting = "Konum ve Biçimlendirme"
|
||||
quickPosition = "Damgayı yerleştirmek için sayfada bir konum seçin."
|
||||
clickToExpand = "Click to expand"
|
||||
customDateDesc = "Custom format"
|
||||
dateDesc = "Current date"
|
||||
dateTimeVars = "Date & Time"
|
||||
datetimeDesc = "Date and time combined"
|
||||
dynamicVariables = "Dynamic Variables"
|
||||
examples = "Examples"
|
||||
fileVars = "File Information"
|
||||
filenameDesc = "Filename without extension"
|
||||
filenameFullDesc = "Filename with extension"
|
||||
metadataDesc = "From PDF document properties"
|
||||
metadataVars = "Document Metadata"
|
||||
multiLine = "multi-line"
|
||||
otherVars = "Other"
|
||||
pageNumberDesc = "Current page number"
|
||||
pageVars = "Page Information"
|
||||
preview = "Preview:"
|
||||
selectTemplate = "Select a template..."
|
||||
stampTextDescription = "Use dynamic variables below. Use @@ for literal @. Use \\n for new lines."
|
||||
timeDesc = "Current time"
|
||||
totalPagesDesc = "Total number of pages"
|
||||
useTemplate = "Use Template"
|
||||
uuidDesc = "Short unique identifier (8 chars)"
|
||||
variablesHelp = "Click on any variable to insert it into your stamp text. Use @@ for literal @."
|
||||
yearMonthDayDesc = "Individual date parts"
|
||||
|
||||
[AddStampRequest.error]
|
||||
failed = "PDF'ye damga eklenirken bir hata oluştu."
|
||||
@@ -3560,6 +3594,14 @@ failed = "PDF'ye damga eklenirken bir hata oluştu."
|
||||
[AddStampRequest.results]
|
||||
title = "Damga Sonuçları"
|
||||
|
||||
[AddStampRequest.template]
|
||||
custom = "Custom"
|
||||
dateHeader = "Date Header"
|
||||
draftWatermark = "Draft Watermark"
|
||||
europeanDate = "European Date"
|
||||
pageNumberFooter = "Page Number Footer"
|
||||
timestamp = "Timestamp"
|
||||
|
||||
[removeImagePdf]
|
||||
tags = "Resmi Kaldır,Sayfa İşlemleri,Arka uç,sunucu tarafı"
|
||||
|
||||
@@ -4526,6 +4568,13 @@ description = "Hesap kilitlenmeden önceki maksimum başarısız oturum açma de
|
||||
label = "Oturum Açma Sıfırlama Süresi (dakika)"
|
||||
description = "Başarısız oturum açma denemelerinin sıfırlanacağı süre"
|
||||
|
||||
[admin.settings.security.xFrameOptions]
|
||||
label = "X-Frame-Options"
|
||||
description = "Controls whether the application can be embedded in iframes"
|
||||
deny = "Deny (Prevents all framing)"
|
||||
sameorigin = "Same Origin (Allow framing from same domain)"
|
||||
disabled = "Disabled (No X-Frame-Options header)"
|
||||
|
||||
[admin.settings.security.csrfDisabled]
|
||||
label = "CSRF Korumasını Devre Dışı Bırak"
|
||||
description = "Siteler Arası İstek Sahteciliği (CSRF) korumasını devre dışı bırak (önerilmez)"
|
||||
|
||||
@@ -439,7 +439,9 @@ fullscreen = "Повноекранний"
|
||||
[settings.general.updates]
|
||||
title = "Оновлення ПЗ"
|
||||
description = "Перевіряйте оновлення та переглядайте інформацію про версію"
|
||||
currentVersion = "Поточна версія"
|
||||
currentBackendVersion = "Current Backend Version"
|
||||
currentFrontendVersion = "Current Frontend Version"
|
||||
versionMismatch = "Warning: A mismatch has been detected between the client version and the AppConfig version. Using different versions can lead to compatibility issues, errors, and security risks. Please ensure that server and client are using the same version."
|
||||
latestVersion = "Остання версія"
|
||||
checkForUpdates = "Перевірити оновлення"
|
||||
viewDetails = "Переглянути деталі"
|
||||
@@ -950,6 +952,7 @@ title = "Автоподіл за розміром/стор."
|
||||
desc = "Розділяє один PDF на кілька документів на основі розміру, кількості сторінок або кількості документів"
|
||||
|
||||
[home.replaceColor]
|
||||
tags = "replace color,invert color,color replacement,swap colors,change color,invert,negative,color swap,find and replace color,convert color,color change"
|
||||
title = "Замінити й інвертувати колір"
|
||||
desc = "Замінювати або інвертувати кольори в PDF-документах"
|
||||
|
||||
@@ -964,18 +967,22 @@ title = "Автоматичне сканування папок"
|
||||
desc = "Посилання на посібник із автоматичного сканування папок"
|
||||
|
||||
[home.devSsoGuide]
|
||||
tags = "SSO,single sign-on,authentication,SAML,OAuth,OIDC,login,enterprise,identity provider,IdP"
|
||||
title = "Посібник з SSO"
|
||||
desc = "Посилання на посібник з SSO"
|
||||
|
||||
[home.devAirgapped]
|
||||
tags = "air-gapped,offline,isolated,no internet,disconnected,secure,network isolation,standalone"
|
||||
title = "Ізольоване розгортання"
|
||||
desc = "Посилання на посібник з налаштування ізольованого середовища"
|
||||
|
||||
[home.addPassword]
|
||||
tags = "encrypt,password,lock,secure,protect,security,encryption,safeguard,confidential,private,restrict access"
|
||||
title = "Додати пароль"
|
||||
desc = "Зашифруйте документ PDF паролем."
|
||||
|
||||
[home.changePermissions]
|
||||
tags = "permissions,restrictions,rights,access control,allow,deny,printing,copying,editing,modify permissions,security settings,user rights"
|
||||
title = "Змінити дозволи"
|
||||
desc = "Змінити обмеження та дозволи документа"
|
||||
|
||||
@@ -985,10 +992,12 @@ title = "Автоматизація"
|
||||
desc = "Створюйте багатокрокові робочі процеси, поєднуючи дії з PDF. Ідеально для повторюваних завдань."
|
||||
|
||||
[home.overlay-pdfs]
|
||||
tags = "overlay,combine,merge,layer,superimpose,overlay PDF,layer PDFs,combine PDFs,stack,overlay pages,background,foreground,composite"
|
||||
desc = "Накладення одного PDF поверх іншого PDF"
|
||||
title = "Накладення PDF"
|
||||
|
||||
[home.pdfTextEditor]
|
||||
tags = "edit text,modify text,change text,edit content,update text,rewrite,correct,amend,redline,revise,text editor,content editor"
|
||||
title = "Редактор тексту PDF"
|
||||
desc = "Переглядайте й редагуйте JSON-експорти Stirling PDF з груповим редагуванням тексту та повторною генерацією PDF"
|
||||
|
||||
@@ -3553,6 +3562,31 @@ imageSize = "Розмір зображення"
|
||||
margin = "Поле"
|
||||
positionAndFormatting = "Позиція та форматування"
|
||||
quickPosition = "Виберіть позицію на сторінці для розміщення штампа."
|
||||
clickToExpand = "Click to expand"
|
||||
customDateDesc = "Custom format"
|
||||
dateDesc = "Current date"
|
||||
dateTimeVars = "Date & Time"
|
||||
datetimeDesc = "Date and time combined"
|
||||
dynamicVariables = "Dynamic Variables"
|
||||
examples = "Examples"
|
||||
fileVars = "File Information"
|
||||
filenameDesc = "Filename without extension"
|
||||
filenameFullDesc = "Filename with extension"
|
||||
metadataDesc = "From PDF document properties"
|
||||
metadataVars = "Document Metadata"
|
||||
multiLine = "multi-line"
|
||||
otherVars = "Other"
|
||||
pageNumberDesc = "Current page number"
|
||||
pageVars = "Page Information"
|
||||
preview = "Preview:"
|
||||
selectTemplate = "Select a template..."
|
||||
stampTextDescription = "Use dynamic variables below. Use @@ for literal @. Use \\n for new lines."
|
||||
timeDesc = "Current time"
|
||||
totalPagesDesc = "Total number of pages"
|
||||
useTemplate = "Use Template"
|
||||
uuidDesc = "Short unique identifier (8 chars)"
|
||||
variablesHelp = "Click on any variable to insert it into your stamp text. Use @@ for literal @."
|
||||
yearMonthDayDesc = "Individual date parts"
|
||||
|
||||
[AddStampRequest.error]
|
||||
failed = "Під час додавання штампа до PDF сталася помилка."
|
||||
@@ -3560,6 +3594,14 @@ failed = "Під час додавання штампа до PDF сталася
|
||||
[AddStampRequest.results]
|
||||
title = "Результати додавання штампа"
|
||||
|
||||
[AddStampRequest.template]
|
||||
custom = "Custom"
|
||||
dateHeader = "Date Header"
|
||||
draftWatermark = "Draft Watermark"
|
||||
europeanDate = "European Date"
|
||||
pageNumberFooter = "Page Number Footer"
|
||||
timestamp = "Timestamp"
|
||||
|
||||
[removeImagePdf]
|
||||
tags = "видалення зображення,операції зі сторінками,серверна частина"
|
||||
|
||||
@@ -4526,6 +4568,13 @@ description = "Максимальна кількість невдалих спр
|
||||
label = "Час скидання спроб (хвилини)"
|
||||
description = "Час, після якого лічильник невдалих спроб входу скидається"
|
||||
|
||||
[admin.settings.security.xFrameOptions]
|
||||
label = "X-Frame-Options"
|
||||
description = "Controls whether the application can be embedded in iframes"
|
||||
deny = "Deny (Prevents all framing)"
|
||||
sameorigin = "Same Origin (Allow framing from same domain)"
|
||||
disabled = "Disabled (No X-Frame-Options header)"
|
||||
|
||||
[admin.settings.security.csrfDisabled]
|
||||
label = "Вимкнути захист CSRF"
|
||||
description = "Вимкнути захист від Cross-Site Request Forgery (не рекомендовано)"
|
||||
|
||||
@@ -439,7 +439,9 @@ fullscreen = "Toàn màn hình"
|
||||
[settings.general.updates]
|
||||
title = "Cập nhật phần mềm"
|
||||
description = "Kiểm tra cập nhật và xem thông tin phiên bản"
|
||||
currentVersion = "Phiên bản hiện tại"
|
||||
currentBackendVersion = "Current Backend Version"
|
||||
currentFrontendVersion = "Current Frontend Version"
|
||||
versionMismatch = "Warning: A mismatch has been detected between the client version and the AppConfig version. Using different versions can lead to compatibility issues, errors, and security risks. Please ensure that server and client are using the same version."
|
||||
latestVersion = "Phiên bản mới nhất"
|
||||
checkForUpdates = "Kiểm tra cập nhật"
|
||||
viewDetails = "Xem chi tiết"
|
||||
@@ -950,6 +952,7 @@ title = "Tự động chia theo kích thước/số lượng"
|
||||
desc = "Chia một tệp PDF thành nhiều tài liệu dựa trên kích thước, số trang hoặc số lượng tài liệu"
|
||||
|
||||
[home.replaceColor]
|
||||
tags = "replace color,invert color,color replacement,swap colors,change color,invert,negative,color swap,find and replace color,convert color,color change"
|
||||
title = "Thay thế & Đảo ngược Màu"
|
||||
desc = "Thay thế hoặc đảo ngược màu trong tài liệu PDF"
|
||||
|
||||
@@ -964,18 +967,22 @@ title = "Quét thư mục tự động"
|
||||
desc = "Liên kết tới hướng dẫn quét thư mục tự động"
|
||||
|
||||
[home.devSsoGuide]
|
||||
tags = "SSO,single sign-on,authentication,SAML,OAuth,OIDC,login,enterprise,identity provider,IdP"
|
||||
title = "Hướng dẫn SSO"
|
||||
desc = "Liên kết tới hướng dẫn SSO"
|
||||
|
||||
[home.devAirgapped]
|
||||
tags = "air-gapped,offline,isolated,no internet,disconnected,secure,network isolation,standalone"
|
||||
title = "Thiết lập cách ly mạng"
|
||||
desc = "Liên kết tới hướng dẫn thiết lập cách ly mạng"
|
||||
|
||||
[home.addPassword]
|
||||
tags = "encrypt,password,lock,secure,protect,security,encryption,safeguard,confidential,private,restrict access"
|
||||
title = "Thêm mật khẩu"
|
||||
desc = "Mã hóa tài liệu PDF của bạn bằng mật khẩu."
|
||||
|
||||
[home.changePermissions]
|
||||
tags = "permissions,restrictions,rights,access control,allow,deny,printing,copying,editing,modify permissions,security settings,user rights"
|
||||
title = "Thay đổi quyền"
|
||||
desc = "Thay đổi hạn chế và quyền của tài liệu"
|
||||
|
||||
@@ -985,10 +992,12 @@ title = "Tự động hóa"
|
||||
desc = "Xây dựng quy trình nhiều bước bằng cách xâu chuỗi các thao tác PDF. Lý tưởng cho các tác vụ lặp lại."
|
||||
|
||||
[home.overlay-pdfs]
|
||||
tags = "overlay,combine,merge,layer,superimpose,overlay PDF,layer PDFs,combine PDFs,stack,overlay pages,background,foreground,composite"
|
||||
desc = "Chồng lớp PDF lên trên PDF khác"
|
||||
title = "Chồng lớp PDF"
|
||||
|
||||
[home.pdfTextEditor]
|
||||
tags = "edit text,modify text,change text,edit content,update text,rewrite,correct,amend,redline,revise,text editor,content editor"
|
||||
title = "Trình chỉnh sửa văn bản PDF"
|
||||
desc = "Xem và chỉnh sửa xuất JSON của Stirling PDF với chỉnh sửa văn bản theo nhóm và tái tạo PDF"
|
||||
|
||||
@@ -3553,6 +3562,31 @@ imageSize = "Kích thước ảnh"
|
||||
margin = "Lề"
|
||||
positionAndFormatting = "Vị trí & định dạng"
|
||||
quickPosition = "Chọn một vị trí trên trang để đặt con dấu."
|
||||
clickToExpand = "Click to expand"
|
||||
customDateDesc = "Custom format"
|
||||
dateDesc = "Current date"
|
||||
dateTimeVars = "Date & Time"
|
||||
datetimeDesc = "Date and time combined"
|
||||
dynamicVariables = "Dynamic Variables"
|
||||
examples = "Examples"
|
||||
fileVars = "File Information"
|
||||
filenameDesc = "Filename without extension"
|
||||
filenameFullDesc = "Filename with extension"
|
||||
metadataDesc = "From PDF document properties"
|
||||
metadataVars = "Document Metadata"
|
||||
multiLine = "multi-line"
|
||||
otherVars = "Other"
|
||||
pageNumberDesc = "Current page number"
|
||||
pageVars = "Page Information"
|
||||
preview = "Preview:"
|
||||
selectTemplate = "Select a template..."
|
||||
stampTextDescription = "Use dynamic variables below. Use @@ for literal @. Use \\n for new lines."
|
||||
timeDesc = "Current time"
|
||||
totalPagesDesc = "Total number of pages"
|
||||
useTemplate = "Use Template"
|
||||
uuidDesc = "Short unique identifier (8 chars)"
|
||||
variablesHelp = "Click on any variable to insert it into your stamp text. Use @@ for literal @."
|
||||
yearMonthDayDesc = "Individual date parts"
|
||||
|
||||
[AddStampRequest.error]
|
||||
failed = "Đã xảy ra lỗi khi thêm con dấu vào PDF."
|
||||
@@ -3560,6 +3594,14 @@ failed = "Đã xảy ra lỗi khi thêm con dấu vào PDF."
|
||||
[AddStampRequest.results]
|
||||
title = "Kết quả đóng dấu"
|
||||
|
||||
[AddStampRequest.template]
|
||||
custom = "Custom"
|
||||
dateHeader = "Date Header"
|
||||
draftWatermark = "Draft Watermark"
|
||||
europeanDate = "European Date"
|
||||
pageNumberFooter = "Page Number Footer"
|
||||
timestamp = "Timestamp"
|
||||
|
||||
[removeImagePdf]
|
||||
tags = "Xóa ảnh,Thao tác trang,Back end,phía máy chủ"
|
||||
|
||||
@@ -4526,6 +4568,13 @@ description = "Số lần đăng nhập thất bại tối đa trước khi khó
|
||||
label = "Thời gian đặt lại đăng nhập (phút)"
|
||||
description = "Thời gian trước khi đặt lại số lần đăng nhập thất bại"
|
||||
|
||||
[admin.settings.security.xFrameOptions]
|
||||
label = "X-Frame-Options"
|
||||
description = "Controls whether the application can be embedded in iframes"
|
||||
deny = "Deny (Prevents all framing)"
|
||||
sameorigin = "Same Origin (Allow framing from same domain)"
|
||||
disabled = "Disabled (No X-Frame-Options header)"
|
||||
|
||||
[admin.settings.security.csrfDisabled]
|
||||
label = "Tắt bảo vệ CSRF"
|
||||
description = "Tắt bảo vệ Cross-Site Request Forgery (không khuyến nghị)"
|
||||
|
||||
@@ -439,7 +439,9 @@ fullscreen = "全屏"
|
||||
[settings.general.updates]
|
||||
title = "软件更新"
|
||||
description = "检查更新并查看版本信息"
|
||||
currentVersion = "当前版本"
|
||||
currentBackendVersion = "Current Backend Version"
|
||||
currentFrontendVersion = "Current Frontend Version"
|
||||
versionMismatch = "Warning: A mismatch has been detected between the client version and the AppConfig version. Using different versions can lead to compatibility issues, errors, and security risks. Please ensure that server and client are using the same version."
|
||||
latestVersion = "最新版本"
|
||||
checkForUpdates = "检查更新"
|
||||
viewDetails = "查看详情"
|
||||
@@ -950,6 +952,7 @@ title = "按大小/页数自动拆分"
|
||||
desc = "按文件大小或页数自动拆分 PDF"
|
||||
|
||||
[home.replaceColor]
|
||||
tags = "replace color,invert color,color replacement,swap colors,change color,invert,negative,color swap,find and replace color,convert color,color change"
|
||||
title = "替换与反转颜色"
|
||||
desc = "替换或反转 PDF 文档中的颜色"
|
||||
|
||||
@@ -964,18 +967,22 @@ title = "自动化文件夹扫描"
|
||||
desc = "链接到自动化文件夹扫描指南"
|
||||
|
||||
[home.devSsoGuide]
|
||||
tags = "SSO,single sign-on,authentication,SAML,OAuth,OIDC,login,enterprise,identity provider,IdP"
|
||||
title = "SSO 指南"
|
||||
desc = "链接到 SSO 指南"
|
||||
|
||||
[home.devAirgapped]
|
||||
tags = "air-gapped,offline,isolated,no internet,disconnected,secure,network isolation,standalone"
|
||||
title = "离线隔离部署"
|
||||
desc = "链接到离线隔离部署指南"
|
||||
|
||||
[home.addPassword]
|
||||
tags = "encrypt,password,lock,secure,protect,security,encryption,safeguard,confidential,private,restrict access"
|
||||
title = "གསང་ཚིག་སྣོན་པ།"
|
||||
desc = "PDF ཡིག་ཆར་གསང་ཚིག་གིས་གསང་སྡོམ་བྱེད་པ།"
|
||||
|
||||
[home.changePermissions]
|
||||
tags = "permissions,restrictions,rights,access control,allow,deny,printing,copying,editing,modify permissions,security settings,user rights"
|
||||
title = "更改权限"
|
||||
desc = "更改文档限制与权限"
|
||||
|
||||
@@ -985,10 +992,12 @@ title = "自动化"
|
||||
desc = "通过串联 PDF 动作构建多步工作流。适合重复性任务。"
|
||||
|
||||
[home.overlay-pdfs]
|
||||
tags = "overlay,combine,merge,layer,superimpose,overlay PDF,layer PDFs,combine PDFs,stack,overlay pages,background,foreground,composite"
|
||||
desc = "PDF གཞན་ཞིག་གི་སྟེང་དུ་ PDF བརྩེགས་པ།"
|
||||
title = "PDF སྟེང་བརྩེགས།"
|
||||
|
||||
[home.pdfTextEditor]
|
||||
tags = "edit text,modify text,change text,edit content,update text,rewrite,correct,amend,redline,revise,text editor,content editor"
|
||||
title = "PDF 文本编辑器"
|
||||
desc = "审阅并编辑 Stirling PDF 的 JSON 导出,支持分组文本编辑与 PDF 再生成"
|
||||
|
||||
@@ -3553,6 +3562,31 @@ imageSize = "图像大小"
|
||||
margin = "边距"
|
||||
positionAndFormatting = "位置与格式"
|
||||
quickPosition = "选择页面上的位置以放置印章。"
|
||||
clickToExpand = "Click to expand"
|
||||
customDateDesc = "Custom format"
|
||||
dateDesc = "Current date"
|
||||
dateTimeVars = "Date & Time"
|
||||
datetimeDesc = "Date and time combined"
|
||||
dynamicVariables = "Dynamic Variables"
|
||||
examples = "Examples"
|
||||
fileVars = "File Information"
|
||||
filenameDesc = "Filename without extension"
|
||||
filenameFullDesc = "Filename with extension"
|
||||
metadataDesc = "From PDF document properties"
|
||||
metadataVars = "Document Metadata"
|
||||
multiLine = "multi-line"
|
||||
otherVars = "Other"
|
||||
pageNumberDesc = "Current page number"
|
||||
pageVars = "Page Information"
|
||||
preview = "Preview:"
|
||||
selectTemplate = "Select a template..."
|
||||
stampTextDescription = "Use dynamic variables below. Use @@ for literal @. Use \\n for new lines."
|
||||
timeDesc = "Current time"
|
||||
totalPagesDesc = "Total number of pages"
|
||||
useTemplate = "Use Template"
|
||||
uuidDesc = "Short unique identifier (8 chars)"
|
||||
variablesHelp = "Click on any variable to insert it into your stamp text. Use @@ for literal @."
|
||||
yearMonthDayDesc = "Individual date parts"
|
||||
|
||||
[AddStampRequest.error]
|
||||
failed = "将印章添加到 PDF 时发生错误。"
|
||||
@@ -3560,6 +3594,14 @@ failed = "将印章添加到 PDF 时发生错误。"
|
||||
[AddStampRequest.results]
|
||||
title = "印章结果"
|
||||
|
||||
[AddStampRequest.template]
|
||||
custom = "Custom"
|
||||
dateHeader = "Date Header"
|
||||
draftWatermark = "Draft Watermark"
|
||||
europeanDate = "European Date"
|
||||
pageNumberFooter = "Page Number Footer"
|
||||
timestamp = "Timestamp"
|
||||
|
||||
[removeImagePdf]
|
||||
tags = "པར་རིས་སུབ་པ།,ཤོག་ངོས་བཀོལ་སྤྱོད།,རྒྱབ་ངོས།,ཞབས་ཞུ་ཕྱོགས།"
|
||||
|
||||
@@ -4526,6 +4568,13 @@ description = "在账户锁定前允许的最大失败登录次数"
|
||||
label = "登录重置时间(分钟)"
|
||||
description = "失败登录尝试被重置前的时间"
|
||||
|
||||
[admin.settings.security.xFrameOptions]
|
||||
label = "X-Frame-Options"
|
||||
description = "Controls whether the application can be embedded in iframes"
|
||||
deny = "Deny (Prevents all framing)"
|
||||
sameorigin = "Same Origin (Allow framing from same domain)"
|
||||
disabled = "Disabled (No X-Frame-Options header)"
|
||||
|
||||
[admin.settings.security.csrfDisabled]
|
||||
label = "禁用 CSRF 保护"
|
||||
description = "禁用跨站请求伪造保护(不推荐)"
|
||||
|
||||
@@ -439,7 +439,9 @@ fullscreen = "全屏"
|
||||
[settings.general.updates]
|
||||
title = "软件更新"
|
||||
description = "检查更新并查看版本信息"
|
||||
currentVersion = "当前版本"
|
||||
currentBackendVersion = "Current Backend Version"
|
||||
currentFrontendVersion = "Current Frontend Version"
|
||||
versionMismatch = "Warning: A mismatch has been detected between the client version and the AppConfig version. Using different versions can lead to compatibility issues, errors, and security risks. Please ensure that server and client are using the same version."
|
||||
latestVersion = "最新版本"
|
||||
checkForUpdates = "检查更新"
|
||||
viewDetails = "查看详情"
|
||||
@@ -950,6 +952,7 @@ title = "自动根据大小/数目拆分 PDF"
|
||||
desc = "将单个 PDF 拆分为多个文档,基于大小、页数或文档数"
|
||||
|
||||
[home.replaceColor]
|
||||
tags = "replace color,invert color,color replacement,swap colors,change color,invert,negative,color swap,find and replace color,convert color,color change"
|
||||
title = "替换和反转颜色"
|
||||
desc = "替换或反转 PDF 文档中的颜色"
|
||||
|
||||
@@ -964,18 +967,22 @@ title = "自动文件夹扫描"
|
||||
desc = "跳转至自动文件夹扫描指南"
|
||||
|
||||
[home.devSsoGuide]
|
||||
tags = "SSO,single sign-on,authentication,SAML,OAuth,OIDC,login,enterprise,identity provider,IdP"
|
||||
title = "SSO 指南"
|
||||
desc = "跳转至 SSO 指南"
|
||||
|
||||
[home.devAirgapped]
|
||||
tags = "air-gapped,offline,isolated,no internet,disconnected,secure,network isolation,standalone"
|
||||
title = "离线/隔离部署"
|
||||
desc = "跳转至隔离部署指南"
|
||||
|
||||
[home.addPassword]
|
||||
tags = "encrypt,password,lock,secure,protect,security,encryption,safeguard,confidential,private,restrict access"
|
||||
title = "添加密码"
|
||||
desc = "使用密码对 PDF 文档进行加密。"
|
||||
|
||||
[home.changePermissions]
|
||||
tags = "permissions,restrictions,rights,access control,allow,deny,printing,copying,editing,modify permissions,security settings,user rights"
|
||||
title = "更改权限"
|
||||
desc = "更改文档限制与权限"
|
||||
|
||||
@@ -985,10 +992,12 @@ title = "自动化"
|
||||
desc = "通过串联 PDF 操作构建多步工作流。适合重复性任务。"
|
||||
|
||||
[home.overlay-pdfs]
|
||||
tags = "overlay,combine,merge,layer,superimpose,overlay PDF,layer PDFs,combine PDFs,stack,overlay pages,background,foreground,composite"
|
||||
desc = "将一个 PDF 叠加在另一个之上"
|
||||
title = "叠加 PDF"
|
||||
|
||||
[home.pdfTextEditor]
|
||||
tags = "edit text,modify text,change text,edit content,update text,rewrite,correct,amend,redline,revise,text editor,content editor"
|
||||
title = "PDF 文本编辑器"
|
||||
desc = "审阅并编辑 Stirling PDF 导出的 JSON,支持分组文本编辑并重新生成 PDF"
|
||||
|
||||
@@ -3553,6 +3562,31 @@ imageSize = "图像大小"
|
||||
margin = "边距"
|
||||
positionAndFormatting = "位置与格式"
|
||||
quickPosition = "选择页面上的一个位置以放置图章。"
|
||||
clickToExpand = "Click to expand"
|
||||
customDateDesc = "Custom format"
|
||||
dateDesc = "Current date"
|
||||
dateTimeVars = "Date & Time"
|
||||
datetimeDesc = "Date and time combined"
|
||||
dynamicVariables = "Dynamic Variables"
|
||||
examples = "Examples"
|
||||
fileVars = "File Information"
|
||||
filenameDesc = "Filename without extension"
|
||||
filenameFullDesc = "Filename with extension"
|
||||
metadataDesc = "From PDF document properties"
|
||||
metadataVars = "Document Metadata"
|
||||
multiLine = "multi-line"
|
||||
otherVars = "Other"
|
||||
pageNumberDesc = "Current page number"
|
||||
pageVars = "Page Information"
|
||||
preview = "Preview:"
|
||||
selectTemplate = "Select a template..."
|
||||
stampTextDescription = "Use dynamic variables below. Use @@ for literal @. Use \\n for new lines."
|
||||
timeDesc = "Current time"
|
||||
totalPagesDesc = "Total number of pages"
|
||||
useTemplate = "Use Template"
|
||||
uuidDesc = "Short unique identifier (8 chars)"
|
||||
variablesHelp = "Click on any variable to insert it into your stamp text. Use @@ for literal @."
|
||||
yearMonthDayDesc = "Individual date parts"
|
||||
|
||||
[AddStampRequest.error]
|
||||
failed = "向 PDF 添加图章时发生错误。"
|
||||
@@ -3560,6 +3594,14 @@ failed = "向 PDF 添加图章时发生错误。"
|
||||
[AddStampRequest.results]
|
||||
title = "图章结果"
|
||||
|
||||
[AddStampRequest.template]
|
||||
custom = "Custom"
|
||||
dateHeader = "Date Header"
|
||||
draftWatermark = "Draft Watermark"
|
||||
europeanDate = "European Date"
|
||||
pageNumberFooter = "Page Number Footer"
|
||||
timestamp = "Timestamp"
|
||||
|
||||
[removeImagePdf]
|
||||
tags = "删除图像, 页面操作, 后端, 服务端"
|
||||
|
||||
@@ -4526,6 +4568,13 @@ description = "达到该失败次数后将锁定账户"
|
||||
label = "登录重置时间(分钟)"
|
||||
description = "重置失败尝试计数的时间"
|
||||
|
||||
[admin.settings.security.xFrameOptions]
|
||||
label = "X-Frame-Options"
|
||||
description = "Controls whether the application can be embedded in iframes"
|
||||
deny = "Deny (Prevents all framing)"
|
||||
sameorigin = "Same Origin (Allow framing from same domain)"
|
||||
disabled = "Disabled (No X-Frame-Options header)"
|
||||
|
||||
[admin.settings.security.csrfDisabled]
|
||||
label = "禁用CSRF保护"
|
||||
description = "禁用跨站请求伪造保护(不建议)"
|
||||
|
||||
@@ -439,7 +439,9 @@ fullscreen = "全螢幕"
|
||||
[settings.general.updates]
|
||||
title = "軟體更新"
|
||||
description = "檢查更新並檢視版本資訊"
|
||||
currentVersion = "目前版本"
|
||||
currentBackendVersion = "Current Backend Version"
|
||||
currentFrontendVersion = "Current Frontend Version"
|
||||
versionMismatch = "Warning: A mismatch has been detected between the client version and the AppConfig version. Using different versions can lead to compatibility issues, errors, and security risks. Please ensure that server and client are using the same version."
|
||||
latestVersion = "最新版本"
|
||||
checkForUpdates = "檢查更新"
|
||||
viewDetails = "檢視詳細資料"
|
||||
@@ -950,6 +952,7 @@ title = "根據大小/數量自動分割"
|
||||
desc = "根據大小、頁數或文件數將單一 PDF 分割為多個文件"
|
||||
|
||||
[home.replaceColor]
|
||||
tags = "replace color,invert color,color replacement,swap colors,change color,invert,negative,color swap,find and replace color,convert color,color change"
|
||||
title = "取代與反轉顏色"
|
||||
desc = "在 PDF 文件中取代或反轉顏色"
|
||||
|
||||
@@ -964,18 +967,22 @@ title = "自動化資料夾掃描"
|
||||
desc = "連結至自動化資料夾掃描指南"
|
||||
|
||||
[home.devSsoGuide]
|
||||
tags = "SSO,single sign-on,authentication,SAML,OAuth,OIDC,login,enterprise,identity provider,IdP"
|
||||
title = "SSO 指南"
|
||||
desc = "連結至 SSO 指南"
|
||||
|
||||
[home.devAirgapped]
|
||||
tags = "air-gapped,offline,isolated,no internet,disconnected,secure,network isolation,standalone"
|
||||
title = "隔離網路設定"
|
||||
desc = "連結至隔離網路設定指南"
|
||||
|
||||
[home.addPassword]
|
||||
tags = "encrypt,password,lock,secure,protect,security,encryption,safeguard,confidential,private,restrict access"
|
||||
title = "新增密碼"
|
||||
desc = "用密碼加密您的 PDF 檔案。"
|
||||
|
||||
[home.changePermissions]
|
||||
tags = "permissions,restrictions,rights,access control,allow,deny,printing,copying,editing,modify permissions,security settings,user rights"
|
||||
title = "變更權限"
|
||||
desc = "變更文件限制與權限"
|
||||
|
||||
@@ -985,10 +992,12 @@ title = "自動化"
|
||||
desc = "將多個 PDF 動作串接,建立多步驟工作流程。適合重複性工作。"
|
||||
|
||||
[home.overlay-pdfs]
|
||||
tags = "overlay,combine,merge,layer,superimpose,overlay PDF,layer PDFs,combine PDFs,stack,overlay pages,background,foreground,composite"
|
||||
desc = "將 PDF 覆蓋在另一個 PDF 上"
|
||||
title = "覆蓋 PDF"
|
||||
|
||||
[home.pdfTextEditor]
|
||||
tags = "edit text,modify text,change text,edit content,update text,rewrite,correct,amend,redline,revise,text editor,content editor"
|
||||
title = "PDF 文字編輯器"
|
||||
desc = "檢視與編輯 Stirling PDF 的 JSON 匯出,支援群組文字編輯與重新產生 PDF"
|
||||
|
||||
@@ -3553,6 +3562,31 @@ imageSize = "影像大小"
|
||||
margin = "邊距"
|
||||
positionAndFormatting = "位置與格式"
|
||||
quickPosition = "選擇頁面上的位置以放置印章。"
|
||||
clickToExpand = "Click to expand"
|
||||
customDateDesc = "Custom format"
|
||||
dateDesc = "Current date"
|
||||
dateTimeVars = "Date & Time"
|
||||
datetimeDesc = "Date and time combined"
|
||||
dynamicVariables = "Dynamic Variables"
|
||||
examples = "Examples"
|
||||
fileVars = "File Information"
|
||||
filenameDesc = "Filename without extension"
|
||||
filenameFullDesc = "Filename with extension"
|
||||
metadataDesc = "From PDF document properties"
|
||||
metadataVars = "Document Metadata"
|
||||
multiLine = "multi-line"
|
||||
otherVars = "Other"
|
||||
pageNumberDesc = "Current page number"
|
||||
pageVars = "Page Information"
|
||||
preview = "Preview:"
|
||||
selectTemplate = "Select a template..."
|
||||
stampTextDescription = "Use dynamic variables below. Use @@ for literal @. Use \\n for new lines."
|
||||
timeDesc = "Current time"
|
||||
totalPagesDesc = "Total number of pages"
|
||||
useTemplate = "Use Template"
|
||||
uuidDesc = "Short unique identifier (8 chars)"
|
||||
variablesHelp = "Click on any variable to insert it into your stamp text. Use @@ for literal @."
|
||||
yearMonthDayDesc = "Individual date parts"
|
||||
|
||||
[AddStampRequest.error]
|
||||
failed = "將印章加入 PDF 時發生錯誤。"
|
||||
@@ -3560,6 +3594,14 @@ failed = "將印章加入 PDF 時發生錯誤。"
|
||||
[AddStampRequest.results]
|
||||
title = "蓋章結果"
|
||||
|
||||
[AddStampRequest.template]
|
||||
custom = "Custom"
|
||||
dateHeader = "Date Header"
|
||||
draftWatermark = "Draft Watermark"
|
||||
europeanDate = "European Date"
|
||||
pageNumberFooter = "Page Number Footer"
|
||||
timestamp = "Timestamp"
|
||||
|
||||
[removeImagePdf]
|
||||
tags = "移除圖片,頁面操作,後端,伺服器端"
|
||||
|
||||
@@ -4526,6 +4568,13 @@ description = "帳戶被鎖定前允許的最大登入失敗次數"
|
||||
label = "登入重設時間(分鐘)"
|
||||
description = "登入失敗次數重設所需的時間"
|
||||
|
||||
[admin.settings.security.xFrameOptions]
|
||||
label = "X-Frame-Options"
|
||||
description = "Controls whether the application can be embedded in iframes"
|
||||
deny = "Deny (Prevents all framing)"
|
||||
sameorigin = "Same Origin (Allow framing from same domain)"
|
||||
disabled = "Disabled (No X-Frame-Options header)"
|
||||
|
||||
[admin.settings.security.csrfDisabled]
|
||||
label = "停用 CSRF 保護"
|
||||
description = "停用跨站請求偽造保護(不建議)"
|
||||
|
||||
Generated
+601
-685
File diff suppressed because it is too large
Load Diff
@@ -18,24 +18,24 @@ name = "app_lib"
|
||||
crate-type = ["staticlib", "cdylib", "rlib"]
|
||||
|
||||
[build-dependencies]
|
||||
tauri-build = { version = "2.2.0", features = [] }
|
||||
tauri-build = { version = "2.5.3", features = [] }
|
||||
|
||||
[dependencies]
|
||||
serde_json = "1.0"
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
log = "0.4"
|
||||
tauri = { version = "2.9.0", features = [ "devtools"] }
|
||||
tauri-plugin-log = "2.0.0-rc"
|
||||
tauri-plugin-shell = "2.1.0"
|
||||
tauri-plugin-fs = "2.4.4"
|
||||
tauri-plugin-http = { version = "2.4.4", features = ["dangerous-settings"] }
|
||||
tauri-plugin-single-instance = { version = "2.3.6", features = ["deep-link"] }
|
||||
tauri-plugin-store = "2.1.0"
|
||||
tauri-plugin-opener = "2.0.0"
|
||||
tauri-plugin-deep-link = "2.4.5"
|
||||
tauri-plugin-log = "2.8.0"
|
||||
tauri-plugin-shell = "2.3.4"
|
||||
tauri-plugin-fs = "2.4.5"
|
||||
tauri-plugin-http = { version = "2.5.6", features = ["dangerous-settings"] }
|
||||
tauri-plugin-single-instance = { version = "2.3.7", features = ["deep-link"] }
|
||||
tauri-plugin-store = "2.4.2"
|
||||
tauri-plugin-opener = "2.5.3"
|
||||
tauri-plugin-deep-link = "2.4.6"
|
||||
keyring = { version = "3.6.1", features = ["apple-native", "windows-native"] }
|
||||
tokio = { version = "1.0", features = ["time", "sync"] }
|
||||
reqwest = { version = "0.11", features = ["json"] }
|
||||
reqwest = { version = "0.11", default-features = false, features = ["json", "rustls-tls", "rustls-tls-native-roots"] }
|
||||
tiny_http = "0.12"
|
||||
url = "2.5"
|
||||
urlencoding = "2.1"
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<!-- Enable printing capability -->
|
||||
<key>com.apple.security.print</key>
|
||||
<true/>
|
||||
|
||||
<!-- Enable network access for connecting to backend -->
|
||||
<key>com.apple.security.network.client</key>
|
||||
<true/>
|
||||
<key>com.apple.security.network.server</key>
|
||||
<true/>
|
||||
|
||||
<!-- Enable file access for PDF handling -->
|
||||
<key>com.apple.security.files.user-selected.read-write</key>
|
||||
<true/>
|
||||
|
||||
<!-- Allow execution of bundled JRE -->
|
||||
<key>com.apple.security.cs.allow-jit</key>
|
||||
<true/>
|
||||
<key>com.apple.security.cs.allow-unsigned-executable-memory</key>
|
||||
<true/>
|
||||
<key>com.apple.security.cs.disable-library-validation</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -11,8 +11,11 @@ use rand::distributions::Alphanumeric;
|
||||
|
||||
const STORE_FILE: &str = "connection.json";
|
||||
const USER_INFO_KEY: &str = "user_info";
|
||||
const TOKENS_STORE_FILE: &str = "tokens.json";
|
||||
const REFRESH_TOKEN_STORE_KEY: &str = "refresh_token";
|
||||
const KEYRING_SERVICE: &str = "stirling-pdf";
|
||||
const KEYRING_TOKEN_KEY: &str = "auth-token";
|
||||
const KEYRING_REFRESH_TOKEN_KEY: &str = "refresh-token";
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize, Clone)]
|
||||
pub struct UserInfo {
|
||||
@@ -31,6 +34,11 @@ fn get_keyring_entry() -> Result<Entry, String> {
|
||||
Ok(entry)
|
||||
}
|
||||
|
||||
fn get_refresh_token_keyring_entry() -> Result<Entry, String> {
|
||||
Entry::new(KEYRING_SERVICE, KEYRING_REFRESH_TOKEN_KEY)
|
||||
.map_err(|e| format!("Failed to access keyring: {}", e))
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub async fn save_auth_token(_app_handle: AppHandle, token: String) -> Result<(), String> {
|
||||
let trimmed = token.trim();
|
||||
@@ -101,6 +109,112 @@ pub async fn clear_auth_token(_app_handle: AppHandle) -> Result<(), String> {
|
||||
}
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub async fn save_refresh_token(app_handle: AppHandle, token: String) -> Result<(), String> {
|
||||
log::info!("Saving refresh token - trying keyring first");
|
||||
|
||||
let entry = get_refresh_token_keyring_entry()?;
|
||||
|
||||
// Try keyring (works in production with code signing)
|
||||
match entry.set_password(&token) {
|
||||
Ok(_) => {
|
||||
// Verify it persists (fails in unsigned dev builds)
|
||||
match entry.get_password() {
|
||||
Ok(saved) if saved == token => {
|
||||
log::info!("✅ Refresh token saved to keyring (production mode)");
|
||||
return Ok(());
|
||||
}
|
||||
_ => {
|
||||
log::info!("Keyring doesn't persist - using Tauri Store fallback (dev mode)");
|
||||
}
|
||||
}
|
||||
}
|
||||
Err(e) => {
|
||||
log::info!("Keyring failed: {} - using Tauri Store fallback", e);
|
||||
}
|
||||
}
|
||||
|
||||
// Fallback to Tauri Store (dev mode without code signing)
|
||||
let store = app_handle
|
||||
.store(TOKENS_STORE_FILE)
|
||||
.map_err(|e| format!("Failed to access tokens store: {}", e))?;
|
||||
|
||||
store.set(
|
||||
REFRESH_TOKEN_STORE_KEY,
|
||||
serde_json::to_value(&token)
|
||||
.map_err(|e| format!("Failed to serialize token: {}", e))?,
|
||||
);
|
||||
|
||||
store
|
||||
.save()
|
||||
.map_err(|e| format!("Failed to save tokens store: {}", e))?;
|
||||
|
||||
log::info!("✅ Refresh token saved to Tauri Store (fallback)");
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub async fn get_refresh_token(app_handle: AppHandle) -> Result<Option<String>, String> {
|
||||
// Try keyring first (production)
|
||||
let entry = get_refresh_token_keyring_entry()?;
|
||||
match entry.get_password() {
|
||||
Ok(token) => {
|
||||
log::info!("✅ Refresh token retrieved from keyring");
|
||||
return Ok(Some(token));
|
||||
}
|
||||
Err(keyring::Error::NoEntry) => {
|
||||
log::debug!("No token in keyring, trying Tauri Store");
|
||||
}
|
||||
Err(e) => {
|
||||
log::warn!("Keyring error: {} - trying Tauri Store", e);
|
||||
}
|
||||
}
|
||||
|
||||
// Fallback to Tauri Store (dev)
|
||||
let store = app_handle
|
||||
.store(TOKENS_STORE_FILE)
|
||||
.map_err(|e| format!("Failed to access tokens store: {}", e))?;
|
||||
|
||||
let token: Option<String> = store
|
||||
.get(REFRESH_TOKEN_STORE_KEY)
|
||||
.and_then(|v| serde_json::from_value(v.clone()).ok());
|
||||
|
||||
if token.is_some() {
|
||||
log::info!("✅ Refresh token retrieved from Tauri Store");
|
||||
} else {
|
||||
log::info!("No refresh token found");
|
||||
}
|
||||
|
||||
Ok(token)
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub async fn clear_refresh_token(app_handle: AppHandle) -> Result<(), String> {
|
||||
log::info!("Clearing refresh token from all storage");
|
||||
|
||||
// Clear from keyring
|
||||
let entry = get_refresh_token_keyring_entry()?;
|
||||
match entry.delete_credential() {
|
||||
Ok(_) => log::info!("Cleared from keyring"),
|
||||
Err(keyring::Error::NoEntry) => log::debug!("Not in keyring"),
|
||||
Err(e) => log::warn!("Keyring clear error: {}", e),
|
||||
}
|
||||
|
||||
// Clear from Tauri Store
|
||||
let store = app_handle
|
||||
.store(TOKENS_STORE_FILE)
|
||||
.map_err(|e| format!("Failed to access tokens store: {}", e))?;
|
||||
|
||||
store.delete(REFRESH_TOKEN_STORE_KEY);
|
||||
|
||||
store
|
||||
.save()
|
||||
.map_err(|e| format!("Failed to save tokens store: {}", e))?;
|
||||
|
||||
log::info!("✅ Refresh token cleared");
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub async fn save_user_info(
|
||||
app_handle: AppHandle,
|
||||
@@ -213,8 +327,20 @@ pub async fn login(
|
||||
// Detect if this is Supabase (SaaS) or Spring Boot (self-hosted)
|
||||
let is_supabase = server_url.trim_end_matches('/') == saas_server_url.trim_end_matches('/');
|
||||
|
||||
// Create HTTP client
|
||||
let client = reqwest::Client::new();
|
||||
// Create HTTP client with certificate bypass
|
||||
// This handles:
|
||||
// - Self-signed certificates
|
||||
// - Missing intermediate certificates
|
||||
// - Certificate hostname mismatches
|
||||
// Note: Rustls only supports TLS 1.2 and TLS 1.3
|
||||
let client = reqwest::Client::builder()
|
||||
.danger_accept_invalid_certs(true)
|
||||
.timeout(std::time::Duration::from_secs(30))
|
||||
.build()
|
||||
.map_err(|e| {
|
||||
log::error!("Failed to create HTTP client: {}", e);
|
||||
format!("Failed to create HTTP client: {}", e)
|
||||
})?;
|
||||
|
||||
if is_supabase {
|
||||
// Supabase authentication flow
|
||||
@@ -235,7 +361,24 @@ pub async fn login(
|
||||
.json(&request_body)
|
||||
.send()
|
||||
.await
|
||||
.map_err(|e| format!("Network error: {}", e))?;
|
||||
.map_err(|e| {
|
||||
let error_msg = e.to_string();
|
||||
let error_lower = error_msg.to_lowercase();
|
||||
log::error!("Supabase login network error: {}", e);
|
||||
|
||||
// Detect TLS version mismatch
|
||||
if error_lower.contains("peer is incompatible") ||
|
||||
error_lower.contains("protocol version") ||
|
||||
error_lower.contains("peerincompatible") ||
|
||||
(error_lower.contains("handshake") && (error_lower.contains("tls") || error_lower.contains("ssl"))) {
|
||||
format!(
|
||||
"TLS version not supported: The Supabase server appears to require an unsupported TLS version. \
|
||||
Please contact support. Technical details: {}", e
|
||||
)
|
||||
} else {
|
||||
format!("Network error connecting to Supabase: {}", e)
|
||||
}
|
||||
})?;
|
||||
|
||||
let status = response.status();
|
||||
|
||||
@@ -296,7 +439,39 @@ pub async fn login(
|
||||
.json(&payload)
|
||||
.send()
|
||||
.await
|
||||
.map_err(|e| format!("Network error: {}", e))?;
|
||||
.map_err(|e| {
|
||||
let error_msg = e.to_string();
|
||||
let error_lower = error_msg.to_lowercase();
|
||||
log::error!("Spring Boot login network error: {}", e);
|
||||
|
||||
// Detect TLS version mismatch (server using TLS 1.0/1.1)
|
||||
if error_lower.contains("peer is incompatible") ||
|
||||
error_lower.contains("protocol version") ||
|
||||
error_lower.contains("peerincompatible") ||
|
||||
(error_lower.contains("handshake") && (error_lower.contains("tls") || error_lower.contains("ssl"))) {
|
||||
format!(
|
||||
"TLS version not supported: The server appears to be using TLS 1.0 or TLS 1.1, which are not supported by this desktop app. \
|
||||
Please upgrade your server to use TLS 1.2 or higher, or use the web version of Stirling-PDF instead. \
|
||||
Technical details: {}", e
|
||||
)
|
||||
// Other TLS/SSL errors (certificate issues)
|
||||
} else if error_lower.contains("tls") || error_lower.contains("ssl") ||
|
||||
error_lower.contains("certificate") || error_lower.contains("decrypt") {
|
||||
format!(
|
||||
"TLS/SSL connection error: This usually means the server has certificate issues. \
|
||||
The desktop app accepts self-signed certificates, so this might be a TLS version issue. \
|
||||
Technical details: {}", e
|
||||
)
|
||||
} else if error_lower.contains("connection refused") {
|
||||
format!("Connection refused: Server is not reachable at {}. Check if the server is running and the URL is correct.", login_url)
|
||||
} else if error_lower.contains("timeout") {
|
||||
format!("Connection timeout: Server at {} is not responding. Check your network connection.", login_url)
|
||||
} else if error_lower.contains("dns") || error_lower.contains("resolve") {
|
||||
format!("DNS resolution failed: Cannot resolve hostname. Check if the server URL is correct.")
|
||||
} else {
|
||||
format!("Network error: {}", e)
|
||||
}
|
||||
})?;
|
||||
|
||||
let status = response.status();
|
||||
log::debug!("Spring Boot login response status: {}", status);
|
||||
@@ -505,7 +680,20 @@ async fn exchange_code_for_token(
|
||||
) -> Result<OAuthCallbackResult, String> {
|
||||
log::info!("Exchanging authorization code for access token with PKCE");
|
||||
|
||||
let client = reqwest::Client::new();
|
||||
// Create HTTP client with certificate bypass
|
||||
// This handles:
|
||||
// - Self-signed certificates
|
||||
// - Missing intermediate certificates
|
||||
// - Certificate hostname mismatches
|
||||
// Note: Rustls only supports TLS 1.2 and TLS 1.3
|
||||
let client = reqwest::Client::builder()
|
||||
.danger_accept_invalid_certs(true)
|
||||
.timeout(std::time::Duration::from_secs(30))
|
||||
.build()
|
||||
.map_err(|e| {
|
||||
log::error!("Failed to create HTTP client: {}", e);
|
||||
format!("Failed to create HTTP client: {}", e)
|
||||
})?;
|
||||
// grant_type goes in query string, not body!
|
||||
let token_url = format!("{}/auth/v1/token?grant_type=pkce", auth_server_url.trim_end_matches('/'));
|
||||
|
||||
@@ -526,7 +714,24 @@ async fn exchange_code_for_token(
|
||||
.json(&body)
|
||||
.send()
|
||||
.await
|
||||
.map_err(|e| format!("Failed to exchange code for token: {}", e))?;
|
||||
.map_err(|e| {
|
||||
let error_msg = e.to_string();
|
||||
let error_lower = error_msg.to_lowercase();
|
||||
log::error!("OAuth token exchange network error: {}", e);
|
||||
|
||||
// Detect TLS version mismatch
|
||||
if error_lower.contains("peer is incompatible") ||
|
||||
error_lower.contains("protocol version") ||
|
||||
error_lower.contains("peerincompatible") ||
|
||||
(error_lower.contains("handshake") && (error_lower.contains("tls") || error_lower.contains("ssl"))) {
|
||||
format!(
|
||||
"TLS version not supported: The authentication server appears to require an unsupported TLS version. \
|
||||
Please contact support. Technical details: {}", e
|
||||
)
|
||||
} else {
|
||||
format!("Failed to exchange code for token: {}", e)
|
||||
}
|
||||
})?;
|
||||
|
||||
let status = response.status();
|
||||
if !status.is_success() {
|
||||
|
||||
@@ -14,11 +14,14 @@ pub use connection::{
|
||||
};
|
||||
pub use auth::{
|
||||
clear_auth_token,
|
||||
clear_refresh_token,
|
||||
clear_user_info,
|
||||
get_auth_token,
|
||||
get_refresh_token,
|
||||
get_user_info,
|
||||
login,
|
||||
save_auth_token,
|
||||
save_refresh_token,
|
||||
save_user_info,
|
||||
start_oauth_login,
|
||||
};
|
||||
|
||||
@@ -9,17 +9,20 @@ use commands::{
|
||||
cleanup_backend,
|
||||
clear_auth_token,
|
||||
clear_opened_files,
|
||||
clear_refresh_token,
|
||||
clear_user_info,
|
||||
is_default_pdf_handler,
|
||||
get_auth_token,
|
||||
get_backend_port,
|
||||
get_connection_config,
|
||||
get_opened_files,
|
||||
get_refresh_token,
|
||||
get_user_info,
|
||||
is_first_launch,
|
||||
login,
|
||||
reset_setup_completion,
|
||||
save_auth_token,
|
||||
save_refresh_token,
|
||||
save_user_info,
|
||||
set_connection_mode,
|
||||
set_as_default_pdf_handler,
|
||||
@@ -143,6 +146,9 @@ pub fn run() {
|
||||
save_auth_token,
|
||||
get_auth_token,
|
||||
clear_auth_token,
|
||||
save_refresh_token,
|
||||
get_refresh_token,
|
||||
clear_refresh_token,
|
||||
save_user_info,
|
||||
get_user_info,
|
||||
clear_user_info,
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
{
|
||||
"$schema": "../node_modules/@tauri-apps/cli/config.schema.json",
|
||||
"productName": "Stirling-PDF",
|
||||
"version": "2.4.0",
|
||||
"version": "2.4.3",
|
||||
"identifier": "stirling.pdf.dev",
|
||||
"build": {
|
||||
"frontendDist": "../dist",
|
||||
"devUrl": "http://localhost:5173",
|
||||
"devUrl": "http://localhost:5174",
|
||||
"beforeDevCommand": "npm run dev -- --mode desktop",
|
||||
"beforeBuildCommand": "npm run build -- --mode desktop"
|
||||
},
|
||||
@@ -16,7 +16,8 @@
|
||||
"width": 1280,
|
||||
"height": 800,
|
||||
"resizable": true,
|
||||
"fullscreen": false
|
||||
"fullscreen": false,
|
||||
"additionalBrowserArgs": "--enable-features=CertVerifierBuiltinFeature"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -66,7 +67,7 @@
|
||||
"macOS": {
|
||||
"minimumSystemVersion": "10.15",
|
||||
"signingIdentity": null,
|
||||
"entitlements": null,
|
||||
"entitlements": "entitlements.plist",
|
||||
"providerShortName": null
|
||||
}
|
||||
},
|
||||
|
||||
@@ -141,14 +141,15 @@ export default function Workbench() {
|
||||
);
|
||||
|
||||
case "pageEditor":
|
||||
|
||||
|
||||
return (
|
||||
<>
|
||||
<div style={{ position: 'relative', flex: '1 1 0', height: 0 }}>
|
||||
<PageEditor
|
||||
onFunctionsReady={setPageEditorFunctions}
|
||||
/>
|
||||
{pageEditorFunctions && (
|
||||
<PageEditorControls
|
||||
<div style={{ position: 'absolute', bottom: 0, left: 0, right: 0, zIndex: 100 }}>
|
||||
<PageEditorControls
|
||||
onClosePdf={pageEditorFunctions.closePdf}
|
||||
onUndo={pageEditorFunctions.handleUndo}
|
||||
onRedo={pageEditorFunctions.handleRedo}
|
||||
@@ -168,8 +169,9 @@ export default function Workbench() {
|
||||
splitPositions={pageEditorFunctions.splitPositions}
|
||||
totalPages={pageEditorFunctions.totalPages}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
</>
|
||||
</div>
|
||||
);
|
||||
|
||||
default:
|
||||
@@ -207,9 +209,10 @@ export default function Workbench() {
|
||||
|
||||
{/* Main content area */}
|
||||
<Box
|
||||
className={`flex-1 min-h-0 relative z-10 ${styles.workbenchScrollable}`}
|
||||
className={`flex-1 min-h-0 z-10 ${currentView === 'pageEditor' ? 'relative flex flex-col' : `relative ${styles.workbenchScrollable}`}`}
|
||||
style={{
|
||||
transition: 'opacity 0.15s ease-in-out',
|
||||
...(currentView === 'pageEditor' && { height: 0 }),
|
||||
}}
|
||||
>
|
||||
{renderMainContent()}
|
||||
|
||||
@@ -37,6 +37,7 @@ interface DragDropGridProps<T extends DragDropItem> {
|
||||
getThumbnailData?: (itemId: string) => { src: string; rotation: number } | null;
|
||||
zoomLevel?: number;
|
||||
selectedFileIds?: string[];
|
||||
onVisibleItemsChange?: (items: T[]) => void;
|
||||
}
|
||||
|
||||
type DropSide = 'left' | 'right' | null;
|
||||
@@ -198,7 +199,7 @@ interface DraggableItemProps<T extends DragDropItem> {
|
||||
zoomLevel: number;
|
||||
}
|
||||
|
||||
const DraggableItem = <T extends DragDropItem>({ item, index, itemRefs, boxSelectedPageIds, clearBoxSelection, getBoxSelection, activeId, activeDragIds, justMoved, getThumbnailData, renderItem, onUpdateDropTarget, zoomLevel }: DraggableItemProps<T>) => {
|
||||
const DraggableItemInner = <T extends DragDropItem>({ item, index, itemRefs, boxSelectedPageIds, clearBoxSelection, getBoxSelection, activeId, activeDragIds, justMoved, getThumbnailData, renderItem, onUpdateDropTarget, zoomLevel }: DraggableItemProps<T>) => {
|
||||
const isPlaceholder = Boolean(item.isPlaceholder);
|
||||
const pageNumber = (item as any).pageNumber ?? index + 1;
|
||||
const { attributes, listeners, setNodeRef: setDraggableRef } = useDraggable({
|
||||
@@ -252,6 +253,31 @@ const DraggableItem = <T extends DragDropItem>({ item, index, itemRefs, boxSelec
|
||||
);
|
||||
};
|
||||
|
||||
// Memoize to prevent unnecessary re-renders and hook thrashing
|
||||
const DraggableItem = React.memo(DraggableItemInner, (prevProps, nextProps) => {
|
||||
// Return true to SKIP re-render (props are equal)
|
||||
// Return false to RE-RENDER (props changed)
|
||||
|
||||
// Check if item reference or content changed (including thumbnail)
|
||||
const itemChanged = prevProps.item !== nextProps.item;
|
||||
|
||||
// If item object reference changed, we need to re-render
|
||||
if (itemChanged) {
|
||||
return false; // Props changed, re-render needed
|
||||
}
|
||||
|
||||
// Item reference is same, check other props
|
||||
return (
|
||||
prevProps.item.id === nextProps.item.id &&
|
||||
prevProps.index === nextProps.index &&
|
||||
prevProps.activeId === nextProps.activeId &&
|
||||
prevProps.justMoved === nextProps.justMoved &&
|
||||
prevProps.zoomLevel === nextProps.zoomLevel &&
|
||||
prevProps.activeDragIds.length === nextProps.activeDragIds.length &&
|
||||
prevProps.boxSelectedPageIds.length === nextProps.boxSelectedPageIds.length
|
||||
);
|
||||
}) as typeof DraggableItemInner;
|
||||
|
||||
const DragDropGrid = <T extends DragDropItem>({
|
||||
items,
|
||||
renderItem,
|
||||
@@ -259,6 +285,7 @@ const DragDropGrid = <T extends DragDropItem>({
|
||||
getThumbnailData,
|
||||
zoomLevel = 1.0,
|
||||
selectedFileIds,
|
||||
onVisibleItemsChange,
|
||||
}: DragDropGridProps<T>) => {
|
||||
const itemRefs = useRef<Map<string, HTMLDivElement>>(new Map());
|
||||
const containerRef = useRef<HTMLDivElement>(null);
|
||||
@@ -421,6 +448,21 @@ const DragDropGrid = <T extends DragDropItem>({
|
||||
overscan: OVERSCAN,
|
||||
});
|
||||
|
||||
const virtualRows = rowVirtualizer.getVirtualItems();
|
||||
|
||||
useEffect(() => {
|
||||
if (!onVisibleItemsChange) return;
|
||||
|
||||
const visibleItemsForCallback: T[] = [];
|
||||
virtualRows.forEach((row) => {
|
||||
const startIndex = row.index * itemsPerRow;
|
||||
const endIndex = Math.min(startIndex + itemsPerRow, visibleItems.length);
|
||||
visibleItemsForCallback.push(...visibleItems.slice(startIndex, endIndex));
|
||||
});
|
||||
|
||||
onVisibleItemsChange(visibleItemsForCallback);
|
||||
}, [virtualRows, visibleItems, itemsPerRow, onVisibleItemsChange]);
|
||||
|
||||
// Re-measure virtualizer when zoom or items per row changes
|
||||
useEffect(() => {
|
||||
rowVirtualizer.measure();
|
||||
@@ -719,7 +761,7 @@ const DragDropGrid = <T extends DragDropItem>({
|
||||
margin: '0 auto',
|
||||
}}
|
||||
>
|
||||
{rowVirtualizer.getVirtualItems().map((virtualRow) => {
|
||||
{virtualRows.map((virtualRow) => {
|
||||
const startIndex = virtualRow.index * itemsPerRow;
|
||||
const endIndex = Math.min(startIndex + itemsPerRow, visibleItems.length);
|
||||
const rowItems = visibleItems.slice(startIndex, endIndex);
|
||||
|
||||
@@ -3,7 +3,7 @@ import { Text, Center, Box, LoadingOverlay, Stack } from "@mantine/core";
|
||||
import { useFileState, useFileActions } from "@app/contexts/FileContext";
|
||||
import { useNavigationGuard } from "@app/contexts/NavigationContext";
|
||||
import { usePageEditor } from "@app/contexts/PageEditorContext";
|
||||
import { PageEditorFunctions } from "@app/types/pageEditor";
|
||||
import { PageEditorFunctions, PDFPage } from "@app/types/pageEditor";
|
||||
// Thumbnail generation is now handled by individual PageThumbnail components
|
||||
import '@app/components/pageEditor/PageEditor.module.css';
|
||||
import PageThumbnail from '@app/components/pageEditor/PageThumbnail';
|
||||
@@ -23,6 +23,7 @@ import { useUndoManagerState } from "@app/components/pageEditor/hooks/useUndoMan
|
||||
import { usePageSelectionManager } from "@app/components/pageEditor/hooks/usePageSelectionManager";
|
||||
import { usePageEditorCommands } from "@app/components/pageEditor/hooks/useEditorCommands";
|
||||
import { usePageEditorExport } from "@app/components/pageEditor/hooks/usePageEditorExport";
|
||||
import { useThumbnailGeneration } from "@app/hooks/useThumbnailGeneration";
|
||||
|
||||
export interface PageEditorProps {
|
||||
onFunctionsReady?: (functions: PageEditorFunctions) => void;
|
||||
@@ -40,7 +41,27 @@ const PageEditor = ({
|
||||
const { setHasUnsavedChanges } = useNavigationGuard();
|
||||
|
||||
// Get PageEditor coordination functions
|
||||
const { updateFileOrderFromPages, fileOrder, reorderedPages, clearReorderedPages, updateCurrentPages } = usePageEditor();
|
||||
const {
|
||||
updateFileOrderFromPages,
|
||||
fileOrder,
|
||||
reorderedPages,
|
||||
clearReorderedPages,
|
||||
updateCurrentPages,
|
||||
savePersistedDocument,
|
||||
} = usePageEditor();
|
||||
|
||||
const [visiblePageIds, setVisiblePageIds] = useState<string[]>([]);
|
||||
const thumbnailRequestsRef = useRef<Set<string>>(new Set());
|
||||
const { requestThumbnail, getThumbnailFromCache } = useThumbnailGeneration();
|
||||
const handleVisibleItemsChange = useCallback((items: PDFPage[]) => {
|
||||
setVisiblePageIds(prev => {
|
||||
const ids = items.map(item => item.id);
|
||||
if (prev.length === ids.length && prev.every((id, index) => id === ids[index])) {
|
||||
return prev;
|
||||
}
|
||||
return ids;
|
||||
});
|
||||
}, []);
|
||||
|
||||
// Zoom state management
|
||||
const [zoomLevel, setZoomLevel] = useState(1.0);
|
||||
@@ -149,6 +170,21 @@ const PageEditor = ({
|
||||
updateCurrentPages,
|
||||
});
|
||||
|
||||
const displayDocumentRef = useRef(displayDocument);
|
||||
useEffect(() => {
|
||||
displayDocumentRef.current = displayDocument;
|
||||
}, [displayDocument]);
|
||||
|
||||
useEffect(() => {
|
||||
return () => {
|
||||
const doc = displayDocumentRef.current;
|
||||
if (doc && doc.pages.length > 0) {
|
||||
const signature = doc.pages.map(page => page.id).join(',');
|
||||
savePersistedDocument(doc, signature);
|
||||
}
|
||||
};
|
||||
}, [savePersistedDocument]);
|
||||
|
||||
// UI state management
|
||||
const {
|
||||
selectionMode, selectedPageIds, movingPage, isAnimating, splitPositions, exportLoading,
|
||||
@@ -231,6 +267,92 @@ const PageEditor = ({
|
||||
setSplitPositions,
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
if (!displayDocument || visiblePageIds.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
const pending = thumbnailRequestsRef.current.size;
|
||||
const MAX_CONCURRENT_THUMBNAILS = 12;
|
||||
const available = Math.max(0, MAX_CONCURRENT_THUMBNAILS - pending);
|
||||
if (available === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
const toLoad: string[] = [];
|
||||
for (const pageId of visiblePageIds) {
|
||||
if (toLoad.length >= available) break;
|
||||
if (thumbnailRequestsRef.current.has(pageId)) continue;
|
||||
const page = displayDocument.pages.find(p => p.id === pageId);
|
||||
if (!page || page.thumbnail) continue;
|
||||
toLoad.push(pageId);
|
||||
}
|
||||
|
||||
if (toLoad.length === 0) return;
|
||||
|
||||
toLoad.forEach(pageId => {
|
||||
const page = displayDocument.pages.find(p => p.id === pageId);
|
||||
if (!page) return;
|
||||
|
||||
const cached = getThumbnailFromCache(pageId);
|
||||
if (cached) {
|
||||
thumbnailRequestsRef.current.add(pageId);
|
||||
Promise.resolve(cached)
|
||||
.then(cache => {
|
||||
setEditedDocument(prev => {
|
||||
if (!prev) return prev;
|
||||
const pageIndex = prev.pages.findIndex(p => p.id === pageId);
|
||||
if (pageIndex === -1) return prev;
|
||||
|
||||
// Only create new page object for the changed page, reuse rest
|
||||
const updated = [...prev.pages];
|
||||
updated[pageIndex] = { ...prev.pages[pageIndex], thumbnail: cache };
|
||||
return { ...prev, pages: updated };
|
||||
});
|
||||
})
|
||||
.finally(() => {
|
||||
thumbnailRequestsRef.current.delete(pageId);
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
const fileId = page.originalFileId;
|
||||
if (!fileId) return;
|
||||
const file = selectors.getFile(fileId);
|
||||
if (!file) return;
|
||||
|
||||
thumbnailRequestsRef.current.add(pageId);
|
||||
requestThumbnail(pageId, file, page.originalPageNumber || page.pageNumber)
|
||||
.then(thumbnail => {
|
||||
if (thumbnail) {
|
||||
setEditedDocument(prev => {
|
||||
if (!prev) return prev;
|
||||
const pageIndex = prev.pages.findIndex(p => p.id === pageId);
|
||||
if (pageIndex === -1) return prev;
|
||||
|
||||
// Only create new page object for the changed page, reuse rest
|
||||
const updated = [...prev.pages];
|
||||
updated[pageIndex] = { ...prev.pages[pageIndex], thumbnail };
|
||||
return { ...prev, pages: updated };
|
||||
});
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('[Thumbnail Loading] Error:', error);
|
||||
})
|
||||
.finally(() => {
|
||||
thumbnailRequestsRef.current.delete(pageId);
|
||||
});
|
||||
});
|
||||
}, [
|
||||
displayDocument,
|
||||
visiblePageIds,
|
||||
selectors,
|
||||
requestThumbnail,
|
||||
getThumbnailFromCache,
|
||||
setEditedDocument,
|
||||
]);
|
||||
|
||||
// Derived values for right rail and usePageEditorRightRailButtons (must be after displayDocument)
|
||||
const selectedPageCount = selectedPageIds.length;
|
||||
const activeFileIds = selectedFileIds;
|
||||
@@ -345,12 +467,17 @@ const PageEditor = ({
|
||||
const fileColorIndexMap = useFileColorMap(orderedFileIds);
|
||||
|
||||
return (
|
||||
<Box
|
||||
<div
|
||||
ref={containerRef}
|
||||
pos="relative"
|
||||
data-scrolling-container="true"
|
||||
onMouseEnter={() => setIsContainerHovered(true)}
|
||||
onMouseLeave={() => setIsContainerHovered(false)}
|
||||
style={{
|
||||
height: '100%',
|
||||
overflow: 'auto',
|
||||
position: 'relative',
|
||||
width: '100%',
|
||||
}}
|
||||
>
|
||||
<LoadingOverlay visible={globalProcessing && !initialDocument} />
|
||||
|
||||
@@ -372,7 +499,7 @@ const PageEditor = ({
|
||||
)}
|
||||
|
||||
{displayDocument && (
|
||||
<Box ref={gridContainerRef} p={0} pt="2rem" pb="15rem" style={{ position: 'relative' }}>
|
||||
<Box ref={gridContainerRef} p={0} pt="2rem" pb="4rem" style={{ position: 'relative' }}>
|
||||
|
||||
{/* Split Lines Overlay */}
|
||||
<div
|
||||
@@ -450,6 +577,7 @@ const PageEditor = ({
|
||||
onReorderPages={handleReorderPages}
|
||||
zoomLevel={zoomLevel}
|
||||
selectedFileIds={selectedFileIds}
|
||||
onVisibleItemsChange={handleVisibleItemsChange}
|
||||
getThumbnailData={(pageId) => {
|
||||
const page = displayDocument.pages.find(p => p.id === pageId);
|
||||
if (!page?.thumbnail) return null;
|
||||
@@ -468,7 +596,6 @@ const PageEditor = ({
|
||||
page={page}
|
||||
index={index}
|
||||
totalPages={displayDocument.pages.length}
|
||||
originalFile={(page as any).originalFileId ? selectors.getFile((page as any).originalFileId) : undefined}
|
||||
fileColorIndex={fileColorIndex}
|
||||
selectedPageIds={selectedPageIds}
|
||||
selectionMode={selectionMode}
|
||||
@@ -512,7 +639,7 @@ const PageEditor = ({
|
||||
}}
|
||||
/>
|
||||
|
||||
</Box>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -9,7 +9,6 @@ import DeleteIcon from '@mui/icons-material/Delete';
|
||||
import ContentCutIcon from '@mui/icons-material/ContentCut';
|
||||
import AddIcon from '@mui/icons-material/Add';
|
||||
import { PDFPage, PDFDocument } from '@app/types/pageEditor';
|
||||
import { useThumbnailGeneration } from '@app/hooks/useThumbnailGeneration';
|
||||
import { useFilesModalContext } from '@app/contexts/FilesModalContext';
|
||||
import { getFileColorWithOpacity } from '@app/components/pageEditor/fileColors';
|
||||
import styles from '@app/components/pageEditor/PageEditor.module.css';
|
||||
@@ -22,7 +21,6 @@ interface PageThumbnailProps {
|
||||
page: PDFPage;
|
||||
index: number;
|
||||
totalPages: number;
|
||||
originalFile?: File;
|
||||
fileColorIndex: number;
|
||||
selectedPageIds: string[];
|
||||
selectionMode: boolean;
|
||||
@@ -55,7 +53,6 @@ const PageThumbnail: React.FC<PageThumbnailProps> = ({
|
||||
page,
|
||||
index: _index,
|
||||
totalPages,
|
||||
originalFile,
|
||||
fileColorIndex,
|
||||
selectedPageIds,
|
||||
selectionMode,
|
||||
@@ -90,7 +87,6 @@ const PageThumbnail: React.FC<PageThumbnailProps> = ({
|
||||
|
||||
const [thumbnailUrl, setThumbnailUrl] = useState<string | null>(page.thumbnail);
|
||||
const elementRef = useRef<HTMLDivElement | null>(null);
|
||||
const { getThumbnailFromCache, requestThumbnail} = useThumbnailGeneration();
|
||||
const { openFilesModal } = useFilesModalContext();
|
||||
|
||||
// Check if this page is currently being dragged
|
||||
@@ -115,43 +111,6 @@ const PageThumbnail: React.FC<PageThumbnailProps> = ({
|
||||
}
|
||||
}, [page.thumbnail, thumbnailUrl]);
|
||||
|
||||
// Request thumbnail if missing (on-demand, virtualized approach)
|
||||
useEffect(() => {
|
||||
let isCancelled = false;
|
||||
|
||||
// If we already have a thumbnail, use it
|
||||
if (page.thumbnail) {
|
||||
setThumbnailUrl(page.thumbnail);
|
||||
return;
|
||||
}
|
||||
|
||||
// Check cache first
|
||||
const cachedThumbnail = getThumbnailFromCache(page.id);
|
||||
if (cachedThumbnail) {
|
||||
setThumbnailUrl(cachedThumbnail);
|
||||
return;
|
||||
}
|
||||
|
||||
// Request thumbnail generation if we have the original file
|
||||
if (originalFile) {
|
||||
const pageNumber = page.originalPageNumber;
|
||||
|
||||
requestThumbnail(page.id, originalFile, pageNumber)
|
||||
.then(thumbnail => {
|
||||
if (!isCancelled && thumbnail) {
|
||||
setThumbnailUrl(thumbnail);
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
console.warn(`Failed to generate thumbnail for ${page.id}:`, error);
|
||||
});
|
||||
}
|
||||
|
||||
return () => {
|
||||
isCancelled = true;
|
||||
};
|
||||
}, [page.id, page.thumbnail, originalFile, getThumbnailFromCache, requestThumbnail]);
|
||||
|
||||
// Merge refs - combine our ref tracking with dnd-kit's ref
|
||||
const mergedRef = useCallback((element: HTMLDivElement | null) => {
|
||||
// Track in our refs map
|
||||
|
||||
@@ -748,43 +748,49 @@ export class InsertFilesCommand extends DOMCommand {
|
||||
console.log('Pages:', pages.length);
|
||||
console.log('ArrayBuffer size:', arrayBuffer?.byteLength || 'undefined');
|
||||
|
||||
if (arrayBuffer && arrayBuffer.byteLength > 0) {
|
||||
// Extract page numbers for all pages from this file
|
||||
const pageNumbers = pages.map(page => {
|
||||
const pageNumMatch = page.id.match(/-page-(\d+)$/);
|
||||
return pageNumMatch ? parseInt(pageNumMatch[1]) : 1;
|
||||
});
|
||||
try {
|
||||
if (arrayBuffer && arrayBuffer.byteLength > 0) {
|
||||
// Extract page numbers for all pages from this file
|
||||
const pageNumbers = pages.map(page => {
|
||||
const pageNumMatch = page.id.match(/-page-(\d+)$/);
|
||||
return pageNumMatch ? parseInt(pageNumMatch[1]) : 1;
|
||||
});
|
||||
|
||||
console.log('Generating thumbnails for page numbers:', pageNumbers);
|
||||
console.log('Generating thumbnails for page numbers:', pageNumbers);
|
||||
|
||||
// Generate thumbnails for all pages from this file at once
|
||||
const results = await thumbnailGenerationService.generateThumbnails(
|
||||
fileId,
|
||||
arrayBuffer,
|
||||
pageNumbers,
|
||||
{ scale: 0.2, quality: 0.8 }
|
||||
);
|
||||
// Generate thumbnails for all pages from this file at once
|
||||
const results = await thumbnailGenerationService.generateThumbnails(
|
||||
fileId,
|
||||
arrayBuffer,
|
||||
pageNumbers,
|
||||
{ scale: 0.2, quality: 0.8 }
|
||||
);
|
||||
|
||||
console.log('Thumbnail generation results:', results.length, 'thumbnails generated');
|
||||
console.log('Thumbnail generation results:', results.length, 'thumbnails generated');
|
||||
|
||||
// Update pages with generated thumbnails
|
||||
for (let i = 0; i < results.length && i < pages.length; i++) {
|
||||
const result = results[i];
|
||||
const page = pages[i];
|
||||
// Update pages with generated thumbnails
|
||||
for (let i = 0; i < results.length && i < pages.length; i++) {
|
||||
const result = results[i];
|
||||
const page = pages[i];
|
||||
|
||||
if (result.success) {
|
||||
const pageIndex = updatedDocument.pages.findIndex(p => p.id === page.id);
|
||||
if (pageIndex >= 0) {
|
||||
updatedDocument.pages[pageIndex].thumbnail = result.thumbnail;
|
||||
console.log('Updated thumbnail for page:', page.id);
|
||||
if (result.success) {
|
||||
const pageIndex = updatedDocument.pages.findIndex(p => p.id === page.id);
|
||||
if (pageIndex >= 0) {
|
||||
updatedDocument.pages[pageIndex].thumbnail = result.thumbnail;
|
||||
console.log('Updated thumbnail for page:', page.id);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Trigger re-render by updating the document
|
||||
this.setDocument({ ...updatedDocument });
|
||||
} else {
|
||||
console.error('No valid ArrayBuffer found for file ID:', fileId);
|
||||
// Trigger re-render by updating the document
|
||||
this.setDocument({ ...updatedDocument });
|
||||
} else {
|
||||
console.error('No valid ArrayBuffer found for file ID:', fileId);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Failed to generate thumbnails for file:', fileId, error);
|
||||
} finally {
|
||||
this.fileDataMap.delete(fileId);
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
|
||||
@@ -3,6 +3,6 @@ export const GRID_CONSTANTS = {
|
||||
ITEM_WIDTH: '20rem', // page width
|
||||
ITEM_HEIGHT: '21.5rem', // 20rem + 1.5rem gap
|
||||
ITEM_GAP: '1.5rem', // gap between items
|
||||
OVERSCAN_SMALL: 4, // Overscan for normal documents
|
||||
OVERSCAN_LARGE: 8, // Overscan for large documents (>1000 pages)
|
||||
OVERSCAN_SMALL: 8, // Overscan for normal documents
|
||||
OVERSCAN_LARGE: 12, // Overscan for large documents (12 rows = ~96 pages pre-rendered)
|
||||
} as const;
|
||||
@@ -1,8 +1,9 @@
|
||||
import { useMemo } from 'react';
|
||||
import { useMemo, useEffect, useState } from 'react';
|
||||
import { useFileState } from '@app/contexts/FileContext';
|
||||
import { usePageEditor } from '@app/contexts/PageEditorContext';
|
||||
import { PDFDocument, PDFPage } from '@app/types/pageEditor';
|
||||
import { FileId } from '@app/types/file';
|
||||
import { FileAnalyzer } from '@app/services/fileAnalyzer';
|
||||
|
||||
export interface PageDocumentHook {
|
||||
document: PDFDocument | null;
|
||||
@@ -16,7 +17,7 @@ export interface PageDocumentHook {
|
||||
*/
|
||||
export function usePageDocument(): PageDocumentHook {
|
||||
const { state, selectors } = useFileState();
|
||||
const { fileOrder, currentPages } = usePageEditor();
|
||||
const { fileOrder, currentPages, persistedDocument, persistedDocumentSignature } = usePageEditor();
|
||||
|
||||
// Use PageEditorContext's fileOrder instead of FileContext's global order
|
||||
// This ensures the page editor respects its own workspace ordering
|
||||
@@ -58,6 +59,63 @@ export function usePageDocument(): PageDocumentHook {
|
||||
const processedFilePages = primaryStirlingFileStub?.processedFile?.pages;
|
||||
const processedFileTotalPages = primaryStirlingFileStub?.processedFile?.totalPages;
|
||||
|
||||
const [placeholderDocument, setPlaceholderDocument] = useState<PDFDocument | null>(null);
|
||||
|
||||
useEffect(() => {
|
||||
if (!primaryFileId) {
|
||||
setPlaceholderDocument(null);
|
||||
return;
|
||||
}
|
||||
|
||||
if (primaryStirlingFileStub?.processedFile) {
|
||||
setPlaceholderDocument(null);
|
||||
return;
|
||||
}
|
||||
|
||||
const file = selectors.getFile(primaryFileId);
|
||||
if (!file) {
|
||||
setPlaceholderDocument(null);
|
||||
return;
|
||||
}
|
||||
|
||||
let canceled = false;
|
||||
|
||||
const loadPlaceholder = async () => {
|
||||
try {
|
||||
const analysis = await FileAnalyzer.quickPDFAnalysis(file);
|
||||
if (canceled) return;
|
||||
const totalPages = Math.max(1, analysis.pageCount || 1);
|
||||
const pages: PDFPage[] = Array.from({ length: totalPages }, (_, index) => ({
|
||||
id: `placeholder-${primaryFileId}-page-${index + 1}`,
|
||||
pageNumber: index + 1,
|
||||
thumbnail: null,
|
||||
rotation: 0,
|
||||
selected: false,
|
||||
originalFileId: primaryFileId,
|
||||
originalPageNumber: index + 1,
|
||||
}));
|
||||
|
||||
setPlaceholderDocument({
|
||||
id: `placeholder-${primaryFileId}`,
|
||||
name: selectors.getStirlingFileStub(primaryFileId)?.name ?? file.name,
|
||||
file,
|
||||
pages,
|
||||
totalPages,
|
||||
});
|
||||
} catch {
|
||||
if (!canceled) {
|
||||
setPlaceholderDocument(null);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
loadPlaceholder();
|
||||
|
||||
return () => {
|
||||
canceled = true;
|
||||
};
|
||||
}, [primaryFileId, primaryStirlingFileStub?.processedFile, selectors]);
|
||||
|
||||
// Compute merged document with stable signature (prevents infinite loops)
|
||||
const currentPagesSignature = useMemo(() => {
|
||||
return currentPages ? currentPages.map(page => page.id).join(',') : '';
|
||||
@@ -66,7 +124,20 @@ export function usePageDocument(): PageDocumentHook {
|
||||
const mergedPdfDocument = useMemo((): PDFDocument | null => {
|
||||
if (activeFileIds.length === 0) return null;
|
||||
|
||||
const primaryFile = primaryFileId ? selectors.getFile(primaryFileId) : null;
|
||||
if (
|
||||
persistedDocument &&
|
||||
persistedDocumentSignature &&
|
||||
persistedDocumentSignature === currentPagesSignature &&
|
||||
currentPagesSignature.length > 0
|
||||
) {
|
||||
return persistedDocument;
|
||||
}
|
||||
|
||||
if (!primaryStirlingFileStub?.processedFile && placeholderDocument) {
|
||||
return placeholderDocument;
|
||||
}
|
||||
|
||||
const primaryFile = primaryFileId ? selectors.getFile(primaryFileId) : null;
|
||||
|
||||
// If we have file IDs but no file record, something is wrong - return null to show loading
|
||||
if (!primaryStirlingFileStub) {
|
||||
@@ -245,7 +316,24 @@ export function usePageDocument(): PageDocumentHook {
|
||||
};
|
||||
|
||||
return mergedDoc;
|
||||
}, [activeFileIds, selectedActiveFileIds, primaryFileId, primaryStirlingFileStub, processedFilePages, processedFileTotalPages, selectors, activeFilesSignature, selectedFileIdsKey, state.ui.selectedFileIds, allFileIds, currentPagesSignature, currentPages]);
|
||||
}, [
|
||||
activeFileIds,
|
||||
selectedActiveFileIds,
|
||||
primaryFileId,
|
||||
primaryStirlingFileStub,
|
||||
processedFilePages,
|
||||
processedFileTotalPages,
|
||||
selectors,
|
||||
activeFilesSignature,
|
||||
selectedFileIdsKey,
|
||||
state.ui.selectedFileIds,
|
||||
allFileIds,
|
||||
currentPagesSignature,
|
||||
currentPages,
|
||||
persistedDocument,
|
||||
persistedDocumentSignature,
|
||||
placeholderDocument,
|
||||
]);
|
||||
|
||||
// Large document detection for smart loading
|
||||
const isVeryLargeDocument = useMemo(() => {
|
||||
|
||||
@@ -10,6 +10,7 @@ import WarningRoundedIcon from '@mui/icons-material/WarningRounded';
|
||||
import { Z_INDEX_OVER_FILE_MANAGER_MODAL } from '@app/styles/zIndex';
|
||||
import { withBasePath } from '@app/constants/app';
|
||||
import { convertImageToPdf, isImageFile } from '@app/utils/imageToPdfUtils';
|
||||
import apiClient from '@app/services/apiClient';
|
||||
|
||||
interface MobileUploadModalProps {
|
||||
opened: boolean;
|
||||
@@ -75,26 +76,27 @@ export default function MobileUploadModal({ opened, onClose, onFilesReceived }:
|
||||
|
||||
// Use configured frontendUrl if set, otherwise use current origin
|
||||
// Combine with base path and mobile-scanner route
|
||||
const frontendUrl = config?.frontendUrl || window.location.origin;
|
||||
const baseUrl = localStorage.getItem('server_url') || '';
|
||||
const frontendUrl = baseUrl || config?.frontendUrl || window.location.origin;
|
||||
const mobileUrl = `${frontendUrl}${withBasePath('/mobile-scanner')}?session=${sessionId}`;
|
||||
|
||||
// Create session on backend
|
||||
const createSession = useCallback(async (newSessionId: string) => {
|
||||
try {
|
||||
const response = await fetch(`/api/v1/mobile-scanner/create-session/${newSessionId}`, {
|
||||
method: 'POST'
|
||||
const response = await apiClient.post<SessionInfo>(`/api/v1/mobile-scanner/create-session/${newSessionId}`, undefined, {
|
||||
responseType: 'json',
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
if (!response.status || response.status !== 200) {
|
||||
throw new Error('Failed to create session');
|
||||
}
|
||||
|
||||
const data = await response.json();
|
||||
const data = response.data;
|
||||
setSessionInfo(data);
|
||||
setError(null);
|
||||
console.log('Session created:', data);
|
||||
console.log('[MobileUploadModal] Session created:', data);
|
||||
} catch (err) {
|
||||
console.error('Failed to create session:', err);
|
||||
console.error('[MobileUploadModal] Failed to create session:', err);
|
||||
setError(t('mobileUpload.sessionCreateError', 'Failed to create session'));
|
||||
}
|
||||
}, [t]);
|
||||
@@ -113,12 +115,12 @@ export default function MobileUploadModal({ opened, onClose, onFilesReceived }:
|
||||
if (!opened) return;
|
||||
|
||||
try {
|
||||
const response = await fetch(`/api/v1/mobile-scanner/files/${sessionId}`);
|
||||
if (!response.ok) {
|
||||
const response = await apiClient.get(`/api/v1/mobile-scanner/files/${sessionId}`);
|
||||
if (!response.status || response.status !== 200) {
|
||||
throw new Error('Failed to check for files');
|
||||
}
|
||||
|
||||
const data = await response.json();
|
||||
const data = response.data;
|
||||
const files = data.files || [];
|
||||
|
||||
// Download only files we haven't processed yet
|
||||
@@ -127,12 +129,14 @@ export default function MobileUploadModal({ opened, onClose, onFilesReceived }:
|
||||
if (newFiles.length > 0) {
|
||||
for (const fileMetadata of newFiles) {
|
||||
try {
|
||||
const downloadResponse = await fetch(
|
||||
`/api/v1/mobile-scanner/download/${sessionId}/${fileMetadata.filename}`
|
||||
const downloadResponse = await apiClient.get(
|
||||
`/api/v1/mobile-scanner/download/${sessionId}/${fileMetadata.filename}`, {
|
||||
responseType: 'blob',
|
||||
}
|
||||
);
|
||||
|
||||
if (downloadResponse.ok) {
|
||||
const blob = await downloadResponse.blob();
|
||||
if (downloadResponse.status === 200) {
|
||||
const blob = downloadResponse.data;
|
||||
let file = new File([blob], fileMetadata.filename, {
|
||||
type: fileMetadata.contentType || 'image/jpeg'
|
||||
});
|
||||
@@ -145,9 +149,9 @@ export default function MobileUploadModal({ opened, onClose, onFilesReceived }:
|
||||
pageFormat: config?.mobileScannerPageFormat as 'keep' | 'A4' | 'letter' | undefined,
|
||||
stretchToFit: config?.mobileScannerStretchToFit,
|
||||
});
|
||||
console.log('Converted image to PDF:', file.name);
|
||||
console.log('[MobileUploadModal] Converted image to PDF:', file.name);
|
||||
} catch (convertError) {
|
||||
console.warn('Failed to convert image to PDF, using original file:', convertError);
|
||||
console.warn('[MobileUploadModal] Failed to convert image to PDF, using original file:', convertError);
|
||||
// Continue with original image file if conversion fails
|
||||
}
|
||||
}
|
||||
@@ -157,21 +161,21 @@ export default function MobileUploadModal({ opened, onClose, onFilesReceived }:
|
||||
onFilesReceived([file]);
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('Failed to download file:', fileMetadata.filename, err);
|
||||
console.error('[MobileUploadModal] Failed to download file:', fileMetadata.filename, err);
|
||||
}
|
||||
}
|
||||
|
||||
// Delete the entire session immediately after downloading all files
|
||||
// This ensures files are only on server for ~1 second
|
||||
try {
|
||||
await fetch(`/api/v1/mobile-scanner/session/${sessionId}`, { method: 'DELETE' });
|
||||
console.log('Session cleaned up after file download');
|
||||
await apiClient.delete(`/api/v1/mobile-scanner/session/${sessionId}`);
|
||||
console.log('[MobileUploadModal] Session cleaned up after file download');
|
||||
} catch (cleanupErr) {
|
||||
console.warn('Failed to cleanup session after download:', cleanupErr);
|
||||
console.warn('[MobileUploadModal] Failed to cleanup session after download:', cleanupErr);
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('Error polling for files:', err);
|
||||
console.error('[MobileUploadModal] Error polling for files:', err);
|
||||
setError(t('mobileUpload.pollingError', 'Error checking for files'));
|
||||
}
|
||||
}, [opened, sessionId, onFilesReceived, t]);
|
||||
@@ -184,14 +188,24 @@ export default function MobileUploadModal({ opened, onClose, onFilesReceived }:
|
||||
setError(null);
|
||||
setShowExpiryWarning(false);
|
||||
processedFiles.current.clear();
|
||||
} else {
|
||||
// Clean up session when modal closes
|
||||
if (sessionId) {
|
||||
fetch(`/api/v1/mobile-scanner/session/${sessionId}`, { method: 'DELETE' })
|
||||
.catch(err => console.warn('Failed to cleanup session on close:', err));
|
||||
}
|
||||
}
|
||||
}, [opened]); // Only run when opened changes
|
||||
}, [opened, sessionId]); // Only run when opened changes
|
||||
|
||||
useEffect(() => {
|
||||
if (!opened) return;
|
||||
|
||||
createSession(sessionId);
|
||||
setFilesReceived(0);
|
||||
setError(null);
|
||||
setShowExpiryWarning(false);
|
||||
processedFiles.current.clear();
|
||||
|
||||
return () => {
|
||||
console.log('Cleaning up session on unmount/close:', sessionId);
|
||||
apiClient.delete(`/api/v1/mobile-scanner/session/${sessionId}`)
|
||||
.catch(err => console.warn('[MobileUploadModal] Cleanup failed:', err));
|
||||
};
|
||||
}, [opened, sessionId, createSession]);
|
||||
|
||||
// Start polling for files when modal opens
|
||||
useEffect(() => {
|
||||
|
||||
@@ -1,15 +1,32 @@
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import { Paper, Stack, Switch, Text, Tooltip, NumberInput, SegmentedControl, Code, Group, Anchor, ActionIcon, Button, Badge, Alert } from '@mantine/core';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { usePreferences } from '@app/contexts/PreferencesContext';
|
||||
import { useAppConfig } from '@app/contexts/AppConfigContext';
|
||||
import type { ToolPanelMode } from '@app/constants/toolPanel';
|
||||
import LocalIcon from '@app/components/shared/LocalIcon';
|
||||
import { updateService, UpdateSummary } from '@app/services/updateService';
|
||||
import UpdateModal from '@app/components/shared/UpdateModal';
|
||||
import React, { useState, useEffect, useMemo } from "react";
|
||||
import {
|
||||
Paper,
|
||||
Stack,
|
||||
Switch,
|
||||
Text,
|
||||
Tooltip,
|
||||
NumberInput,
|
||||
SegmentedControl,
|
||||
Code,
|
||||
Group,
|
||||
Anchor,
|
||||
ActionIcon,
|
||||
Button,
|
||||
Badge,
|
||||
Alert,
|
||||
} from "@mantine/core";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { usePreferences } from "@app/contexts/PreferencesContext";
|
||||
import { useAppConfig } from "@app/contexts/AppConfigContext";
|
||||
import type { ToolPanelMode } from "@app/constants/toolPanel";
|
||||
import LocalIcon from "@app/components/shared/LocalIcon";
|
||||
import { updateService, UpdateSummary } from "@app/services/updateService";
|
||||
import UpdateModal from "@app/components/shared/UpdateModal";
|
||||
import { getVersion } from "@tauri-apps/api/app";
|
||||
import { isTauri } from "@tauri-apps/api/core";
|
||||
|
||||
const DEFAULT_AUTO_UNZIP_FILE_LIMIT = 4;
|
||||
const BANNER_DISMISSED_KEY = 'stirlingpdf_features_banner_dismissed';
|
||||
const BANNER_DISMISSED_KEY = "stirlingpdf_features_banner_dismissed";
|
||||
|
||||
interface GeneralSectionProps {
|
||||
hideTitle?: boolean;
|
||||
@@ -22,11 +39,15 @@ const GeneralSection: React.FC<GeneralSectionProps> = ({ hideTitle = false }) =>
|
||||
const [fileLimitInput, setFileLimitInput] = useState<number | string>(preferences.autoUnzipFileLimit);
|
||||
const [bannerDismissed, setBannerDismissed] = useState(() => {
|
||||
// Check localStorage on mount
|
||||
return localStorage.getItem(BANNER_DISMISSED_KEY) === 'true';
|
||||
return localStorage.getItem(BANNER_DISMISSED_KEY) === "true";
|
||||
});
|
||||
const [updateSummary, setUpdateSummary] = useState<UpdateSummary | null>(null);
|
||||
const [updateModalOpened, setUpdateModalOpened] = useState(false);
|
||||
const [checkingUpdate, setCheckingUpdate] = useState(false);
|
||||
const [mismatchVersion, setMismatchVersion] = useState(false);
|
||||
const isTauriApp = useMemo(() => isTauri(), []);
|
||||
const [appVersion, setAppVersion] = useState<string | null>(null);
|
||||
const frontendVersionLabel = appVersion ?? t("common.loading", "Loading...");
|
||||
|
||||
// Sync local state with preference changes
|
||||
useEffect(() => {
|
||||
@@ -49,7 +70,7 @@ const GeneralSection: React.FC<GeneralSectionProps> = ({ hideTitle = false }) =>
|
||||
const machineInfo = {
|
||||
machineType: config.machineType,
|
||||
activeSecurity: config.activeSecurity ?? false,
|
||||
licenseType: config.license ?? 'NORMAL',
|
||||
licenseType: config.license ?? "NORMAL",
|
||||
};
|
||||
|
||||
const summary = await updateService.getUpdateSummary(config.appVersion, machineInfo);
|
||||
@@ -68,67 +89,126 @@ const GeneralSection: React.FC<GeneralSectionProps> = ({ hideTitle = false }) =>
|
||||
setCheckingUpdate(false);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (!isTauriApp) {
|
||||
setMismatchVersion(false);
|
||||
return;
|
||||
}
|
||||
|
||||
let cancelled = false;
|
||||
const fetchFrontendVersion = async () => {
|
||||
try {
|
||||
const frontendVersion = await getVersion();
|
||||
if (!cancelled) {
|
||||
setAppVersion(frontendVersion);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("[GeneralSection] Failed to fetch frontend version:", error);
|
||||
}
|
||||
};
|
||||
|
||||
fetchFrontendVersion();
|
||||
|
||||
return () => {
|
||||
cancelled = true;
|
||||
};
|
||||
}, [isTauriApp]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!isTauriApp) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!appVersion || !config?.appVersion) {
|
||||
setMismatchVersion(false);
|
||||
return;
|
||||
}
|
||||
|
||||
if (appVersion !== config.appVersion) {
|
||||
console.warn("[GeneralSection] Mismatch between Tauri version and AppConfig version:", {
|
||||
backendVersion: config.appVersion,
|
||||
frontendVersion: appVersion,
|
||||
});
|
||||
setMismatchVersion(true);
|
||||
} else {
|
||||
setMismatchVersion(false);
|
||||
}
|
||||
}, [isTauriApp, appVersion, config?.appVersion]);
|
||||
|
||||
// Check if login is disabled
|
||||
const loginDisabled = !config?.enableLogin;
|
||||
|
||||
const handleDismissBanner = () => {
|
||||
setBannerDismissed(true);
|
||||
localStorage.setItem(BANNER_DISMISSED_KEY, 'true');
|
||||
localStorage.setItem(BANNER_DISMISSED_KEY, "true");
|
||||
};
|
||||
|
||||
return (
|
||||
<Stack gap="lg">
|
||||
{!hideTitle && (
|
||||
<div>
|
||||
<Text fw={600} size="lg">{t('settings.general.title', 'General')}</Text>
|
||||
<Text fw={600} size="lg">
|
||||
{t("settings.general.title", "General")}
|
||||
</Text>
|
||||
<Text size="sm" c="dimmed">
|
||||
{t('settings.general.description', 'Configure general application preferences.')}
|
||||
{t("settings.general.description", "Configure general application preferences.")}
|
||||
</Text>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{loginDisabled && !bannerDismissed && (
|
||||
<Paper withBorder p="md" radius="md" style={{ background: 'var(--mantine-color-blue-0)', position: 'relative' }}>
|
||||
<Paper withBorder p="md" radius="md" style={{ background: "var(--mantine-color-blue-0)", position: "relative" }}>
|
||||
<ActionIcon
|
||||
variant="subtle"
|
||||
color="gray"
|
||||
size="sm"
|
||||
style={{ position: 'absolute', top: '0.5rem', right: '0.5rem' }}
|
||||
style={{ position: "absolute", top: "0.5rem", right: "0.5rem" }}
|
||||
onClick={handleDismissBanner}
|
||||
aria-label={t('settings.general.enableFeatures.dismiss', 'Dismiss')}
|
||||
aria-label={t("settings.general.enableFeatures.dismiss", "Dismiss")}
|
||||
>
|
||||
<LocalIcon icon="close-rounded" width="1rem" height="1rem" />
|
||||
</ActionIcon>
|
||||
<Stack gap="sm">
|
||||
<Group gap="xs">
|
||||
<LocalIcon icon="admin-panel-settings-rounded" width="1.2rem" height="1.2rem" style={{ color: 'var(--mantine-color-blue-6)' }} />
|
||||
<Text fw={600} size="sm" style={{ color: 'var(--mantine-color-blue-9)' }}>
|
||||
{t('settings.general.enableFeatures.title', 'For System Administrators')}
|
||||
<LocalIcon
|
||||
icon="admin-panel-settings-rounded"
|
||||
width="1.2rem"
|
||||
height="1.2rem"
|
||||
style={{ color: "var(--mantine-color-blue-6)" }}
|
||||
/>
|
||||
<Text fw={600} size="sm" style={{ color: "var(--mantine-color-blue-9)" }}>
|
||||
{t("settings.general.enableFeatures.title", "For System Administrators")}
|
||||
</Text>
|
||||
</Group>
|
||||
<Text size="sm" c="dimmed">
|
||||
{t('settings.general.enableFeatures.intro', 'Enable user authentication, team management, and workspace features for your organization.')}
|
||||
{t(
|
||||
"settings.general.enableFeatures.intro",
|
||||
"Enable user authentication, team management, and workspace features for your organization.",
|
||||
)}
|
||||
</Text>
|
||||
<Group gap="xs" wrap="wrap">
|
||||
<Text size="sm" c="dimmed">
|
||||
{t('settings.general.enableFeatures.action', 'Configure')}
|
||||
{t("settings.general.enableFeatures.action", "Configure")}
|
||||
</Text>
|
||||
<Code>SECURITY_ENABLELOGIN=true</Code>
|
||||
<Text size="sm" c="dimmed">
|
||||
{t('settings.general.enableFeatures.and', 'and')}
|
||||
{t("settings.general.enableFeatures.and", "and")}
|
||||
</Text>
|
||||
<Code>DISABLE_ADDITIONAL_FEATURES=false</Code>
|
||||
</Group>
|
||||
<Text size="xs" c="dimmed" fs="italic">
|
||||
{t('settings.general.enableFeatures.benefit', 'Enables user roles, team collaboration, admin controls, and enterprise features.')}
|
||||
{t(
|
||||
"settings.general.enableFeatures.benefit",
|
||||
"Enables user roles, team collaboration, admin controls, and enterprise features.",
|
||||
)}
|
||||
</Text>
|
||||
<Anchor
|
||||
href="https://docs.stirlingpdf.com/Advanced%20Configuration/System%20and%20Security"
|
||||
href="https://docs.stirlingpdf.com/Configuration/System%20and%20Security/"
|
||||
target="_blank"
|
||||
size="sm"
|
||||
style={{ color: 'var(--mantine-color-blue-6)' }}
|
||||
style={{ color: "var(--mantine-color-blue-6)" }}
|
||||
>
|
||||
{t('settings.general.enableFeatures.learnMore', 'Learn more in documentation')} →
|
||||
{t("settings.general.enableFeatures.learnMore", "Learn more in documentation")} →
|
||||
</Anchor>
|
||||
</Stack>
|
||||
</Paper>
|
||||
@@ -142,36 +222,52 @@ const GeneralSection: React.FC<GeneralSectionProps> = ({ hideTitle = false }) =>
|
||||
<Group justify="space-between" align="center">
|
||||
<div>
|
||||
<Text fw={600} size="sm">
|
||||
{t('settings.general.updates.title', 'Software Updates')}
|
||||
{t("settings.general.updates.title", "Software Updates")}
|
||||
</Text>
|
||||
<Text size="xs" c="dimmed" mt={4}>
|
||||
{t('settings.general.updates.description', 'Check for updates and view version information')}
|
||||
{t("settings.general.updates.description", "Check for updates and view version information")}
|
||||
</Text>
|
||||
</div>
|
||||
{updateSummary && (
|
||||
<Badge
|
||||
color={updateSummary.max_priority === 'urgent' ? 'red' : 'blue'}
|
||||
variant="filled"
|
||||
>
|
||||
{updateSummary.max_priority === 'urgent'
|
||||
? t('update.urgentUpdateAvailable', 'Urgent Update')
|
||||
: t('update.updateAvailable', 'Update Available')}
|
||||
<Badge color={updateSummary.max_priority === "urgent" ? "red" : "blue"} variant="filled">
|
||||
{updateSummary.max_priority === "urgent"
|
||||
? t("update.urgentUpdateAvailable", "Urgent Update")
|
||||
: t("update.updateAvailable", "Update Available")}
|
||||
</Badge>
|
||||
)}
|
||||
</Group>
|
||||
</div>
|
||||
|
||||
{isTauriApp && (
|
||||
<Group justify="space-between" align="center">
|
||||
<div>
|
||||
<Text size="sm" c="dimmed">
|
||||
{t("settings.general.updates.currentFrontendVersion", "Current Frontend Version")}:{" "}
|
||||
<Text component="span" fw={500}>
|
||||
{frontendVersionLabel}
|
||||
</Text>
|
||||
</Text>
|
||||
{mismatchVersion && (
|
||||
<Text size="sm" c="red" mt={4}>
|
||||
{t(
|
||||
"settings.general.updates.versionMismatch",
|
||||
"Warning: A mismatch has been detected between the client version and the AppConfig version. Using different versions can lead to compatibility issues, errors, and security risks. Please ensure that server and client are using the same version.",
|
||||
)}
|
||||
</Text>
|
||||
)}
|
||||
</div>
|
||||
</Group>
|
||||
)}
|
||||
<Group justify="space-between" align="center">
|
||||
<div>
|
||||
<Text size="sm" c="dimmed">
|
||||
{t('settings.general.updates.currentVersion', 'Current Version')}:{' '}
|
||||
{t("settings.general.updates.currentBackendVersion", "Current Backend Version")}:{" "}
|
||||
<Text component="span" fw={500}>
|
||||
{config.appVersion}
|
||||
</Text>
|
||||
</Text>
|
||||
{updateSummary && (
|
||||
<Text size="sm" c="dimmed" mt={4}>
|
||||
{t('settings.general.updates.latestVersion', 'Latest Version')}:{' '}
|
||||
{t("settings.general.updates.latestVersion", "Latest Version")}:{" "}
|
||||
<Text component="span" fw={500} c="blue">
|
||||
{updateSummary.latest_version}
|
||||
</Text>
|
||||
@@ -186,16 +282,16 @@ const GeneralSection: React.FC<GeneralSectionProps> = ({ hideTitle = false }) =>
|
||||
loading={checkingUpdate}
|
||||
leftSection={<LocalIcon icon="refresh-rounded" width="1rem" height="1rem" />}
|
||||
>
|
||||
{t('settings.general.updates.checkForUpdates', 'Check for Updates')}
|
||||
{t("settings.general.updates.checkForUpdates", "Check for Updates")}
|
||||
</Button>
|
||||
{updateSummary && (
|
||||
<Button
|
||||
size="sm"
|
||||
color={updateSummary.max_priority === 'urgent' ? 'red' : 'blue'}
|
||||
color={updateSummary.max_priority === "urgent" ? "red" : "blue"}
|
||||
onClick={() => setUpdateModalOpened(true)}
|
||||
leftSection={<LocalIcon icon="system-update-alt-rounded" width="1rem" height="1rem" />}
|
||||
>
|
||||
{t('settings.general.updates.viewDetails', 'View Details')}
|
||||
{t("settings.general.updates.viewDetails", "View Details")}
|
||||
</Button>
|
||||
)}
|
||||
</Group>
|
||||
@@ -204,15 +300,15 @@ const GeneralSection: React.FC<GeneralSectionProps> = ({ hideTitle = false }) =>
|
||||
{updateSummary?.any_breaking && (
|
||||
<Alert
|
||||
color="orange"
|
||||
title={t('update.breakingChangesDetected', 'Breaking Changes Detected')}
|
||||
title={t("update.breakingChangesDetected", "Breaking Changes Detected")}
|
||||
styles={{
|
||||
title: { fontWeight: 600 }
|
||||
title: { fontWeight: 600 },
|
||||
}}
|
||||
>
|
||||
<Text size="sm">
|
||||
{t(
|
||||
'update.breakingChangesMessage',
|
||||
'Some versions contain breaking changes. Please review the migration guides before updating.'
|
||||
"update.breakingChangesMessage",
|
||||
"Some versions contain breaking changes. Please review the migration guides before updating.",
|
||||
)}
|
||||
</Text>
|
||||
</Alert>
|
||||
@@ -223,87 +319,102 @@ const GeneralSection: React.FC<GeneralSectionProps> = ({ hideTitle = false }) =>
|
||||
|
||||
<Paper withBorder p="md" radius="md">
|
||||
<Stack gap="md">
|
||||
<div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
|
||||
<div style={{ display: "flex", alignItems: "center", justifyContent: "space-between" }}>
|
||||
<div>
|
||||
<Text fw={500} size="sm">
|
||||
{t('settings.general.defaultToolPickerMode', 'Default tool picker mode')}
|
||||
{t("settings.general.defaultToolPickerMode", "Default tool picker mode")}
|
||||
</Text>
|
||||
<Text size="xs" c="dimmed" mt={4}>
|
||||
{t('settings.general.defaultToolPickerModeDescription', 'Choose whether the tool picker opens in fullscreen or sidebar by default')}
|
||||
{t(
|
||||
"settings.general.defaultToolPickerModeDescription",
|
||||
"Choose whether the tool picker opens in fullscreen or sidebar by default",
|
||||
)}
|
||||
</Text>
|
||||
</div>
|
||||
<SegmentedControl
|
||||
value={preferences.defaultToolPanelMode}
|
||||
onChange={(val: string) => updatePreference('defaultToolPanelMode', val as ToolPanelMode)}
|
||||
onChange={(val: string) => updatePreference("defaultToolPanelMode", val as ToolPanelMode)}
|
||||
data={[
|
||||
{ label: t('settings.general.mode.sidebar', 'Sidebar'), value: 'sidebar' },
|
||||
{ label: t('settings.general.mode.fullscreen', 'Fullscreen'), value: 'fullscreen' },
|
||||
{ label: t("settings.general.mode.sidebar", "Sidebar"), value: "sidebar" },
|
||||
{ label: t("settings.general.mode.fullscreen", "Fullscreen"), value: "fullscreen" },
|
||||
]}
|
||||
/>
|
||||
</div>
|
||||
<div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
|
||||
<div style={{ display: "flex", alignItems: "center", justifyContent: "space-between" }}>
|
||||
<div>
|
||||
<Text fw={500} size="sm">
|
||||
{t('settings.general.hideUnavailableTools', 'Hide unavailable tools')}
|
||||
{t("settings.general.hideUnavailableTools", "Hide unavailable tools")}
|
||||
</Text>
|
||||
<Text size="xs" c="dimmed" mt={4}>
|
||||
{t('settings.general.hideUnavailableToolsDescription', 'Remove tools that have been disabled by your server instead of showing them greyed out.')}
|
||||
{t(
|
||||
"settings.general.hideUnavailableToolsDescription",
|
||||
"Remove tools that have been disabled by your server instead of showing them greyed out.",
|
||||
)}
|
||||
</Text>
|
||||
</div>
|
||||
<Switch
|
||||
checked={preferences.hideUnavailableTools}
|
||||
onChange={(event) => updatePreference('hideUnavailableTools', event.currentTarget.checked)}
|
||||
onChange={(event) => updatePreference("hideUnavailableTools", event.currentTarget.checked)}
|
||||
/>
|
||||
</div>
|
||||
<div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
|
||||
<div style={{ display: "flex", alignItems: "center", justifyContent: "space-between" }}>
|
||||
<div>
|
||||
<Text fw={500} size="sm">
|
||||
{t('settings.general.hideUnavailableConversions', 'Hide unavailable conversions')}
|
||||
{t("settings.general.hideUnavailableConversions", "Hide unavailable conversions")}
|
||||
</Text>
|
||||
<Text size="xs" c="dimmed" mt={4}>
|
||||
{t('settings.general.hideUnavailableConversionsDescription', 'Remove disabled conversion options in the Convert tool instead of showing them greyed out.')}
|
||||
{t(
|
||||
"settings.general.hideUnavailableConversionsDescription",
|
||||
"Remove disabled conversion options in the Convert tool instead of showing them greyed out.",
|
||||
)}
|
||||
</Text>
|
||||
</div>
|
||||
<Switch
|
||||
checked={preferences.hideUnavailableConversions}
|
||||
onChange={(event) => updatePreference('hideUnavailableConversions', event.currentTarget.checked)}
|
||||
onChange={(event) => updatePreference("hideUnavailableConversions", event.currentTarget.checked)}
|
||||
/>
|
||||
</div>
|
||||
<Tooltip
|
||||
label={t('settings.general.autoUnzipTooltip', 'Automatically extract ZIP files returned from API operations. Disable to keep ZIP files intact. This does not affect automation workflows.')}
|
||||
label={t(
|
||||
"settings.general.autoUnzipTooltip",
|
||||
"Automatically extract ZIP files returned from API operations. Disable to keep ZIP files intact. This does not affect automation workflows.",
|
||||
)}
|
||||
multiline
|
||||
w={300}
|
||||
withArrow
|
||||
>
|
||||
<div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', cursor: 'help' }}>
|
||||
<div style={{ display: "flex", alignItems: "center", justifyContent: "space-between", cursor: "help" }}>
|
||||
<div>
|
||||
<Text fw={500} size="sm">
|
||||
{t('settings.general.autoUnzip', 'Auto-unzip API responses')}
|
||||
{t("settings.general.autoUnzip", "Auto-unzip API responses")}
|
||||
</Text>
|
||||
<Text size="xs" c="dimmed" mt={4}>
|
||||
{t('settings.general.autoUnzipDescription', 'Automatically extract files from ZIP responses')}
|
||||
{t("settings.general.autoUnzipDescription", "Automatically extract files from ZIP responses")}
|
||||
</Text>
|
||||
</div>
|
||||
<Switch
|
||||
checked={preferences.autoUnzip}
|
||||
onChange={(event) => updatePreference('autoUnzip', event.currentTarget.checked)}
|
||||
onChange={(event) => updatePreference("autoUnzip", event.currentTarget.checked)}
|
||||
/>
|
||||
</div>
|
||||
</Tooltip>
|
||||
|
||||
<Tooltip
|
||||
label={t('settings.general.autoUnzipFileLimitTooltip', 'Only unzip if the ZIP contains this many files or fewer. Set higher to extract larger ZIPs.')}
|
||||
label={t(
|
||||
"settings.general.autoUnzipFileLimitTooltip",
|
||||
"Only unzip if the ZIP contains this many files or fewer. Set higher to extract larger ZIPs.",
|
||||
)}
|
||||
multiline
|
||||
w={300}
|
||||
withArrow
|
||||
>
|
||||
<div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', cursor: 'help' }}>
|
||||
<div style={{ display: "flex", alignItems: "center", justifyContent: "space-between", cursor: "help" }}>
|
||||
<div>
|
||||
<Text fw={500} size="sm">
|
||||
{t('settings.general.autoUnzipFileLimit', 'Auto-unzip file limit')}
|
||||
{t("settings.general.autoUnzipFileLimit", "Auto-unzip file limit")}
|
||||
</Text>
|
||||
<Text size="xs" c="dimmed" mt={4}>
|
||||
{t('settings.general.autoUnzipFileLimitDescription', 'Maximum number of files to extract from ZIP')}
|
||||
{t("settings.general.autoUnzipFileLimitDescription", "Maximum number of files to extract from ZIP")}
|
||||
</Text>
|
||||
</div>
|
||||
<NumberInput
|
||||
@@ -311,9 +422,12 @@ const GeneralSection: React.FC<GeneralSectionProps> = ({ hideTitle = false }) =>
|
||||
onChange={setFileLimitInput}
|
||||
onBlur={() => {
|
||||
const numValue = Number(fileLimitInput);
|
||||
const finalValue = (!fileLimitInput || isNaN(numValue) || numValue < 1 || numValue > 100) ? DEFAULT_AUTO_UNZIP_FILE_LIMIT : numValue;
|
||||
const finalValue =
|
||||
!fileLimitInput || isNaN(numValue) || numValue < 1 || numValue > 100
|
||||
? DEFAULT_AUTO_UNZIP_FILE_LIMIT
|
||||
: numValue;
|
||||
setFileLimitInput(finalValue);
|
||||
updatePreference('autoUnzipFileLimit', finalValue);
|
||||
updatePreference("autoUnzipFileLimit", finalValue);
|
||||
}}
|
||||
min={1}
|
||||
max={100}
|
||||
@@ -336,7 +450,7 @@ const GeneralSection: React.FC<GeneralSectionProps> = ({ hideTitle = false }) =>
|
||||
machineInfo={{
|
||||
machineType: config.machineType,
|
||||
activeSecurity: config.activeSecurity ?? false,
|
||||
licenseType: config.license ?? 'NORMAL',
|
||||
licenseType: config.license ?? "NORMAL",
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
|
||||
+10
@@ -49,6 +49,16 @@ const AddPageNumbersAppearanceSettings = ({
|
||||
/>
|
||||
</Tooltip>
|
||||
|
||||
<Tooltip content={t('addPageNumbers.zeroPadTooltip', 'Zero-pad (Bates Stamp) page numbers to this width (e.g. 3 => 001). Set 0 to disable.')}>
|
||||
<NumberInput
|
||||
label={t('addPageNumbers.zeroPad', 'Zero-pad Width (Bates Stamping)')}
|
||||
value={parameters.zeroPad}
|
||||
onChange={(v) => onParameterChange('zeroPad', typeof v === 'number' ? v : 0)}
|
||||
min={0}
|
||||
disabled={disabled}
|
||||
/>
|
||||
</Tooltip>
|
||||
|
||||
<Tooltip content={t('fontTypeTooltip', 'Font family for the page numbers. Choose based on your document style.')}>
|
||||
<Select
|
||||
label={t('addPageNumbers.fontName', 'Font Type')}
|
||||
|
||||
@@ -13,6 +13,7 @@ export const buildAddPageNumbersFormData = (parameters: AddPageNumbersParameters
|
||||
formData.append('startingNumber', String(parameters.startingNumber));
|
||||
formData.append('pagesToNumber', parameters.pagesToNumber);
|
||||
formData.append('customText', parameters.customText);
|
||||
formData.append('zeroPad', String(parameters.zeroPad));
|
||||
|
||||
return formData;
|
||||
};
|
||||
|
||||
@@ -9,6 +9,8 @@ export interface AddPageNumbersParameters extends BaseParameters {
|
||||
startingNumber: number;
|
||||
pagesToNumber: string;
|
||||
customText: string;
|
||||
// Number of digits to zero-pad page numbers to. 0 = no padding.
|
||||
zeroPad: number;
|
||||
}
|
||||
|
||||
export const defaultParameters: AddPageNumbersParameters = {
|
||||
@@ -19,6 +21,7 @@ export const defaultParameters: AddPageNumbersParameters = {
|
||||
startingNumber: 1,
|
||||
pagesToNumber: '',
|
||||
customText: '',
|
||||
zeroPad: 0,
|
||||
};
|
||||
|
||||
export type AddPageNumbersParametersHook = BaseParametersHook<AddPageNumbersParameters>;
|
||||
|
||||
@@ -99,7 +99,7 @@ const StampPositionFormattingSettings = ({ parameters, onParameterChange, disabl
|
||||
<Group className={styles.sliderGroup} align="center">
|
||||
<NumberInput
|
||||
value={parameters.fontSize}
|
||||
onChange={(v) => onParameterChange('fontSize', typeof v === 'number' ? v : 1)}
|
||||
onChange={(v) => onParameterChange('fontSize', typeof v === 'number' && v > 0 ? v : 1)}
|
||||
min={1}
|
||||
max={400}
|
||||
step={1}
|
||||
@@ -114,6 +114,7 @@ const StampPositionFormattingSettings = ({ parameters, onParameterChange, disabl
|
||||
max={400}
|
||||
step={1}
|
||||
className={styles.slider}
|
||||
disabled={disabled}
|
||||
/>
|
||||
</Group>
|
||||
</Stack>
|
||||
|
||||
@@ -1,18 +1,169 @@
|
||||
import { useMemo } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Stack, Textarea, TextInput, Select, Button, Text, Divider } from "@mantine/core";
|
||||
import { Stack, Textarea, TextInput, Select, Button, Text, Divider, Accordion, Code, Group, Badge, Box, Paper } from "@mantine/core";
|
||||
import { AddStampParameters } from "@app/components/tools/addStamp/useAddStampParameters";
|
||||
import ButtonSelector from "@app/components/shared/ButtonSelector";
|
||||
import styles from "@app/components/tools/addStamp/StampPreview.module.css";
|
||||
import { getDefaultFontSizeForAlphabet } from "@app/components/tools/addStamp/StampPreviewUtils";
|
||||
import { Z_INDEX_AUTOMATE_DROPDOWN } from "@app/styles/zIndex";
|
||||
|
||||
const STAMP_TEMPLATES = [
|
||||
{
|
||||
id: 'page-numbers',
|
||||
name: 'Page Numbers',
|
||||
text: 'Page @page_number of @total_pages',
|
||||
position: 2, // bottom center
|
||||
},
|
||||
{
|
||||
id: 'draft',
|
||||
name: 'Draft Watermark',
|
||||
text: 'DRAFT - @date',
|
||||
position: 5, // center
|
||||
},
|
||||
{
|
||||
id: 'doc-info',
|
||||
name: 'Document Info',
|
||||
text: '@filename\nCreated: @date{dd MMM yyyy}',
|
||||
position: 7, // top left
|
||||
},
|
||||
{
|
||||
id: 'legal-footer',
|
||||
name: 'Legal Footer',
|
||||
text: '© @year - All Rights Reserved\n@filename - Page @page_number',
|
||||
position: 2, // bottom center
|
||||
},
|
||||
{
|
||||
id: 'european-date',
|
||||
name: 'European Date (DD/MM/YYYY)',
|
||||
text: '@date{dd/MM/yyyy}',
|
||||
position: 9, // top right
|
||||
},
|
||||
{
|
||||
id: 'timestamp',
|
||||
name: 'Timestamp',
|
||||
text: '@date{dd/MM/yyyy HH:mm}',
|
||||
position: 9, // top right
|
||||
},
|
||||
];
|
||||
|
||||
const resolveVariablesForPreview = (text: string, filename?: string): string => {
|
||||
const now = new Date();
|
||||
const pad = (n: number) => String(n).padStart(2, '0');
|
||||
|
||||
const ESCAPED_AT_PLACEHOLDER = '\uE000ESCAPED_AT\uE000';
|
||||
let result = text.replace(/@@/g, ESCAPED_AT_PLACEHOLDER);
|
||||
|
||||
const actualFilename = filename || 'sample-document.pdf';
|
||||
const filenameWithoutExt = actualFilename.includes('.')
|
||||
? actualFilename.substring(0, actualFilename.lastIndexOf('.'))
|
||||
: actualFilename;
|
||||
|
||||
const sampleData: Record<string, string> = {
|
||||
'@datetime': `${now.getFullYear()}-${pad(now.getMonth() + 1)}-${pad(now.getDate())} ${pad(now.getHours())}:${pad(now.getMinutes())}:${pad(now.getSeconds())}`,
|
||||
'@date': `${now.getFullYear()}-${pad(now.getMonth() + 1)}-${pad(now.getDate())}`,
|
||||
'@time': `${pad(now.getHours())}:${pad(now.getMinutes())}:${pad(now.getSeconds())}`,
|
||||
'@year': String(now.getFullYear()),
|
||||
'@month': pad(now.getMonth() + 1),
|
||||
'@day': pad(now.getDate()),
|
||||
// Page info - cannot be previewed, show placeholder
|
||||
'@page_number': '?',
|
||||
'@page': '?',
|
||||
'@total_pages': '?',
|
||||
'@page_count': '?',
|
||||
// Filename - use actual file if provided
|
||||
'@filename': filenameWithoutExt,
|
||||
'@filename_full': actualFilename,
|
||||
// Metadata - cannot be read from PDF in frontend, show placeholder
|
||||
'@author': '?',
|
||||
'@title': '?',
|
||||
'@subject': '?',
|
||||
// UUID - will be random each time
|
||||
'@uuid': '????????',
|
||||
};
|
||||
|
||||
result = result.replace(/@date\{([^}]+)\}/g, (match, format) => {
|
||||
try {
|
||||
return format
|
||||
.replace(/yyyy/g, String(now.getFullYear()))
|
||||
.replace(/yy/g, String(now.getFullYear()).slice(-2))
|
||||
.replace(/MMMM/g, now.toLocaleString('default', { month: 'long' }))
|
||||
.replace(/MMM/g, now.toLocaleString('default', { month: 'short' }))
|
||||
.replace(/MM/g, pad(now.getMonth() + 1))
|
||||
.replace(/dd/g, pad(now.getDate()))
|
||||
.replace(/HH/g, pad(now.getHours()))
|
||||
.replace(/hh/g, pad(now.getHours() % 12 || 12))
|
||||
.replace(/mm/g, pad(now.getMinutes()))
|
||||
.replace(/ss/g, pad(now.getSeconds()));
|
||||
} catch {
|
||||
return match;
|
||||
}
|
||||
});
|
||||
|
||||
Object.entries(sampleData).forEach(([key, value]) => {
|
||||
result = result.split(key).join(value);
|
||||
});
|
||||
|
||||
result = result.replace(new RegExp(ESCAPED_AT_PLACEHOLDER, 'g'), '@');
|
||||
|
||||
result = result.replace(/\\n/g, '\n');
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
interface ClickableCodeProps {
|
||||
children: React.ReactNode;
|
||||
onClick: () => void;
|
||||
block?: boolean;
|
||||
}
|
||||
|
||||
const ClickableCode = ({ children, onClick, block = false }: ClickableCodeProps) => (
|
||||
<Code
|
||||
tabIndex={0}
|
||||
role="button"
|
||||
style={{
|
||||
cursor: 'pointer',
|
||||
display: block ? 'block' : undefined,
|
||||
}}
|
||||
onClick={onClick}
|
||||
onKeyDown={(e: React.KeyboardEvent) => {
|
||||
if (e.key === 'Enter' || e.key === ' ') {
|
||||
e.preventDefault();
|
||||
onClick();
|
||||
}
|
||||
}}
|
||||
>
|
||||
{children}
|
||||
</Code>
|
||||
);
|
||||
|
||||
const StampTextPreview = ({ stampText, filename }: { stampText: string; filename?: string }) => {
|
||||
const { t } = useTranslation();
|
||||
|
||||
const resolvedText = useMemo(() => {
|
||||
if (!stampText.trim()) return '';
|
||||
return resolveVariablesForPreview(stampText, filename);
|
||||
}, [stampText, filename]);
|
||||
|
||||
if (!stampText.trim()) return null;
|
||||
|
||||
return (
|
||||
<Paper p="xs" withBorder bg="var(--mantine-color-default)">
|
||||
<Text size="xs" c="dimmed" mb={4}>{t('AddStampRequest.preview', 'Preview:')}</Text>
|
||||
<Text size="sm" style={{ whiteSpace: 'pre-wrap', fontFamily: 'monospace', wordBreak: 'break-word' }}>
|
||||
{resolvedText}
|
||||
</Text>
|
||||
</Paper>
|
||||
);
|
||||
};
|
||||
|
||||
interface StampSetupSettingsProps {
|
||||
parameters: AddStampParameters;
|
||||
onParameterChange: <K extends keyof AddStampParameters>(key: K, value: AddStampParameters[K]) => void;
|
||||
disabled?: boolean;
|
||||
filename?: string;
|
||||
}
|
||||
|
||||
const StampSetupSettings = ({ parameters, onParameterChange, disabled = false }: StampSetupSettingsProps) => {
|
||||
const StampSetupSettings = ({ parameters, onParameterChange, disabled = false, filename }: StampSetupSettingsProps) => {
|
||||
const { t } = useTranslation();
|
||||
|
||||
return (
|
||||
@@ -41,14 +192,172 @@ const StampSetupSettings = ({ parameters, onParameterChange, disabled = false }:
|
||||
|
||||
{parameters.stampType === 'text' && (
|
||||
<>
|
||||
{/* Template Selector - always shows placeholder, doesn't persist selection */}
|
||||
<Select
|
||||
label={t('AddStampRequest.useTemplate', 'Use Template')}
|
||||
placeholder={t('AddStampRequest.selectTemplate', 'Select a template...')}
|
||||
value={null}
|
||||
data={STAMP_TEMPLATES.map(template => ({
|
||||
value: template.id,
|
||||
label: t(`AddStampRequest.template.${template.id}`, template.name)
|
||||
}))}
|
||||
onChange={(value) => {
|
||||
const template = STAMP_TEMPLATES.find(t => t.id === value);
|
||||
if (template) {
|
||||
onParameterChange('stampText', template.text);
|
||||
onParameterChange('position', template.position as any);
|
||||
}
|
||||
}}
|
||||
clearable
|
||||
disabled={disabled}
|
||||
comboboxProps={{ withinPortal: true, zIndex: Z_INDEX_AUTOMATE_DROPDOWN }}
|
||||
/>
|
||||
|
||||
<Textarea
|
||||
label={t('AddStampRequest.stampText', 'Stamp Text')}
|
||||
description={t('AddStampRequest.stampTextDescription', 'Use dynamic variables below. Use @@ for literal @. Use \\n for new lines.')}
|
||||
value={parameters.stampText}
|
||||
onChange={(e) => onParameterChange('stampText', e.currentTarget.value)}
|
||||
autosize
|
||||
minRows={2}
|
||||
disabled={disabled}
|
||||
/>
|
||||
|
||||
{/* Live Preview */}
|
||||
<StampTextPreview stampText={parameters.stampText} filename={filename} />
|
||||
|
||||
<Accordion variant="contained" radius="sm">
|
||||
<Accordion.Item value="variables">
|
||||
<Accordion.Control>
|
||||
<Group gap="xs">
|
||||
<Text size="sm" fw={500}>{t('AddStampRequest.dynamicVariables', 'Dynamic Variables')}</Text>
|
||||
<Badge size="xs" variant="light" color="blue">{t('AddStampRequest.clickToExpand', 'Click to expand')}</Badge>
|
||||
</Group>
|
||||
</Accordion.Control>
|
||||
<Accordion.Panel>
|
||||
<Stack gap="xs">
|
||||
<Text size="xs" c="dimmed" mb="xs">
|
||||
{t('AddStampRequest.variablesHelp', 'Click on any variable to insert it into your stamp text. Use @@ for literal @.')}
|
||||
</Text>
|
||||
<Box>
|
||||
<Text size="xs" fw={600} mb={4}>{t('AddStampRequest.dateTimeVars', 'Date & Time')}</Text>
|
||||
<Group gap="xs">
|
||||
<ClickableCode onClick={() => onParameterChange('stampText', parameters.stampText + '@date')}>
|
||||
@date
|
||||
</ClickableCode>
|
||||
<Text size="xs" c="dimmed">— {t('AddStampRequest.dateDesc', 'Current date')} (YYYY-MM-DD)</Text>
|
||||
</Group>
|
||||
<Group gap="xs" mt={4}>
|
||||
<ClickableCode onClick={() => onParameterChange('stampText', parameters.stampText + '@time')}>
|
||||
@time
|
||||
</ClickableCode>
|
||||
<Text size="xs" c="dimmed">— {t('AddStampRequest.timeDesc', 'Current time')} (HH:mm:ss)</Text>
|
||||
</Group>
|
||||
<Group gap="xs" mt={4}>
|
||||
<ClickableCode onClick={() => onParameterChange('stampText', parameters.stampText + '@datetime')}>
|
||||
@datetime
|
||||
</ClickableCode>
|
||||
<Text size="xs" c="dimmed">— {t('AddStampRequest.datetimeDesc', 'Date and time combined')}</Text>
|
||||
</Group>
|
||||
<Group gap="xs" mt={4}>
|
||||
<ClickableCode onClick={() => onParameterChange('stampText', parameters.stampText + '@date{dd/MM/yyyy}')}>
|
||||
@date{format}
|
||||
</ClickableCode>
|
||||
<Text size="xs" c="dimmed">— {t('AddStampRequest.customDateDesc', 'Custom format')}</Text>
|
||||
</Group>
|
||||
<Group gap="xs" mt={4}>
|
||||
<ClickableCode onClick={() => onParameterChange('stampText', parameters.stampText + '@year')}>
|
||||
@year
|
||||
</ClickableCode>
|
||||
<ClickableCode onClick={() => onParameterChange('stampText', parameters.stampText + '@month')}>
|
||||
@month
|
||||
</ClickableCode>
|
||||
<ClickableCode onClick={() => onParameterChange('stampText', parameters.stampText + '@day')}>
|
||||
@day
|
||||
</ClickableCode>
|
||||
<Text size="xs" c="dimmed">— {t('AddStampRequest.yearMonthDayDesc', 'Individual date parts')}</Text>
|
||||
</Group>
|
||||
</Box>
|
||||
<Divider my="xs" />
|
||||
<Box>
|
||||
<Text size="xs" fw={600} mb={4}>{t('AddStampRequest.pageVars', 'Page Information')}</Text>
|
||||
<Group gap="xs">
|
||||
<ClickableCode onClick={() => onParameterChange('stampText', parameters.stampText + '@page_number')}>
|
||||
@page_number
|
||||
</ClickableCode>
|
||||
<Text size="xs" c="dimmed">— {t('AddStampRequest.pageNumberDesc', 'Current page number')}</Text>
|
||||
</Group>
|
||||
<Group gap="xs" mt={4}>
|
||||
<ClickableCode onClick={() => onParameterChange('stampText', parameters.stampText + '@total_pages')}>
|
||||
@total_pages
|
||||
</ClickableCode>
|
||||
<Text size="xs" c="dimmed">— {t('AddStampRequest.totalPagesDesc', 'Total number of pages')}</Text>
|
||||
</Group>
|
||||
</Box>
|
||||
<Divider my="xs" />
|
||||
<Box>
|
||||
<Text size="xs" fw={600} mb={4}>{t('AddStampRequest.fileVars', 'File Information')}</Text>
|
||||
<Group gap="xs">
|
||||
<ClickableCode onClick={() => onParameterChange('stampText', parameters.stampText + '@filename')}>
|
||||
@filename
|
||||
</ClickableCode>
|
||||
<Text size="xs" c="dimmed">— {t('AddStampRequest.filenameDesc', 'Filename without extension')}</Text>
|
||||
</Group>
|
||||
<Group gap="xs" mt={4}>
|
||||
<ClickableCode onClick={() => onParameterChange('stampText', parameters.stampText + '@filename_full')}>
|
||||
@filename_full
|
||||
</ClickableCode>
|
||||
<Text size="xs" c="dimmed">— {t('AddStampRequest.filenameFullDesc', 'Filename with extension')}</Text>
|
||||
</Group>
|
||||
</Box>
|
||||
<Divider my="xs" />
|
||||
<Box>
|
||||
<Text size="xs" fw={600} mb={4}>{t('AddStampRequest.metadataVars', 'Document Metadata')}</Text>
|
||||
<Group gap="xs">
|
||||
<ClickableCode onClick={() => onParameterChange('stampText', parameters.stampText + '@author')}>
|
||||
@author
|
||||
</ClickableCode>
|
||||
<ClickableCode onClick={() => onParameterChange('stampText', parameters.stampText + '@title')}>
|
||||
@title
|
||||
</ClickableCode>
|
||||
<ClickableCode onClick={() => onParameterChange('stampText', parameters.stampText + '@subject')}>
|
||||
@subject
|
||||
</ClickableCode>
|
||||
</Group>
|
||||
<Text size="xs" c="dimmed" mt={4}>— {t('AddStampRequest.metadataDesc', 'From PDF document properties')}</Text>
|
||||
</Box>
|
||||
<Divider my="xs" />
|
||||
<Box>
|
||||
<Text size="xs" fw={600} mb={4}>{t('AddStampRequest.otherVars', 'Other')}</Text>
|
||||
<Group gap="xs">
|
||||
<ClickableCode onClick={() => onParameterChange('stampText', parameters.stampText + '@uuid')}>
|
||||
@uuid
|
||||
</ClickableCode>
|
||||
<Text size="xs" c="dimmed">— {t('AddStampRequest.uuidDesc', 'Short unique identifier (8 chars)')}</Text>
|
||||
</Group>
|
||||
</Box>
|
||||
<Divider my="xs" />
|
||||
<Box>
|
||||
<Text size="xs" fw={600} mb={4}>{t('AddStampRequest.examples', 'Examples')}</Text>
|
||||
<Stack gap={4}>
|
||||
<ClickableCode block onClick={() => onParameterChange('stampText', 'Page @page_number of @total_pages')}>
|
||||
Page @page_number of @total_pages
|
||||
</ClickableCode>
|
||||
<ClickableCode block onClick={() => onParameterChange('stampText', 'Created: @date{dd/MM/yyyy HH:mm}')}>
|
||||
Created: @date{dd/MM/yyyy HH:mm}
|
||||
</ClickableCode>
|
||||
<ClickableCode block onClick={() => onParameterChange('stampText', '© @year @author')}>
|
||||
© @year @author
|
||||
</ClickableCode>
|
||||
<ClickableCode block onClick={() => onParameterChange('stampText', '@filename\\n@date')}>
|
||||
@filename\n@date ({t('AddStampRequest.multiLine', 'multi-line')})
|
||||
</ClickableCode>
|
||||
</Stack>
|
||||
</Box>
|
||||
</Stack>
|
||||
</Accordion.Panel>
|
||||
</Accordion.Item>
|
||||
</Accordion>
|
||||
<Select
|
||||
label={t('AddStampRequest.alphabet', 'Alphabet')}
|
||||
value={parameters.alphabet}
|
||||
|
||||
@@ -22,7 +22,7 @@ export const defaultParameters: AddStampParameters = {
|
||||
stampType: 'text',
|
||||
stampText: '',
|
||||
alphabet: 'roman',
|
||||
fontSize: 80,
|
||||
fontSize: 40,
|
||||
rotation: 0,
|
||||
opacity: 50,
|
||||
position: 5,
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user