scitex 2.13.0__py3-none-any.whl → 2.15.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (1429) hide show
  1. scitex/__init__.py +80 -2
  2. scitex/__version__.py +11 -8
  3. scitex/_env_loader.py +156 -0
  4. scitex/_mcp_resources/__init__.py +37 -0
  5. scitex/_mcp_resources/_cheatsheet.py +135 -0
  6. scitex/_mcp_resources/_figrecipe.py +138 -0
  7. scitex/_mcp_resources/_formats.py +102 -0
  8. scitex/_mcp_resources/_modules.py +337 -0
  9. scitex/_mcp_resources/_session.py +149 -0
  10. scitex/_mcp_tools/__init__.py +40 -0
  11. scitex/_mcp_tools/audio.py +200 -0
  12. scitex/_mcp_tools/canvas.py +128 -0
  13. scitex/_mcp_tools/capture.py +174 -0
  14. scitex/_mcp_tools/diagram.py +22 -0
  15. scitex/_mcp_tools/introspect.py +191 -0
  16. scitex/_mcp_tools/plt.py +305 -0
  17. scitex/_mcp_tools/scholar.py +447 -0
  18. scitex/_mcp_tools/social.py +244 -0
  19. scitex/_mcp_tools/stats.py +206 -0
  20. scitex/_mcp_tools/template.py +66 -0
  21. scitex/_mcp_tools/ui.py +80 -0
  22. scitex/_mcp_tools/writer.py +37 -0
  23. scitex/ai/_gen_ai/_PARAMS.py +10 -7
  24. scitex/ai/classification/reporters/_ClassificationReporter.py +0 -0
  25. scitex/ai/classification/reporters/_SingleClassificationReporter.py +45 -1603
  26. scitex/ai/classification/reporters/_mixins/__init__.py +36 -0
  27. scitex/ai/classification/reporters/_mixins/_constants.py +67 -0
  28. scitex/ai/classification/reporters/_mixins/_cv_summary.py +387 -0
  29. scitex/ai/classification/reporters/_mixins/_feature_importance.py +119 -0
  30. scitex/ai/classification/reporters/_mixins/_metrics.py +275 -0
  31. scitex/ai/classification/reporters/_mixins/_plotting.py +179 -0
  32. scitex/ai/classification/reporters/_mixins/_reports.py +153 -0
  33. scitex/ai/classification/reporters/_mixins/_storage.py +160 -0
  34. scitex/ai/classification/timeseries/_TimeSeriesBlockingSplit.py +0 -0
  35. scitex/ai/classification/timeseries/_TimeSeriesCalendarSplit.py +0 -0
  36. scitex/ai/classification/timeseries/_TimeSeriesSlidingWindowSplit.py +0 -0
  37. scitex/ai/classification/timeseries/_TimeSeriesSlidingWindowSplit_v01-not-using-n_splits.py +0 -0
  38. scitex/ai/classification/timeseries/_TimeSeriesStratifiedSplit.py +0 -0
  39. scitex/ai/classification/timeseries/_normalize_timestamp.py +0 -0
  40. scitex/ai/metrics/_calc_seizure_prediction_metrics.py +0 -0
  41. scitex/ai/plt/_plot_feature_importance.py +0 -0
  42. scitex/ai/plt/_plot_learning_curve.py +0 -0
  43. scitex/ai/plt/_plot_optuna_study.py +0 -0
  44. scitex/ai/plt/_plot_pre_rec_curve.py +0 -0
  45. scitex/ai/plt/_plot_roc_curve.py +0 -0
  46. scitex/ai/plt/_stx_conf_mat.py +0 -0
  47. scitex/ai/training/_LearningCurveLogger.py +0 -0
  48. scitex/audio/README.md +88 -7
  49. scitex/audio/__init__.py +127 -60
  50. scitex/audio/__main__.py +17 -21
  51. scitex/audio/_branding.py +185 -0
  52. scitex/audio/_mcp/__init__.py +36 -0
  53. scitex/audio/_mcp/handlers.py +419 -0
  54. scitex/audio/_mcp/speak_handlers.py +238 -0
  55. scitex/audio/_mcp/tool_schemas.py +203 -0
  56. scitex/audio/_relay.py +225 -0
  57. scitex/audio/engines/elevenlabs_engine.py +6 -1
  58. scitex/audio/mcp_server.py +355 -337
  59. scitex/bridge/_figrecipe.py +40 -8
  60. scitex/bridge/_stats_plt.py +2 -4
  61. scitex/bridge/_stats_vis.py +7 -5
  62. scitex/browser/automation/CookieHandler.py +0 -0
  63. scitex/browser/collaboration/__init__.py +0 -1
  64. scitex/browser/core/BrowserMixin.py +0 -0
  65. scitex/browser/core/ChromeProfileManager.py +10 -3
  66. scitex/browser/debugging/_browser_logger.py +6 -9
  67. scitex/browser/debugging/_highlight_element.py +0 -0
  68. scitex/browser/debugging/_show_grid.py +0 -0
  69. scitex/browser/interaction/click_center.py +0 -0
  70. scitex/browser/interaction/click_with_fallbacks.py +0 -0
  71. scitex/browser/interaction/close_popups.py +0 -0
  72. scitex/browser/interaction/fill_with_fallbacks.py +0 -0
  73. scitex/browser/pdf/click_download_for_chrome_pdf_viewer.py +0 -0
  74. scitex/browser/pdf/detect_chrome_pdf_viewer.py +0 -0
  75. scitex/browser/stealth/HumanBehavior.py +0 -0
  76. scitex/browser/stealth/StealthManager.py +0 -0
  77. scitex/canvas/README.md +1 -1
  78. scitex/canvas/_mcp/__init__.py +4 -0
  79. scitex/canvas/_mcp/handlers.py +372 -0
  80. scitex/canvas/_mcp/tool_schemas.py +219 -0
  81. scitex/canvas/editor/_dearpygui/__init__.py +25 -0
  82. scitex/canvas/editor/_dearpygui/_editor.py +147 -0
  83. scitex/canvas/editor/_dearpygui/_handlers.py +476 -0
  84. scitex/canvas/editor/_dearpygui/_panels/__init__.py +17 -0
  85. scitex/canvas/editor/_dearpygui/_panels/_control.py +119 -0
  86. scitex/canvas/editor/_dearpygui/_panels/_element_controls.py +190 -0
  87. scitex/canvas/editor/_dearpygui/_panels/_preview.py +43 -0
  88. scitex/canvas/editor/_dearpygui/_panels/_sections.py +390 -0
  89. scitex/canvas/editor/_dearpygui/_plotting.py +187 -0
  90. scitex/canvas/editor/_dearpygui/_rendering.py +504 -0
  91. scitex/canvas/editor/_dearpygui/_selection.py +295 -0
  92. scitex/canvas/editor/_dearpygui/_state.py +93 -0
  93. scitex/canvas/editor/_dearpygui/_utils.py +61 -0
  94. scitex/canvas/editor/flask_editor/templates/__init__.py +32 -70
  95. scitex/canvas/mcp_server.py +2 -2
  96. scitex/capture/__init__.py +0 -1
  97. scitex/capture/_mcp/__init__.py +11 -0
  98. scitex/capture/_mcp/handlers.py +438 -0
  99. scitex/capture/_mcp/tool_schemas.py +270 -0
  100. scitex/cli/__init__.py +44 -2
  101. scitex/cli/audio.py +150 -3
  102. scitex/cli/browser.py +310 -0
  103. scitex/cli/capture.py +14 -3
  104. scitex/cli/introspect.py +443 -0
  105. scitex/cli/main.py +230 -103
  106. scitex/cli/mcp.py +362 -0
  107. scitex/cli/repro.py +18 -0
  108. scitex/cli/resource.py +18 -0
  109. scitex/cli/scholar/__init__.py +97 -0
  110. scitex/cli/scholar/_crossref_scitex.py +296 -0
  111. scitex/cli/scholar/_fetch.py +369 -0
  112. scitex/cli/scholar/_jobs.py +306 -0
  113. scitex/cli/scholar/_library.py +152 -0
  114. scitex/cli/scholar/_utils.py +35 -0
  115. scitex/cli/social.py +314 -0
  116. scitex/cli/stats.py +18 -0
  117. scitex/cli/template.py +18 -0
  118. scitex/cli/tex.py +18 -0
  119. scitex/cli/writer.py +190 -20
  120. scitex/compat/__init__.py +74 -0
  121. scitex/config/README.md +1 -1
  122. scitex/config/__init__.py +16 -2
  123. scitex/config/_env_registry.py +191 -0
  124. scitex/config/default.yaml +31 -0
  125. scitex/cv/__init__.py +87 -0
  126. scitex/cv/_draw.py +236 -0
  127. scitex/cv/_filters.py +217 -0
  128. scitex/cv/_io.py +157 -0
  129. scitex/cv/_transform.py +184 -0
  130. scitex/dev/__init__.py +2 -0
  131. scitex/dev/cv/__init__.py +60 -0
  132. scitex/dev/cv/_compose.py +330 -0
  133. scitex/dev/cv/_title_card.py +351 -0
  134. scitex/dev/plt/__init__.py +0 -0
  135. scitex/dev/plt/demo_plotters/__init__.py +0 -0
  136. scitex/dev/plt/mpl/get_dir_ax.py +0 -0
  137. scitex/dev/plt/mpl/get_signatures.py +0 -0
  138. scitex/dev/plt/mpl/get_signatures_details.py +0 -0
  139. scitex/diagram/__init__.py +42 -19
  140. scitex/diagram/mcp_server.py +13 -125
  141. scitex/dt/_normalize_timestamp.py +0 -0
  142. scitex/gen/__init__.py +0 -0
  143. scitex/gen/misc.py +0 -0
  144. scitex/git/_init.py +2 -2
  145. scitex/git/_session.py +0 -0
  146. scitex/introspect/__init__.py +75 -0
  147. scitex/introspect/_call_graph.py +303 -0
  148. scitex/introspect/_class_hierarchy.py +163 -0
  149. scitex/introspect/_core.py +42 -0
  150. scitex/introspect/_docstring.py +131 -0
  151. scitex/introspect/_examples.py +113 -0
  152. scitex/introspect/_imports.py +271 -0
  153. scitex/introspect/_mcp/__init__.py +37 -0
  154. scitex/introspect/_mcp/handlers.py +208 -0
  155. scitex/introspect/_members.py +151 -0
  156. scitex/introspect/_resolve.py +89 -0
  157. scitex/introspect/_signature.py +131 -0
  158. scitex/introspect/_source.py +80 -0
  159. scitex/introspect/_type_hints.py +172 -0
  160. scitex/io/bundle/README.md +1 -1
  161. scitex/io/bundle/kinds/__init__.py +0 -0
  162. scitex/io/bundle/kinds/_figure/__init__.py +0 -0
  163. scitex/io/bundle/kinds/_plot/__init__.py +0 -0
  164. scitex/io/bundle/kinds/_shape/__init__.py +0 -0
  165. scitex/io/bundle/kinds/_text/__init__.py +0 -0
  166. scitex/logging/_context.py +5 -4
  167. scitex/mcp_server.py +170 -145
  168. scitex/plt/__init__.py +249 -548
  169. scitex/plt/_figrecipe_integration.py +121 -0
  170. scitex/plt/_subplots/_AxisWrapperMixins/_SeabornMixin/_wrappers.py +5 -10
  171. scitex/plt/_subplots/_FigWrapper.py +139 -88
  172. scitex/plt/_subplots/_export_as_csv_formatters/_format_pcolormesh.py +0 -0
  173. scitex/plt/_subplots/_export_as_csv_formatters/_format_stackplot.py +0 -0
  174. scitex/plt/docs/EXTERNAL_PACKAGE_BRANDING.md +149 -0
  175. scitex/plt/gallery/README.md +1 -1
  176. scitex/plt/styles/_plot_postprocess.py +35 -117
  177. scitex/plt/styles/_postprocess_helpers.py +158 -0
  178. scitex/plt/utils/_hitmap/__init__.py +82 -0
  179. scitex/plt/utils/_hitmap/_artist_extraction.py +343 -0
  180. scitex/plt/utils/_hitmap/_color_application.py +346 -0
  181. scitex/plt/utils/_hitmap/_color_conversion.py +121 -0
  182. scitex/plt/utils/_hitmap/_constants.py +40 -0
  183. scitex/plt/utils/_hitmap/_hitmap_core.py +334 -0
  184. scitex/plt/utils/_hitmap/_path_extraction.py +357 -0
  185. scitex/plt/utils/_hitmap/_query.py +113 -0
  186. scitex/plt/utils/_hitmap.py +46 -1616
  187. scitex/plt/utils/_metadata/__init__.py +80 -0
  188. scitex/plt/utils/_metadata/_artists/__init__.py +25 -0
  189. scitex/plt/utils/_metadata/_artists/_base.py +195 -0
  190. scitex/plt/utils/_metadata/_artists/_collections.py +356 -0
  191. scitex/plt/utils/_metadata/_artists/_extract.py +57 -0
  192. scitex/plt/utils/_metadata/_artists/_images.py +80 -0
  193. scitex/plt/utils/_metadata/_artists/_lines.py +261 -0
  194. scitex/plt/utils/_metadata/_artists/_patches.py +247 -0
  195. scitex/plt/utils/_metadata/_artists/_text.py +106 -0
  196. scitex/plt/utils/_metadata/_csv.py +416 -0
  197. scitex/plt/utils/_metadata/_detect.py +225 -0
  198. scitex/plt/utils/_metadata/_legend.py +127 -0
  199. scitex/plt/utils/_metadata/_rounding.py +117 -0
  200. scitex/plt/utils/_metadata/_verification.py +202 -0
  201. scitex/repro/_RandomStateManager.py +0 -0
  202. scitex/repro/_gen_ID.py +0 -0
  203. scitex/repro/_gen_timestamp.py +0 -0
  204. scitex/repro/_hash_array.py +0 -0
  205. scitex/schema/README.md +1 -1
  206. scitex/scholar/__init__.py +8 -0
  207. scitex/scholar/_mcp/__init__.py +4 -0
  208. scitex/scholar/_mcp/all_handlers.py +74 -0
  209. scitex/scholar/_mcp/crossref_handlers.py +265 -0
  210. scitex/scholar/_mcp/handlers.py +1478 -0
  211. scitex/scholar/_mcp/job_handlers.py +172 -0
  212. scitex/scholar/_mcp/job_tool_schemas.py +166 -0
  213. scitex/scholar/_mcp/tool_schemas.py +505 -0
  214. scitex/scholar/auth/core/BrowserAuthenticator.py +126 -9
  215. scitex/scholar/auth/providers/OpenAthensAuthenticator.py +55 -210
  216. scitex/scholar/auth/providers/_notifications.py +417 -0
  217. scitex/scholar/auth/sso/BaseSSOAutomator.py +36 -17
  218. scitex/scholar/auth/sso/UniversityOfMelbourneSSOAutomator.py +8 -15
  219. scitex/scholar/citation_graph/__init__.py +0 -1
  220. scitex/scholar/config/core/_PathManager.py +5 -1
  221. scitex/scholar/config/default.yaml +1 -1
  222. scitex/scholar/core/Paper.py +19 -41
  223. scitex/scholar/core/Scholar.py +64 -1688
  224. scitex/scholar/core/_mixins/__init__.py +36 -0
  225. scitex/scholar/core/_mixins/_enrichers.py +270 -0
  226. scitex/scholar/core/_mixins/_library_handlers.py +100 -0
  227. scitex/scholar/core/_mixins/_loaders.py +103 -0
  228. scitex/scholar/core/_mixins/_pdf_download.py +375 -0
  229. scitex/scholar/core/_mixins/_pipeline.py +312 -0
  230. scitex/scholar/core/_mixins/_project_handlers.py +125 -0
  231. scitex/scholar/core/_mixins/_savers.py +69 -0
  232. scitex/scholar/core/_mixins/_search.py +103 -0
  233. scitex/scholar/core/_mixins/_services.py +88 -0
  234. scitex/scholar/core/_mixins/_url_finding.py +105 -0
  235. scitex/scholar/core/journal_normalizer.py +36 -25
  236. scitex/scholar/crossref_scitex.py +367 -0
  237. scitex/scholar/docs/EXTERNAL_PACKAGE_BRANDING.md +149 -0
  238. scitex/scholar/examples/00_run_all.sh +120 -0
  239. scitex/scholar/examples/07_storage_integration.py +0 -0
  240. scitex/scholar/impact_factor/estimation/__init__.py +0 -1
  241. scitex/scholar/impact_factor/jcr/ImpactFactorJCREngine.py +19 -6
  242. scitex/scholar/impact_factor/jcr/build_database.py +0 -0
  243. scitex/scholar/jobs/_Job.py +266 -0
  244. scitex/scholar/jobs/_JobManager.py +458 -0
  245. scitex/scholar/jobs/__init__.py +74 -0
  246. scitex/scholar/jobs/_errors.py +346 -0
  247. scitex/scholar/jobs/_executors.py +397 -0
  248. scitex/scholar/mcp_server.py +52 -2
  249. scitex/scholar/pdf_download/ScholarPDFDownloader.py +38 -416
  250. scitex/scholar/pdf_download/_cli.py +154 -0
  251. scitex/scholar/pdf_download/strategies/__init__.py +11 -8
  252. scitex/scholar/pdf_download/strategies/chrome_pdf_viewer.py +11 -11
  253. scitex/scholar/pdf_download/strategies/manual_download_fallback.py +80 -3
  254. scitex/scholar/pipelines/ScholarPipelineBibTeX.py +73 -121
  255. scitex/scholar/pipelines/ScholarPipelineParallel.py +83 -140
  256. scitex/scholar/pipelines/ScholarPipelineSearchParallel.py +11 -13
  257. scitex/scholar/pipelines/ScholarPipelineSingle.py +83 -656
  258. scitex/scholar/pipelines/_single_steps.py +465 -0
  259. scitex/scholar/storage/BibTeXHandler.py +71 -23
  260. scitex/scholar/storage/PaperIO.py +53 -18
  261. scitex/scholar/storage/_BibTeXValidator.py +571 -0
  262. scitex/scholar/storage/_LibraryManager.py +97 -1695
  263. scitex/scholar/storage/__init__.py +17 -3
  264. scitex/scholar/storage/_mixins/__init__.py +30 -0
  265. scitex/scholar/storage/_mixins/_bibtex_handlers.py +128 -0
  266. scitex/scholar/storage/_mixins/_library_operations.py +218 -0
  267. scitex/scholar/storage/_mixins/_metadata_conversion.py +226 -0
  268. scitex/scholar/storage/_mixins/_paper_saving.py +456 -0
  269. scitex/scholar/storage/_mixins/_resolution.py +376 -0
  270. scitex/scholar/storage/_mixins/_storage_helpers.py +121 -0
  271. scitex/scholar/storage/_mixins/_symlink_handlers.py +226 -0
  272. scitex/scholar/url_finder/translators/individual/cell_press.py +131 -4
  273. scitex/security/README.md +3 -3
  274. scitex/security/__init__.py +0 -1
  275. scitex/session/README.md +1 -1
  276. scitex/session/__init__.py +0 -0
  277. scitex/session/_decorator.py +0 -0
  278. scitex/session/_lifecycle.py +0 -0
  279. scitex/sh/README.md +1 -1
  280. scitex/social/__init__.py +153 -0
  281. scitex/social/docs/EXTERNAL_PACKAGE_BRANDING.md +149 -0
  282. scitex/stats/__init__.py +14 -2
  283. scitex/stats/__main__.py +2 -2
  284. scitex/stats/_figrecipe_integration.py +116 -0
  285. scitex/stats/_mcp/__init__.py +4 -0
  286. scitex/stats/_mcp/handlers.py +1191 -0
  287. scitex/stats/_mcp/tool_schemas.py +384 -0
  288. scitex/stats/auto/__init__.py +0 -1
  289. scitex/stats/correct/_correct_bonferroni.py +0 -0
  290. scitex/stats/correct/_correct_fdr.py +0 -0
  291. scitex/stats/correct/_correct_fdr_.py +0 -0
  292. scitex/stats/correct/_correct_holm.py +0 -0
  293. scitex/stats/correct/_correct_sidak.py +0 -0
  294. scitex/stats/effect_sizes/_cliffs_delta.py +0 -0
  295. scitex/stats/effect_sizes/_cohens_d.py +0 -0
  296. scitex/stats/effect_sizes/_epsilon_squared.py +0 -0
  297. scitex/stats/effect_sizes/_eta_squared.py +0 -0
  298. scitex/stats/effect_sizes/_prob_superiority.py +0 -0
  299. scitex/stats/mcp_server.py +2 -2
  300. scitex/stats/posthoc/_dunnett.py +0 -0
  301. scitex/stats/posthoc/_games_howell.py +0 -0
  302. scitex/stats/posthoc/_tukey_hsd.py +0 -0
  303. scitex/stats/power/_power.py +0 -0
  304. scitex/stats/utils/_effect_size.py +0 -0
  305. scitex/stats/utils/_formatters.py +0 -0
  306. scitex/stats/utils/_power.py +0 -0
  307. scitex/template/README.md +1 -1
  308. scitex/template/_mcp/__init__.py +4 -0
  309. scitex/template/_mcp/handlers.py +259 -0
  310. scitex/template/_mcp/tool_schemas.py +112 -0
  311. scitex/template/clone_writer_directory.py +6 -6
  312. scitex/template/mcp_server.py +2 -2
  313. scitex/ui/__init__.py +173 -0
  314. scitex/ui/_backends/__init__.py +66 -0
  315. scitex/ui/_backends/_audio.py +86 -0
  316. scitex/ui/_backends/_config.py +250 -0
  317. scitex/ui/_backends/_desktop.py +184 -0
  318. scitex/ui/_backends/_emacs.py +210 -0
  319. scitex/ui/_backends/_email.py +78 -0
  320. scitex/ui/_backends/_matplotlib.py +118 -0
  321. scitex/ui/_backends/_playwright.py +109 -0
  322. scitex/ui/_backends/_types.py +58 -0
  323. scitex/ui/_backends/_webhook.py +77 -0
  324. scitex/ui/_backends.py +37 -0
  325. scitex/ui/_mcp/__init__.py +23 -0
  326. scitex/ui/_mcp/handlers.py +260 -0
  327. scitex/ui/_mcp/tool_schemas.py +107 -0
  328. scitex/ui/mcp_server.py +151 -0
  329. scitex/utils/_email.py +85 -7
  330. scitex/utils/_notify.py +16 -5
  331. scitex/utils/_search.py +11 -9
  332. scitex/utils/_verify_scitex_format.py +0 -0
  333. scitex/writer/README.md +1 -1
  334. scitex/writer/Writer.py +110 -111
  335. scitex/writer/__init__.py +26 -48
  336. scitex/writer/_clone_writer_project.py +0 -0
  337. scitex/writer/_compile/__init__.py +5 -4
  338. scitex/writer/_compile/_compile_async.py +130 -0
  339. scitex/writer/_compile/_compile_unified.py +148 -0
  340. scitex/writer/_compile/_runner.py +2 -2
  341. scitex/writer/_compile/_validator.py +3 -3
  342. scitex/writer/_compile/manuscript.py +1 -1
  343. scitex/writer/_compile/revision.py +1 -1
  344. scitex/writer/_compile/supplementary.py +1 -1
  345. scitex/writer/_dataclasses/config/_WriterConfig.py +175 -0
  346. scitex/writer/_dataclasses/contents/_ManuscriptContents.py +236 -0
  347. scitex/writer/_dataclasses/core/_Document.py +146 -0
  348. scitex/writer/_dataclasses/core/_DocumentSection.py +546 -0
  349. scitex/writer/_dataclasses/results/_CompilationResult.py +165 -0
  350. scitex/writer/_dataclasses/results/_LaTeXIssue.py +102 -0
  351. scitex/writer/_dataclasses/tree/MINIMUM_FILES.md +121 -0
  352. scitex/writer/_mcp/__init__.py +4 -0
  353. scitex/writer/_mcp/handlers.py +32 -0
  354. scitex/writer/_mcp/tool_schemas.py +33 -0
  355. scitex/writer/_project/_trees.py +2 -2
  356. scitex/writer/utils/__init__.py +19 -2
  357. scitex/writer/utils/_converters.py +635 -0
  358. scitex/writer/utils/_parse_latex_logs.py +1 -1
  359. scitex/writer/utils/_verify_tree_structure.py +205 -0
  360. scitex-2.15.1.dist-info/METADATA +648 -0
  361. scitex-2.15.1.dist-info/RECORD +2553 -0
  362. scitex-2.15.1.dist-info/entry_points.txt +12 -0
  363. scitex/audio/_mcp_handlers.py +0 -256
  364. scitex/audio/_mcp_tool_schemas.py +0 -203
  365. scitex/canvas/_mcp_handlers.py +0 -372
  366. scitex/canvas/_mcp_tool_schemas.py +0 -219
  367. scitex/canvas/editor/flask_editor/templates/_scripts.py +0 -4933
  368. scitex/canvas/editor/flask_editor/templates/_styles.py +0 -1658
  369. scitex/capture/mcp_handlers.py +0 -401
  370. scitex/capture/mcp_tool_defs.py +0 -192
  371. scitex/capture/mcp_tools.py +0 -241
  372. scitex/capture/mcp_utils.py +0 -30
  373. scitex/cli/scholar.py +0 -313
  374. scitex/diagram/_compile.py +0 -312
  375. scitex/diagram/_diagram.py +0 -355
  376. scitex/diagram/_mcp_handlers.py +0 -400
  377. scitex/diagram/_mcp_tool_schemas.py +0 -157
  378. scitex/diagram/_presets.py +0 -173
  379. scitex/diagram/_schema.py +0 -182
  380. scitex/diagram/_split.py +0 -278
  381. scitex/plt/_mcp_handlers.py +0 -361
  382. scitex/plt/_mcp_tool_schemas.py +0 -169
  383. scitex/plt/mcp_server.py +0 -205
  384. scitex/scholar/.legacy/Scholar.py +0 -400
  385. scitex/scholar/.legacy/_Scholar.py +0 -1763
  386. scitex/scholar/.legacy/_ScholarAPI.py +0 -316
  387. scitex/scholar/.legacy/_tmp/search_engine/_BaseSearchEngine.py +0 -101
  388. scitex/scholar/.legacy/_tmp/search_engine/_UnifiedSearcher.py +0 -392
  389. scitex/scholar/.legacy/_tmp/search_engine/__init__.py +0 -53
  390. scitex/scholar/.legacy/_tmp/search_engine/local/_LocalSearchEngine.py +0 -134
  391. scitex/scholar/.legacy/_tmp/search_engine/local/_VectorSearchEngine.py +0 -129
  392. scitex/scholar/.legacy/_tmp/search_engine/web/_ArxivSearchEngine.py +0 -279
  393. scitex/scholar/.legacy/_tmp/search_engine/web/_CrossRefSearchEngine.py +0 -319
  394. scitex/scholar/.legacy/_tmp/search_engine/web/_GoogleScholarSearchEngine.py +0 -209
  395. scitex/scholar/.legacy/_tmp/search_engine/web/_PubMedSearchEngine.py +0 -374
  396. scitex/scholar/.legacy/_tmp/search_engine/web/_SemanticScholarSearchEngine.py +0 -362
  397. scitex/scholar/.legacy/database/README.md +0 -121
  398. scitex/scholar/.legacy/database/README_CONCURRENT_ACCESS.md +0 -103
  399. scitex/scholar/.legacy/database/_DatabaseEntry.py +0 -232
  400. scitex/scholar/.legacy/database/_DatabaseIndex.py +0 -426
  401. scitex/scholar/.legacy/database/_LibraryManager.py +0 -276
  402. scitex/scholar/.legacy/database/_PaperDatabase.py +0 -543
  403. scitex/scholar/.legacy/database/_ScholarDatabaseIntegration.py +0 -391
  404. scitex/scholar/.legacy/database/_StorageIntegratedDB.py +0 -619
  405. scitex/scholar/.legacy/database/_ZoteroCompatibleDB.py +0 -1194
  406. scitex/scholar/.legacy/database/__init__.py +0 -28
  407. scitex/scholar/.legacy/database/manage.py +0 -274
  408. scitex/scholar/.legacy/lookup/_LookupIndex.py +0 -470
  409. scitex/scholar/.legacy/lookup/__init__.py +0 -22
  410. scitex/scholar/.legacy/metadata/README.md +0 -62
  411. scitex/scholar/.legacy/metadata/__init__.py +0 -1
  412. scitex/scholar/.legacy/metadata/doi/README.md +0 -368
  413. scitex/scholar/.legacy/metadata/doi/__init__.py +0 -7
  414. scitex/scholar/.legacy/metadata/doi/batch/_MetadataHandlerForBatchDOIResolution.py +0 -304
  415. scitex/scholar/.legacy/metadata/doi/batch/_ProgressManagerForBatchDOIResolution.py +0 -304
  416. scitex/scholar/.legacy/metadata/doi/batch/_SourceStatsManagerForBatchDOIResolution.py +0 -299
  417. scitex/scholar/.legacy/metadata/doi/batch/__init__.py +0 -26
  418. scitex/scholar/.legacy/metadata/doi/resolvers/_BatchDOIResolver.py +0 -586
  419. scitex/scholar/.legacy/metadata/doi/resolvers/_BibTeXDOIResolver.py +0 -609
  420. scitex/scholar/.legacy/metadata/doi/resolvers/_DOIResolver.py +0 -192
  421. scitex/scholar/.legacy/metadata/doi/resolvers/_SingleDOIResolver.py +0 -395
  422. scitex/scholar/.legacy/metadata/doi/resolvers/__init__.py +0 -2
  423. scitex/scholar/.legacy/metadata/doi/sources/.combined-SemanticScholarSource/_SemanticScholarSource.py +0 -289
  424. scitex/scholar/.legacy/metadata/doi/sources/.combined-SemanticScholarSource/_SemanticScholarSourceEnhanced.py +0 -229
  425. scitex/scholar/.legacy/metadata/doi/sources/_ArXivSource.py +0 -306
  426. scitex/scholar/.legacy/metadata/doi/sources/_BaseDOISource.py +0 -347
  427. scitex/scholar/.legacy/metadata/doi/sources/_CrossRefLocalSource.py +0 -79
  428. scitex/scholar/.legacy/metadata/doi/sources/_CrossRefSource.py +0 -225
  429. scitex/scholar/.legacy/metadata/doi/sources/_OpenAlexSource.py +0 -306
  430. scitex/scholar/.legacy/metadata/doi/sources/_PubMedSource.py +0 -302
  431. scitex/scholar/.legacy/metadata/doi/sources/_SemanticScholarSource.py +0 -341
  432. scitex/scholar/.legacy/metadata/doi/sources/_SourceManager.py +0 -317
  433. scitex/scholar/.legacy/metadata/doi/sources/_SourceResolutionStrategy.py +0 -595
  434. scitex/scholar/.legacy/metadata/doi/sources/_SourceRotationManager.py +0 -585
  435. scitex/scholar/.legacy/metadata/doi/sources/_URLDOISource.py +0 -394
  436. scitex/scholar/.legacy/metadata/doi/sources/_UnifiedSource.py +0 -412
  437. scitex/scholar/.legacy/metadata/doi/sources/__init__.py +0 -38
  438. scitex/scholar/.legacy/metadata/doi/utils/_PubMedConverter.py +0 -465
  439. scitex/scholar/.legacy/metadata/doi/utils/_RateLimitHandler.py +0 -707
  440. scitex/scholar/.legacy/metadata/doi/utils/_TextNormalizer.py +0 -587
  441. scitex/scholar/.legacy/metadata/doi/utils/_URLDOIExtractor.py +0 -278
  442. scitex/scholar/.legacy/metadata/doi/utils/__init__.py +0 -40
  443. scitex/scholar/.legacy/metadata/doi/utils/_to_complete_metadata_structure.py +0 -315
  444. scitex/scholar/.legacy/metadata/enrichment/README.md +0 -51
  445. scitex/scholar/.legacy/metadata/enrichment/_LibraryEnricher.py +0 -99
  446. scitex/scholar/.legacy/metadata/enrichment/__init__.py +0 -2
  447. scitex/scholar/.legacy/metadata/enrichment/enrichers/_ImpactFactorEnricher.py +0 -107
  448. scitex/scholar/.legacy/metadata/enrichment/enrichers/_SmartEnricher.py +0 -164
  449. scitex/scholar/.legacy/metadata/enrichment/enrichers/__init__.py +0 -4
  450. scitex/scholar/.legacy/metadata/enrichment/sources/_UnifiedMetadataSource.py +0 -126
  451. scitex/scholar/.legacy/metadata/enrichment/sources/__init__.py +0 -3
  452. scitex/scholar/.legacy/metadata/query_to_full_meta_json.py +0 -184
  453. scitex/scholar/.legacy/metadata/urls/.tmp/open_url/KNOWN_RESOLVERS.py +0 -462
  454. scitex/scholar/.legacy/metadata/urls/.tmp/open_url/README.md +0 -223
  455. scitex/scholar/.legacy/metadata/urls/.tmp/open_url/_DOIToURLResolver.py +0 -694
  456. scitex/scholar/.legacy/metadata/urls/.tmp/open_url/_OpenURLResolver.py +0 -1160
  457. scitex/scholar/.legacy/metadata/urls/.tmp/open_url/_ResolverLinkFinder.py +0 -344
  458. scitex/scholar/.legacy/metadata/urls/.tmp/open_url/__init__.py +0 -24
  459. scitex/scholar/.legacy/metadata/urls/README.md +0 -142
  460. scitex/scholar/.legacy/metadata/urls/_URLMetadataHandler.py +0 -383
  461. scitex/scholar/.legacy/metadata/urls/_ZoteroTranslatorRunner.py +0 -294
  462. scitex/scholar/.legacy/metadata/urls/__init__.py +0 -39
  463. scitex/scholar/.legacy/metadata/urls/_finder.py +0 -319
  464. scitex/scholar/.legacy/metadata/urls/_handler.py +0 -326
  465. scitex/scholar/.legacy/metadata/urls/_resolver.py +0 -287
  466. scitex/scholar/.legacy/metadata/urls/docs/CORE_URL_TYPES.md +0 -187
  467. scitex/scholar/.legacy/metadata/urls/docs/URL_SCHEMA.md +0 -223
  468. scitex/scholar/.legacy/metadata/urls/zotero_translators/.ci/.eslintrc +0 -11
  469. scitex/scholar/.legacy/metadata/urls/zotero_translators/.ci/AGPL +0 -22
  470. scitex/scholar/.legacy/metadata/urls/zotero_translators/.ci/checkDeletedTxt.sh +0 -46
  471. scitex/scholar/.legacy/metadata/urls/zotero_translators/.ci/eslint-plugin-zotero-translator/bin/teslint.js +0 -9
  472. scitex/scholar/.legacy/metadata/urls/zotero_translators/.ci/eslint-plugin-zotero-translator/index.js +0 -15
  473. scitex/scholar/.legacy/metadata/urls/zotero_translators/.ci/eslint-plugin-zotero-translator/package-lock.json +0 -151
  474. scitex/scholar/.legacy/metadata/urls/zotero_translators/.ci/eslint-plugin-zotero-translator/package.json +0 -21
  475. scitex/scholar/.legacy/metadata/urls/zotero_translators/.ci/eslint-plugin-zotero-translator/processor.js +0 -257
  476. scitex/scholar/.legacy/metadata/urls/zotero_translators/.ci/helper.sh +0 -29
  477. scitex/scholar/.legacy/metadata/urls/zotero_translators/.ci/lint.sh +0 -12
  478. scitex/scholar/.legacy/metadata/urls/zotero_translators/.ci/pull-request-check/check-pull-request.sh +0 -39
  479. scitex/scholar/.legacy/metadata/urls/zotero_translators/.ci/pull-request-check/selenium-test.js +0 -147
  480. scitex/scholar/.legacy/metadata/urls/zotero_translators/.ci/pull-request-check/translator-server.js +0 -72
  481. scitex/scholar/.legacy/metadata/urls/zotero_translators/.ci/updateTypes.mjs +0 -75
  482. scitex/scholar/.legacy/metadata/urls/zotero_translators/.editorconfig +0 -8
  483. scitex/scholar/.legacy/metadata/urls/zotero_translators/.eslintrc +0 -70
  484. scitex/scholar/.legacy/metadata/urls/zotero_translators/ABC News Australia.js +0 -224
  485. scitex/scholar/.legacy/metadata/urls/zotero_translators/ACLS Humanities EBook.js +0 -165
  486. scitex/scholar/.legacy/metadata/urls/zotero_translators/ACLWeb.js +0 -600
  487. scitex/scholar/.legacy/metadata/urls/zotero_translators/ACM Digital Library.js +0 -710
  488. scitex/scholar/.legacy/metadata/urls/zotero_translators/ACS Publications.js +0 -633
  489. scitex/scholar/.legacy/metadata/urls/zotero_translators/ADS Bibcode.js +0 -664
  490. scitex/scholar/.legacy/metadata/urls/zotero_translators/AEA Web.js +0 -450
  491. scitex/scholar/.legacy/metadata/urls/zotero_translators/AGRIS.js +0 -311
  492. scitex/scholar/.legacy/metadata/urls/zotero_translators/AIP.js +0 -295
  493. scitex/scholar/.legacy/metadata/urls/zotero_translators/AMS Journals.js +0 -136
  494. scitex/scholar/.legacy/metadata/urls/zotero_translators/AMS MathSciNet (Legacy).js +0 -313
  495. scitex/scholar/.legacy/metadata/urls/zotero_translators/AMS MathSciNet.js +0 -288
  496. scitex/scholar/.legacy/metadata/urls/zotero_translators/APA PsycNET.js +0 -915
  497. scitex/scholar/.legacy/metadata/urls/zotero_translators/APN.ru.js +0 -132
  498. scitex/scholar/.legacy/metadata/urls/zotero_translators/APS-Physics.js +0 -204
  499. scitex/scholar/.legacy/metadata/urls/zotero_translators/APS.js +0 -542
  500. scitex/scholar/.legacy/metadata/urls/zotero_translators/ARTFL Encyclopedie.js +0 -283
  501. scitex/scholar/.legacy/metadata/urls/zotero_translators/ARTnews.js +0 -155
  502. scitex/scholar/.legacy/metadata/urls/zotero_translators/ARTstor.js +0 -619
  503. scitex/scholar/.legacy/metadata/urls/zotero_translators/ASCE.js +0 -199
  504. scitex/scholar/.legacy/metadata/urls/zotero_translators/ASCO Meeting Library.js +0 -153
  505. scitex/scholar/.legacy/metadata/urls/zotero_translators/ASTIS.js +0 -337
  506. scitex/scholar/.legacy/metadata/urls/zotero_translators/ATS International Journal.js +0 -290
  507. scitex/scholar/.legacy/metadata/urls/zotero_translators/Access Engineering.js +0 -384
  508. scitex/scholar/.legacy/metadata/urls/zotero_translators/Access Medicine.js +0 -343
  509. scitex/scholar/.legacy/metadata/urls/zotero_translators/Access Science.js +0 -391
  510. scitex/scholar/.legacy/metadata/urls/zotero_translators/Adam Matthew Digital.js +0 -405
  511. scitex/scholar/.legacy/metadata/urls/zotero_translators/Agencia del ISBN.js +0 -77
  512. scitex/scholar/.legacy/metadata/urls/zotero_translators/Ahval News.js +0 -309
  513. scitex/scholar/.legacy/metadata/urls/zotero_translators/Air University Journals.js +0 -236
  514. scitex/scholar/.legacy/metadata/urls/zotero_translators/Airiti.js +0 -423
  515. scitex/scholar/.legacy/metadata/urls/zotero_translators/Alexander Street Press.js +0 -198
  516. scitex/scholar/.legacy/metadata/urls/zotero_translators/AllAfrica.js +0 -291
  517. scitex/scholar/.legacy/metadata/urls/zotero_translators/Alsharekh.js +0 -242
  518. scitex/scholar/.legacy/metadata/urls/zotero_translators/AlterNet.js +0 -134
  519. scitex/scholar/.legacy/metadata/urls/zotero_translators/Aluka.js +0 -261
  520. scitex/scholar/.legacy/metadata/urls/zotero_translators/Amazon.js +0 -1043
  521. scitex/scholar/.legacy/metadata/urls/zotero_translators/American Archive of Public Broadcasting.js +0 -592
  522. scitex/scholar/.legacy/metadata/urls/zotero_translators/American Institute of Aeronautics and Astronautics.js +0 -210
  523. scitex/scholar/.legacy/metadata/urls/zotero_translators/American Prospect.js +0 -114
  524. scitex/scholar/.legacy/metadata/urls/zotero_translators/Ancestry.com US Federal Census.js +0 -164
  525. scitex/scholar/.legacy/metadata/urls/zotero_translators/Annual Reviews.js +0 -329
  526. scitex/scholar/.legacy/metadata/urls/zotero_translators/Antikvarium.hu.js +0 -280
  527. scitex/scholar/.legacy/metadata/urls/zotero_translators/AquaDocs.js +0 -390
  528. scitex/scholar/.legacy/metadata/urls/zotero_translators/Archeion.js +0 -249
  529. scitex/scholar/.legacy/metadata/urls/zotero_translators/Archiv fuer Sozialgeschichte.js +0 -157
  530. scitex/scholar/.legacy/metadata/urls/zotero_translators/Archive Ouverte en Sciences de l'Information et de la Communication (AOSIC).js +0 -179
  531. scitex/scholar/.legacy/metadata/urls/zotero_translators/Archives Canada.js +0 -142
  532. scitex/scholar/.legacy/metadata/urls/zotero_translators/Ariana News.js +0 -203
  533. scitex/scholar/.legacy/metadata/urls/zotero_translators/Art Institute of Chicago.js +0 -279
  534. scitex/scholar/.legacy/metadata/urls/zotero_translators/Artefacts Canada.js +0 -192
  535. scitex/scholar/.legacy/metadata/urls/zotero_translators/Artforum.js +0 -438
  536. scitex/scholar/.legacy/metadata/urls/zotero_translators/Atlanta Journal-Constitution.js +0 -311
  537. scitex/scholar/.legacy/metadata/urls/zotero_translators/Atypon Journals.js +0 -1204
  538. scitex/scholar/.legacy/metadata/urls/zotero_translators/AustLII and NZLII.js +0 -604
  539. scitex/scholar/.legacy/metadata/urls/zotero_translators/Australian Dictionary of Biography.js +0 -196
  540. scitex/scholar/.legacy/metadata/urls/zotero_translators/BAILII.js +0 -176
  541. scitex/scholar/.legacy/metadata/urls/zotero_translators/BBC Genome.js +0 -254
  542. scitex/scholar/.legacy/metadata/urls/zotero_translators/BBC.js +0 -430
  543. scitex/scholar/.legacy/metadata/urls/zotero_translators/BIBSYS.js +0 -112
  544. scitex/scholar/.legacy/metadata/urls/zotero_translators/BOCC.js +0 -217
  545. scitex/scholar/.legacy/metadata/urls/zotero_translators/BOE.js +0 -229
  546. scitex/scholar/.legacy/metadata/urls/zotero_translators/BOFiP-Impots.js +0 -132
  547. scitex/scholar/.legacy/metadata/urls/zotero_translators/Baidu Scholar.js +0 -276
  548. scitex/scholar/.legacy/metadata/urls/zotero_translators/Bangkok Post.js +0 -216
  549. scitex/scholar/.legacy/metadata/urls/zotero_translators/Baruch Foundation.js +0 -175
  550. scitex/scholar/.legacy/metadata/urls/zotero_translators/Beobachter.js +0 -175
  551. scitex/scholar/.legacy/metadata/urls/zotero_translators/Bezneng Gajit.js +0 -92
  552. scitex/scholar/.legacy/metadata/urls/zotero_translators/BibLaTeX.js +0 -888
  553. scitex/scholar/.legacy/metadata/urls/zotero_translators/BibTeX.js +0 -4236
  554. scitex/scholar/.legacy/metadata/urls/zotero_translators/Biblio.com.js +0 -216
  555. scitex/scholar/.legacy/metadata/urls/zotero_translators/Bibliontology RDF.js +0 -1166
  556. scitex/scholar/.legacy/metadata/urls/zotero_translators/Biblioteca Nacional de Maestros.js +0 -213
  557. scitex/scholar/.legacy/metadata/urls/zotero_translators/Bibliotheque et Archives Nationale du Quebec (Pistard).js +0 -147
  558. scitex/scholar/.legacy/metadata/urls/zotero_translators/Bibliotheque et Archives Nationales du Quebec.js +0 -266
  559. scitex/scholar/.legacy/metadata/urls/zotero_translators/Bibliotheque nationale de France.js +0 -872
  560. scitex/scholar/.legacy/metadata/urls/zotero_translators/BioMed Central.js +0 -585
  561. scitex/scholar/.legacy/metadata/urls/zotero_translators/BioOne.js +0 -233
  562. scitex/scholar/.legacy/metadata/urls/zotero_translators/Bioconductor.js +0 -343
  563. scitex/scholar/.legacy/metadata/urls/zotero_translators/Blaetter.js +0 -192
  564. scitex/scholar/.legacy/metadata/urls/zotero_translators/Blogger.js +0 -244
  565. scitex/scholar/.legacy/metadata/urls/zotero_translators/Bloomberg.js +0 -205
  566. scitex/scholar/.legacy/metadata/urls/zotero_translators/Bloomsbury Food Library.js +0 -296
  567. scitex/scholar/.legacy/metadata/urls/zotero_translators/Bluesky.js +0 -195
  568. scitex/scholar/.legacy/metadata/urls/zotero_translators/BnF ISBN.js +0 -129
  569. scitex/scholar/.legacy/metadata/urls/zotero_translators/Bookmarks.js +0 -282
  570. scitex/scholar/.legacy/metadata/urls/zotero_translators/Bookshop.org.js +0 -223
  571. scitex/scholar/.legacy/metadata/urls/zotero_translators/Boston Review.js +0 -332
  572. scitex/scholar/.legacy/metadata/urls/zotero_translators/Bosworth Toller's Anglo-Saxon Dictionary Online.js +0 -496
  573. scitex/scholar/.legacy/metadata/urls/zotero_translators/Bracero History Archive.js +0 -200
  574. scitex/scholar/.legacy/metadata/urls/zotero_translators/Brill.js +0 -434
  575. scitex/scholar/.legacy/metadata/urls/zotero_translators/Brukerhandboken.js +0 -153
  576. scitex/scholar/.legacy/metadata/urls/zotero_translators/Bryn Mawr Classical Review.js +0 -303
  577. scitex/scholar/.legacy/metadata/urls/zotero_translators/Bundesgesetzblatt.js +0 -231
  578. scitex/scholar/.legacy/metadata/urls/zotero_translators/Business Standard.js +0 -151
  579. scitex/scholar/.legacy/metadata/urls/zotero_translators/CABI - CAB Abstracts.js +0 -317
  580. scitex/scholar/.legacy/metadata/urls/zotero_translators/CAOD.js +0 -260
  581. scitex/scholar/.legacy/metadata/urls/zotero_translators/CBC.js +0 -439
  582. scitex/scholar/.legacy/metadata/urls/zotero_translators/CCfr (BnF).js +0 -162
  583. scitex/scholar/.legacy/metadata/urls/zotero_translators/CERN Document Server.js +0 -277
  584. scitex/scholar/.legacy/metadata/urls/zotero_translators/CEUR Workshop Proceedings.js +0 -145
  585. scitex/scholar/.legacy/metadata/urls/zotero_translators/CFF References.js +0 -170
  586. scitex/scholar/.legacy/metadata/urls/zotero_translators/CFF.js +0 -113
  587. scitex/scholar/.legacy/metadata/urls/zotero_translators/CIA World Factbook.js +0 -128
  588. scitex/scholar/.legacy/metadata/urls/zotero_translators/CLACSO.js +0 -226
  589. scitex/scholar/.legacy/metadata/urls/zotero_translators/CLASE.js +0 -135
  590. scitex/scholar/.legacy/metadata/urls/zotero_translators/CNKI.js +0 -731
  591. scitex/scholar/.legacy/metadata/urls/zotero_translators/COBISS.js +0 -1945
  592. scitex/scholar/.legacy/metadata/urls/zotero_translators/COinS.js +0 -336
  593. scitex/scholar/.legacy/metadata/urls/zotero_translators/CQ Press.js +0 -418
  594. scitex/scholar/.legacy/metadata/urls/zotero_translators/CROSBI.js +0 -227
  595. scitex/scholar/.legacy/metadata/urls/zotero_translators/CSIRO Publishing.js +0 -139
  596. scitex/scholar/.legacy/metadata/urls/zotero_translators/CSL JSON.js +0 -203
  597. scitex/scholar/.legacy/metadata/urls/zotero_translators/CSV.js +0 -294
  598. scitex/scholar/.legacy/metadata/urls/zotero_translators/Cairn.info.js +0 -368
  599. scitex/scholar/.legacy/metadata/urls/zotero_translators/CalMatters.js +0 -228
  600. scitex/scholar/.legacy/metadata/urls/zotero_translators/Calisphere.js +0 -355
  601. scitex/scholar/.legacy/metadata/urls/zotero_translators/Camara Brasileira do Livro ISBN.js +0 -842
  602. scitex/scholar/.legacy/metadata/urls/zotero_translators/Cambridge Core.js +0 -580
  603. scitex/scholar/.legacy/metadata/urls/zotero_translators/Cambridge Engage Preprints.js +0 -276
  604. scitex/scholar/.legacy/metadata/urls/zotero_translators/CanLII.js +0 -284
  605. scitex/scholar/.legacy/metadata/urls/zotero_translators/Canada.com.js +0 -171
  606. scitex/scholar/.legacy/metadata/urls/zotero_translators/Canadian Letters and Images.js +0 -148
  607. scitex/scholar/.legacy/metadata/urls/zotero_translators/Canadiana.ca.js +0 -196
  608. scitex/scholar/.legacy/metadata/urls/zotero_translators/Cascadilla Proceedings Project.js +0 -390
  609. scitex/scholar/.legacy/metadata/urls/zotero_translators/Cell Press.js +0 -516
  610. scitex/scholar/.legacy/metadata/urls/zotero_translators/Central and Eastern European Online Library Journals.js +0 -313
  611. scitex/scholar/.legacy/metadata/urls/zotero_translators/Champlain Society - Collection.js +0 -220
  612. scitex/scholar/.legacy/metadata/urls/zotero_translators/Chicago Journal of Theoretical Computer Science.js +0 -203
  613. scitex/scholar/.legacy/metadata/urls/zotero_translators/Christian Science Monitor.js +0 -148
  614. scitex/scholar/.legacy/metadata/urls/zotero_translators/Chronicling America.js +0 -131
  615. scitex/scholar/.legacy/metadata/urls/zotero_translators/CiNii Research.js +0 -168
  616. scitex/scholar/.legacy/metadata/urls/zotero_translators/Citavi 5 XML.js +0 -516
  617. scitex/scholar/.legacy/metadata/urls/zotero_translators/CiteSeer.js +0 -196
  618. scitex/scholar/.legacy/metadata/urls/zotero_translators/Citizen Lab.js +0 -347
  619. scitex/scholar/.legacy/metadata/urls/zotero_translators/Civilization.ca.js +0 -146
  620. scitex/scholar/.legacy/metadata/urls/zotero_translators/Climate Change and Human Health Literature Portal.js +0 -283
  621. scitex/scholar/.legacy/metadata/urls/zotero_translators/Clinical Key.js +0 -367
  622. scitex/scholar/.legacy/metadata/urls/zotero_translators/Code4Lib Journal.js +0 -143
  623. scitex/scholar/.legacy/metadata/urls/zotero_translators/Colorado State Legislature.js +0 -215
  624. scitex/scholar/.legacy/metadata/urls/zotero_translators/Columbia University Press.js +0 -238
  625. scitex/scholar/.legacy/metadata/urls/zotero_translators/Common-Place.js +0 -218
  626. scitex/scholar/.legacy/metadata/urls/zotero_translators/Computer History Museum Archive.js +0 -1319
  627. scitex/scholar/.legacy/metadata/urls/zotero_translators/Copernicus.js +0 -461
  628. scitex/scholar/.legacy/metadata/urls/zotero_translators/Cornell LII.js +0 -252
  629. scitex/scholar/.legacy/metadata/urls/zotero_translators/Cornell University Press.js +0 -235
  630. scitex/scholar/.legacy/metadata/urls/zotero_translators/CourtListener.js +0 -265
  631. scitex/scholar/.legacy/metadata/urls/zotero_translators/Crossref REST.js +0 -1757
  632. scitex/scholar/.legacy/metadata/urls/zotero_translators/Crossref Unixref XML.js +0 -965
  633. scitex/scholar/.legacy/metadata/urls/zotero_translators/Current Affairs.js +0 -160
  634. scitex/scholar/.legacy/metadata/urls/zotero_translators/DABI.js +0 -476
  635. scitex/scholar/.legacy/metadata/urls/zotero_translators/DAI-Zenon.js +0 -392
  636. scitex/scholar/.legacy/metadata/urls/zotero_translators/DART-Europe.js +0 -176
  637. scitex/scholar/.legacy/metadata/urls/zotero_translators/DBLP Computer Science Bibliography.js +0 -462
  638. scitex/scholar/.legacy/metadata/urls/zotero_translators/DBpia.js +0 -233
  639. scitex/scholar/.legacy/metadata/urls/zotero_translators/DEPATISnet.js +0 -373
  640. scitex/scholar/.legacy/metadata/urls/zotero_translators/DOAJ.js +0 -242
  641. scitex/scholar/.legacy/metadata/urls/zotero_translators/DOI Content Negotiation.js +0 -352
  642. scitex/scholar/.legacy/metadata/urls/zotero_translators/DOI.js +0 -322
  643. scitex/scholar/.legacy/metadata/urls/zotero_translators/DPLA.js +0 -425
  644. scitex/scholar/.legacy/metadata/urls/zotero_translators/DSpace Intermediate Metadata.js +0 -208
  645. scitex/scholar/.legacy/metadata/urls/zotero_translators/Dagens Nyheter.js +0 -369
  646. scitex/scholar/.legacy/metadata/urls/zotero_translators/Dagstuhl Research Online Publication Server.js +0 -278
  647. scitex/scholar/.legacy/metadata/urls/zotero_translators/Dar Almandumah.js +0 -253
  648. scitex/scholar/.legacy/metadata/urls/zotero_translators/Data.gov.js +0 -225
  649. scitex/scholar/.legacy/metadata/urls/zotero_translators/Databrary.js +0 -184
  650. scitex/scholar/.legacy/metadata/urls/zotero_translators/Datacite JSON.js +0 -1182
  651. scitex/scholar/.legacy/metadata/urls/zotero_translators/Dataverse.js +0 -418
  652. scitex/scholar/.legacy/metadata/urls/zotero_translators/Daum News.js +0 -139
  653. scitex/scholar/.legacy/metadata/urls/zotero_translators/De Gruyter Brill.js +0 -674
  654. scitex/scholar/.legacy/metadata/urls/zotero_translators/Defense Technical Information Center.js +0 -146
  655. scitex/scholar/.legacy/metadata/urls/zotero_translators/Delpher.js +0 -413
  656. scitex/scholar/.legacy/metadata/urls/zotero_translators/Demographic Research.js +0 -164
  657. scitex/scholar/.legacy/metadata/urls/zotero_translators/Denik CZ.js +0 -273
  658. scitex/scholar/.legacy/metadata/urls/zotero_translators/Der Freitag.js +0 -236
  659. scitex/scholar/.legacy/metadata/urls/zotero_translators/Der Spiegel.js +0 -479
  660. scitex/scholar/.legacy/metadata/urls/zotero_translators/Desiring God.js +0 -216
  661. scitex/scholar/.legacy/metadata/urls/zotero_translators/Deutsche Fotothek.js +0 -364
  662. scitex/scholar/.legacy/metadata/urls/zotero_translators/Deutsche Nationalbibliothek.js +0 -594
  663. scitex/scholar/.legacy/metadata/urls/zotero_translators/Dialnet.js +0 -258
  664. scitex/scholar/.legacy/metadata/urls/zotero_translators/Die Zeit.js +0 -378
  665. scitex/scholar/.legacy/metadata/urls/zotero_translators/DigiZeitschriften.js +0 -269
  666. scitex/scholar/.legacy/metadata/urls/zotero_translators/Digital Humanities Quarterly.js +0 -207
  667. scitex/scholar/.legacy/metadata/urls/zotero_translators/Digital Spy.js +0 -215
  668. scitex/scholar/.legacy/metadata/urls/zotero_translators/Dimensions.js +0 -233
  669. scitex/scholar/.legacy/metadata/urls/zotero_translators/Douban.js +0 -316
  670. scitex/scholar/.legacy/metadata/urls/zotero_translators/Dreier Neuerscheinungsdienst.js +0 -209
  671. scitex/scholar/.legacy/metadata/urls/zotero_translators/DrugBank.ca.js +0 -209
  672. scitex/scholar/.legacy/metadata/urls/zotero_translators/Dryad Digital Repository.js +0 -323
  673. scitex/scholar/.legacy/metadata/urls/zotero_translators/Duke University Press Books.js +0 -250
  674. scitex/scholar/.legacy/metadata/urls/zotero_translators/E-periodica Switzerland.js +0 -347
  675. scitex/scholar/.legacy/metadata/urls/zotero_translators/EBSCO Discovery Layer.js +0 -147
  676. scitex/scholar/.legacy/metadata/urls/zotero_translators/EBSCOhost.js +0 -592
  677. scitex/scholar/.legacy/metadata/urls/zotero_translators/EIDR.js +0 -184
  678. scitex/scholar/.legacy/metadata/urls/zotero_translators/EPA National Library Catalog.js +0 -245
  679. scitex/scholar/.legacy/metadata/urls/zotero_translators/ERIC.js +0 -986
  680. scitex/scholar/.legacy/metadata/urls/zotero_translators/ESpacenet.js +0 -465
  681. scitex/scholar/.legacy/metadata/urls/zotero_translators/EUR-Lex.js +0 -423
  682. scitex/scholar/.legacy/metadata/urls/zotero_translators/Eastview.js +0 -336
  683. scitex/scholar/.legacy/metadata/urls/zotero_translators/Edinburgh University Press Journals.js +0 -178
  684. scitex/scholar/.legacy/metadata/urls/zotero_translators/Education Week.js +0 -197
  685. scitex/scholar/.legacy/metadata/urls/zotero_translators/El Comercio (Peru).js +0 -347
  686. scitex/scholar/.legacy/metadata/urls/zotero_translators/El Pais.js +0 -262
  687. scitex/scholar/.legacy/metadata/urls/zotero_translators/Electronic Colloquium on Computational Complexity.js +0 -230
  688. scitex/scholar/.legacy/metadata/urls/zotero_translators/Elicit.js +0 -120
  689. scitex/scholar/.legacy/metadata/urls/zotero_translators/Elsevier Health Journals.js +0 -531
  690. scitex/scholar/.legacy/metadata/urls/zotero_translators/Elsevier Pure.js +0 -420
  691. scitex/scholar/.legacy/metadata/urls/zotero_translators/Embedded Metadata.js +0 -1951
  692. scitex/scholar/.legacy/metadata/urls/zotero_translators/Emerald Insight.js +0 -626
  693. scitex/scholar/.legacy/metadata/urls/zotero_translators/Encyclopedia of Chicago.js +0 -162
  694. scitex/scholar/.legacy/metadata/urls/zotero_translators/Encyclopedia of Korean Culture.js +0 -221
  695. scitex/scholar/.legacy/metadata/urls/zotero_translators/Endnote XML.js +0 -1407
  696. scitex/scholar/.legacy/metadata/urls/zotero_translators/Engineering Village.js +0 -139
  697. scitex/scholar/.legacy/metadata/urls/zotero_translators/Envidat.js +0 -331
  698. scitex/scholar/.legacy/metadata/urls/zotero_translators/Epicurious.js +0 -144
  699. scitex/scholar/.legacy/metadata/urls/zotero_translators/Erudit.js +0 -272
  700. scitex/scholar/.legacy/metadata/urls/zotero_translators/Euclid.js +0 -220
  701. scitex/scholar/.legacy/metadata/urls/zotero_translators/EurasiaNet.js +0 -109
  702. scitex/scholar/.legacy/metadata/urls/zotero_translators/EurogamerUSgamer.js +0 -380
  703. scitex/scholar/.legacy/metadata/urls/zotero_translators/Europe PMC.js +0 -448
  704. scitex/scholar/.legacy/metadata/urls/zotero_translators/Evernote.js +0 -104
  705. scitex/scholar/.legacy/metadata/urls/zotero_translators/F1000 Research.js +0 -655
  706. scitex/scholar/.legacy/metadata/urls/zotero_translators/FAO Publications.js +0 -1139
  707. scitex/scholar/.legacy/metadata/urls/zotero_translators/FAZ.NET.js +0 -231
  708. scitex/scholar/.legacy/metadata/urls/zotero_translators/Fachportal Padagogik.js +0 -839
  709. scitex/scholar/.legacy/metadata/urls/zotero_translators/Factiva.js +0 -302
  710. scitex/scholar/.legacy/metadata/urls/zotero_translators/Failed Architecture.js +0 -114
  711. scitex/scholar/.legacy/metadata/urls/zotero_translators/Fairfax Australia.js +0 -200
  712. scitex/scholar/.legacy/metadata/urls/zotero_translators/Fatcat.js +0 -425
  713. scitex/scholar/.legacy/metadata/urls/zotero_translators/Figshare.js +0 -191
  714. scitex/scholar/.legacy/metadata/urls/zotero_translators/Financial Times.js +0 -187
  715. scitex/scholar/.legacy/metadata/urls/zotero_translators/Finna.js +0 -357
  716. scitex/scholar/.legacy/metadata/urls/zotero_translators/Flickr.js +0 -318
  717. scitex/scholar/.legacy/metadata/urls/zotero_translators/Foreign Affairs.js +0 -485
  718. scitex/scholar/.legacy/metadata/urls/zotero_translators/Foreign Policy.js +0 -146
  719. scitex/scholar/.legacy/metadata/urls/zotero_translators/FreeCite.js +0 -95
  720. scitex/scholar/.legacy/metadata/urls/zotero_translators/FreePatentsOnline.js +0 -265
  721. scitex/scholar/.legacy/metadata/urls/zotero_translators/Frieze.js +0 -243
  722. scitex/scholar/.legacy/metadata/urls/zotero_translators/Frontiers.js +0 -667
  723. scitex/scholar/.legacy/metadata/urls/zotero_translators/GMS German Medical Science.js +0 -319
  724. scitex/scholar/.legacy/metadata/urls/zotero_translators/GPO Access e-CFR.js +0 -134
  725. scitex/scholar/.legacy/metadata/urls/zotero_translators/Gale Databases.js +0 -324
  726. scitex/scholar/.legacy/metadata/urls/zotero_translators/GaleGDC.js +0 -189
  727. scitex/scholar/.legacy/metadata/urls/zotero_translators/Galegroup.js +0 -327
  728. scitex/scholar/.legacy/metadata/urls/zotero_translators/Gallica.js +0 -194
  729. scitex/scholar/.legacy/metadata/urls/zotero_translators/Game Studies.js +0 -155
  730. scitex/scholar/.legacy/metadata/urls/zotero_translators/GameSpot.js +0 -199
  731. scitex/scholar/.legacy/metadata/urls/zotero_translators/GameStar GamePro.js +0 -198
  732. scitex/scholar/.legacy/metadata/urls/zotero_translators/Gasyrlar Awazy.js +0 -156
  733. scitex/scholar/.legacy/metadata/urls/zotero_translators/Gemeinsamer Bibliotheksverbund ISBN.js +0 -23
  734. scitex/scholar/.legacy/metadata/urls/zotero_translators/Gene Ontology.js +0 -128
  735. scitex/scholar/.legacy/metadata/urls/zotero_translators/GitHub.js +0 -501
  736. scitex/scholar/.legacy/metadata/urls/zotero_translators/Globes.js +0 -243
  737. scitex/scholar/.legacy/metadata/urls/zotero_translators/Gmail.js +0 -64
  738. scitex/scholar/.legacy/metadata/urls/zotero_translators/Goodreads.js +0 -219
  739. scitex/scholar/.legacy/metadata/urls/zotero_translators/Google Books.js +0 -552
  740. scitex/scholar/.legacy/metadata/urls/zotero_translators/Google Patents.js +0 -959
  741. scitex/scholar/.legacy/metadata/urls/zotero_translators/Google Play.js +0 -186
  742. scitex/scholar/.legacy/metadata/urls/zotero_translators/Google Presentation.js +0 -104
  743. scitex/scholar/.legacy/metadata/urls/zotero_translators/Google Research.js +0 -221
  744. scitex/scholar/.legacy/metadata/urls/zotero_translators/Google Scholar.js +0 -1361
  745. scitex/scholar/.legacy/metadata/urls/zotero_translators/Gulag Many Days, Many Lives.js +0 -179
  746. scitex/scholar/.legacy/metadata/urls/zotero_translators/HAL Archives Ouvertes.js +0 -429
  747. scitex/scholar/.legacy/metadata/urls/zotero_translators/HCSP.js +0 -312
  748. scitex/scholar/.legacy/metadata/urls/zotero_translators/HUDOC.js +0 -650
  749. scitex/scholar/.legacy/metadata/urls/zotero_translators/Haaretz.js +0 -562
  750. scitex/scholar/.legacy/metadata/urls/zotero_translators/Habr.js +0 -232
  751. scitex/scholar/.legacy/metadata/urls/zotero_translators/Handelszeitung.js +0 -273
  752. scitex/scholar/.legacy/metadata/urls/zotero_translators/Hanrei Watch.js +0 -123
  753. scitex/scholar/.legacy/metadata/urls/zotero_translators/Harper's Magazine.js +0 -365
  754. scitex/scholar/.legacy/metadata/urls/zotero_translators/Harvard Business Review.js +0 -326
  755. scitex/scholar/.legacy/metadata/urls/zotero_translators/Harvard Caselaw Access Project.js +0 -244
  756. scitex/scholar/.legacy/metadata/urls/zotero_translators/Harvard University Press Books.js +0 -286
  757. scitex/scholar/.legacy/metadata/urls/zotero_translators/HathiTrust.js +0 -311
  758. scitex/scholar/.legacy/metadata/urls/zotero_translators/HeinOnline.js +0 -266
  759. scitex/scholar/.legacy/metadata/urls/zotero_translators/Heise.js +0 -200
  760. scitex/scholar/.legacy/metadata/urls/zotero_translators/Herder.js +0 -236
  761. scitex/scholar/.legacy/metadata/urls/zotero_translators/HighBeam.js +0 -198
  762. scitex/scholar/.legacy/metadata/urls/zotero_translators/HighWire 2.0.js +0 -1355
  763. scitex/scholar/.legacy/metadata/urls/zotero_translators/HighWire.js +0 -209
  764. scitex/scholar/.legacy/metadata/urls/zotero_translators/Hindawi Publishers.js +0 -177
  765. scitex/scholar/.legacy/metadata/urls/zotero_translators/Hispanic-American Periodical Index.js +0 -236
  766. scitex/scholar/.legacy/metadata/urls/zotero_translators/Homeland Security Digital Library.js +0 -426
  767. scitex/scholar/.legacy/metadata/urls/zotero_translators/Huff Post.js +0 -223
  768. scitex/scholar/.legacy/metadata/urls/zotero_translators/Human Rights Watch.js +0 -450
  769. scitex/scholar/.legacy/metadata/urls/zotero_translators/IBISWorld.js +0 -171
  770. scitex/scholar/.legacy/metadata/urls/zotero_translators/IDEA ALM.js +0 -536
  771. scitex/scholar/.legacy/metadata/urls/zotero_translators/IEEE Computer Society.js +0 -429
  772. scitex/scholar/.legacy/metadata/urls/zotero_translators/IEEE Xplore.js +0 -1000
  773. scitex/scholar/.legacy/metadata/urls/zotero_translators/IETF.js +0 -451
  774. scitex/scholar/.legacy/metadata/urls/zotero_translators/IGN.js +0 -136
  775. scitex/scholar/.legacy/metadata/urls/zotero_translators/IMDb.js +0 -566
  776. scitex/scholar/.legacy/metadata/urls/zotero_translators/INSPIRE.js +0 -247
  777. scitex/scholar/.legacy/metadata/urls/zotero_translators/IPCC.js +0 -757
  778. scitex/scholar/.legacy/metadata/urls/zotero_translators/ISTC.js +0 -181
  779. scitex/scholar/.legacy/metadata/urls/zotero_translators/Idref.js +0 -179
  780. scitex/scholar/.legacy/metadata/urls/zotero_translators/In These Times.js +0 -196
  781. scitex/scholar/.legacy/metadata/urls/zotero_translators/InfoTrac.js +0 -279
  782. scitex/scholar/.legacy/metadata/urls/zotero_translators/Informationssystem Medienpaedagogik.js +0 -305
  783. scitex/scholar/.legacy/metadata/urls/zotero_translators/IngentaConnect.js +0 -312
  784. scitex/scholar/.legacy/metadata/urls/zotero_translators/Inside Higher Ed.js +0 -167
  785. scitex/scholar/.legacy/metadata/urls/zotero_translators/Insignia OPAC.js +0 -114
  786. scitex/scholar/.legacy/metadata/urls/zotero_translators/Institute of Contemporary Art.js +0 -180
  787. scitex/scholar/.legacy/metadata/urls/zotero_translators/Institute of Physics.js +0 -340
  788. scitex/scholar/.legacy/metadata/urls/zotero_translators/Integrum.js +0 -173
  789. scitex/scholar/.legacy/metadata/urls/zotero_translators/Intellixir.js +0 -264
  790. scitex/scholar/.legacy/metadata/urls/zotero_translators/Inter-Research Science Center.js +0 -185
  791. scitex/scholar/.legacy/metadata/urls/zotero_translators/International Nuclear Information System.js +0 -285
  792. scitex/scholar/.legacy/metadata/urls/zotero_translators/Internet Archive Scholar.js +0 -106
  793. scitex/scholar/.legacy/metadata/urls/zotero_translators/Internet Archive Wayback Machine.js +0 -152
  794. scitex/scholar/.legacy/metadata/urls/zotero_translators/Internet Archive.js +0 -552
  795. scitex/scholar/.legacy/metadata/urls/zotero_translators/InvenioRDM.js +0 -1260
  796. scitex/scholar/.legacy/metadata/urls/zotero_translators/Isidore.js +0 -235
  797. scitex/scholar/.legacy/metadata/urls/zotero_translators/J-Stage.js +0 -272
  798. scitex/scholar/.legacy/metadata/urls/zotero_translators/JETS.js +0 -122
  799. scitex/scholar/.legacy/metadata/urls/zotero_translators/JISC Historical Texts.js +0 -273
  800. scitex/scholar/.legacy/metadata/urls/zotero_translators/JRC Publications Repository.js +0 -569
  801. scitex/scholar/.legacy/metadata/urls/zotero_translators/JSTOR.js +0 -821
  802. scitex/scholar/.legacy/metadata/urls/zotero_translators/Jahrbuch.js +0 -213
  803. scitex/scholar/.legacy/metadata/urls/zotero_translators/Japan Times Online.js +0 -138
  804. scitex/scholar/.legacy/metadata/urls/zotero_translators/Journal of Electronic Publishing.js +0 -147
  805. scitex/scholar/.legacy/metadata/urls/zotero_translators/Journal of Extension.js +0 -288
  806. scitex/scholar/.legacy/metadata/urls/zotero_translators/Journal of Machine Learning Research.js +0 -441
  807. scitex/scholar/.legacy/metadata/urls/zotero_translators/Journal of Religion and Society.js +0 -174
  808. scitex/scholar/.legacy/metadata/urls/zotero_translators/JurPC.js +0 -274
  809. scitex/scholar/.legacy/metadata/urls/zotero_translators/Juricaf.js +0 -141
  810. scitex/scholar/.legacy/metadata/urls/zotero_translators/Juris.js +0 -728
  811. scitex/scholar/.legacy/metadata/urls/zotero_translators/K10plus ISBN.js +0 -386
  812. scitex/scholar/.legacy/metadata/urls/zotero_translators/KStudy.js +0 -632
  813. scitex/scholar/.legacy/metadata/urls/zotero_translators/Kanopy.js +0 -358
  814. scitex/scholar/.legacy/metadata/urls/zotero_translators/Khaama Press.js +0 -249
  815. scitex/scholar/.legacy/metadata/urls/zotero_translators/KitapYurdu.com.js +0 -376
  816. scitex/scholar/.legacy/metadata/urls/zotero_translators/Kommersant.js +0 -174
  817. scitex/scholar/.legacy/metadata/urls/zotero_translators/Korean National Library.js +0 -621
  818. scitex/scholar/.legacy/metadata/urls/zotero_translators/L'Annee Philologique.js +0 -267
  819. scitex/scholar/.legacy/metadata/urls/zotero_translators/LA Times.js +0 -239
  820. scitex/scholar/.legacy/metadata/urls/zotero_translators/LIBRIS ISBN.js +0 -103
  821. scitex/scholar/.legacy/metadata/urls/zotero_translators/LIVIVO.js +0 -260
  822. scitex/scholar/.legacy/metadata/urls/zotero_translators/LWN.net.js +0 -315
  823. scitex/scholar/.legacy/metadata/urls/zotero_translators/La Croix.js +0 -237
  824. scitex/scholar/.legacy/metadata/urls/zotero_translators/La Nacion (Argentina).js +0 -231
  825. scitex/scholar/.legacy/metadata/urls/zotero_translators/La Presse.js +0 -218
  826. scitex/scholar/.legacy/metadata/urls/zotero_translators/La Republica (Peru).js +0 -174
  827. scitex/scholar/.legacy/metadata/urls/zotero_translators/Lagen.nu.js +0 -214
  828. scitex/scholar/.legacy/metadata/urls/zotero_translators/Landesbibliographie Baden-Wurttemberg.js +0 -324
  829. scitex/scholar/.legacy/metadata/urls/zotero_translators/Lapham's Quarterly.js +0 -1062
  830. scitex/scholar/.legacy/metadata/urls/zotero_translators/Le Devoir.js +0 -167
  831. scitex/scholar/.legacy/metadata/urls/zotero_translators/Le Figaro.js +0 -225
  832. scitex/scholar/.legacy/metadata/urls/zotero_translators/Le Maitron.js +0 -484
  833. scitex/scholar/.legacy/metadata/urls/zotero_translators/Le Monde.js +0 -258
  834. scitex/scholar/.legacy/metadata/urls/zotero_translators/Le monde diplomatique.js +0 -200
  835. scitex/scholar/.legacy/metadata/urls/zotero_translators/Legifrance.js +0 -641
  836. scitex/scholar/.legacy/metadata/urls/zotero_translators/Legislative Insight.js +0 -406
  837. scitex/scholar/.legacy/metadata/urls/zotero_translators/Lexis+.js +0 -264
  838. scitex/scholar/.legacy/metadata/urls/zotero_translators/LexisNexis.js +0 -505
  839. scitex/scholar/.legacy/metadata/urls/zotero_translators/Libraries Tasmania.js +0 -778
  840. scitex/scholar/.legacy/metadata/urls/zotero_translators/Library Catalog (Aleph).js +0 -385
  841. scitex/scholar/.legacy/metadata/urls/zotero_translators/Library Catalog (Amicus).js +0 -254
  842. scitex/scholar/.legacy/metadata/urls/zotero_translators/Library Catalog (Aquabrowser).js +0 -253
  843. scitex/scholar/.legacy/metadata/urls/zotero_translators/Library Catalog (BiblioCommons).js +0 -249
  844. scitex/scholar/.legacy/metadata/urls/zotero_translators/Library Catalog (Blacklight).js +0 -341
  845. scitex/scholar/.legacy/metadata/urls/zotero_translators/Library Catalog (Capita Prism).js +0 -162
  846. scitex/scholar/.legacy/metadata/urls/zotero_translators/Library Catalog (DRA).js +0 -203
  847. scitex/scholar/.legacy/metadata/urls/zotero_translators/Library Catalog (Dynix).js +0 -315
  848. scitex/scholar/.legacy/metadata/urls/zotero_translators/Library Catalog (Encore).js +0 -211
  849. scitex/scholar/.legacy/metadata/urls/zotero_translators/Library Catalog (InnoPAC).js +0 -305
  850. scitex/scholar/.legacy/metadata/urls/zotero_translators/Library Catalog (Koha).js +0 -225
  851. scitex/scholar/.legacy/metadata/urls/zotero_translators/Library Catalog (Mango).js +0 -285
  852. scitex/scholar/.legacy/metadata/urls/zotero_translators/Library Catalog (OPALS).js +0 -200
  853. scitex/scholar/.legacy/metadata/urls/zotero_translators/Library Catalog (PICA).js +0 -2120
  854. scitex/scholar/.legacy/metadata/urls/zotero_translators/Library Catalog (PICA2).js +0 -331
  855. scitex/scholar/.legacy/metadata/urls/zotero_translators/Library Catalog (Pika).js +0 -488
  856. scitex/scholar/.legacy/metadata/urls/zotero_translators/Library Catalog (Polaris).js +0 -183
  857. scitex/scholar/.legacy/metadata/urls/zotero_translators/Library Catalog (Quolto).js +0 -320
  858. scitex/scholar/.legacy/metadata/urls/zotero_translators/Library Catalog (RERO ILS).js +0 -754
  859. scitex/scholar/.legacy/metadata/urls/zotero_translators/Library Catalog (SIRSI eLibrary).js +0 -407
  860. scitex/scholar/.legacy/metadata/urls/zotero_translators/Library Catalog (SIRSI).js +0 -452
  861. scitex/scholar/.legacy/metadata/urls/zotero_translators/Library Catalog (SLIMS).js +0 -146
  862. scitex/scholar/.legacy/metadata/urls/zotero_translators/Library Catalog (TIND ILS).js +0 -773
  863. scitex/scholar/.legacy/metadata/urls/zotero_translators/Library Catalog (TLCYouSeeMore).js +0 -132
  864. scitex/scholar/.legacy/metadata/urls/zotero_translators/Library Catalog (TinREAD).js +0 -277
  865. scitex/scholar/.legacy/metadata/urls/zotero_translators/Library Catalog (VTLS).js +0 -125
  866. scitex/scholar/.legacy/metadata/urls/zotero_translators/Library Catalog (Visual Library 2021).js +0 -765
  867. scitex/scholar/.legacy/metadata/urls/zotero_translators/Library Catalog (Voyager 7).js +0 -199
  868. scitex/scholar/.legacy/metadata/urls/zotero_translators/Library Catalog (Voyager).js +0 -212
  869. scitex/scholar/.legacy/metadata/urls/zotero_translators/Library Genesis.js +0 -337
  870. scitex/scholar/.legacy/metadata/urls/zotero_translators/Library Hub Discover.js +0 -359
  871. scitex/scholar/.legacy/metadata/urls/zotero_translators/Library of Congress Digital Collections.js +0 -869
  872. scitex/scholar/.legacy/metadata/urls/zotero_translators/Library of Congress ISBN.js +0 -86
  873. scitex/scholar/.legacy/metadata/urls/zotero_translators/LingBuzz.js +0 -359
  874. scitex/scholar/.legacy/metadata/urls/zotero_translators/Lippincott Williams and Wilkins.js +0 -341
  875. scitex/scholar/.legacy/metadata/urls/zotero_translators/Literary Hub.js +0 -950
  876. scitex/scholar/.legacy/metadata/urls/zotero_translators/Litres.js +0 -236
  877. scitex/scholar/.legacy/metadata/urls/zotero_translators/LiveJournal.js +0 -219
  878. scitex/scholar/.legacy/metadata/urls/zotero_translators/London Review of Books.js +0 -291
  879. scitex/scholar/.legacy/metadata/urls/zotero_translators/LookUs.js +0 -260
  880. scitex/scholar/.legacy/metadata/urls/zotero_translators/Lulu.js +0 -264
  881. scitex/scholar/.legacy/metadata/urls/zotero_translators/MAB2.js +0 -373
  882. scitex/scholar/.legacy/metadata/urls/zotero_translators/MARC.js +0 -1080
  883. scitex/scholar/.legacy/metadata/urls/zotero_translators/MARCXML.js +0 -489
  884. scitex/scholar/.legacy/metadata/urls/zotero_translators/MCV.js +0 -258
  885. scitex/scholar/.legacy/metadata/urls/zotero_translators/MDPI Journals.js +0 -356
  886. scitex/scholar/.legacy/metadata/urls/zotero_translators/MEDLINEnbib.js +0 -1561
  887. scitex/scholar/.legacy/metadata/urls/zotero_translators/METS.js +0 -384
  888. scitex/scholar/.legacy/metadata/urls/zotero_translators/MIDAS Journals.js +0 -343
  889. scitex/scholar/.legacy/metadata/urls/zotero_translators/MIT Press Books.js +0 -637
  890. scitex/scholar/.legacy/metadata/urls/zotero_translators/MODS.js +0 -2545
  891. scitex/scholar/.legacy/metadata/urls/zotero_translators/MPG PuRe.js +0 -541
  892. scitex/scholar/.legacy/metadata/urls/zotero_translators/Mailman.js +0 -136
  893. scitex/scholar/.legacy/metadata/urls/zotero_translators/Mainichi Daily News.js +0 -189
  894. scitex/scholar/.legacy/metadata/urls/zotero_translators/Mastodon.js +0 -198
  895. scitex/scholar/.legacy/metadata/urls/zotero_translators/Matbugat.ru.js +0 -110
  896. scitex/scholar/.legacy/metadata/urls/zotero_translators/Max Planck Institute for the History of Science Virtual Laboratory Library.js +0 -136
  897. scitex/scholar/.legacy/metadata/urls/zotero_translators/Medium.js +0 -208
  898. scitex/scholar/.legacy/metadata/urls/zotero_translators/MetaLib.js +0 -126
  899. scitex/scholar/.legacy/metadata/urls/zotero_translators/Microbiology Society Journals.js +0 -343
  900. scitex/scholar/.legacy/metadata/urls/zotero_translators/Microsoft Academic.js +0 -424
  901. scitex/scholar/.legacy/metadata/urls/zotero_translators/Mikromarc.js +0 -207
  902. scitex/scholar/.legacy/metadata/urls/zotero_translators/Milli Kutuphane.js +0 -244
  903. scitex/scholar/.legacy/metadata/urls/zotero_translators/Musee du Louvre.js +0 -265
  904. scitex/scholar/.legacy/metadata/urls/zotero_translators/NASA ADS.js +0 -889
  905. scitex/scholar/.legacy/metadata/urls/zotero_translators/NASA NTRS.js +0 -610
  906. scitex/scholar/.legacy/metadata/urls/zotero_translators/NCBI Nucleotide.js +0 -227
  907. scitex/scholar/.legacy/metadata/urls/zotero_translators/NPR.js +0 -341
  908. scitex/scholar/.legacy/metadata/urls/zotero_translators/NRC Research Press.js +0 -181
  909. scitex/scholar/.legacy/metadata/urls/zotero_translators/NRC.nl.js +0 -226
  910. scitex/scholar/.legacy/metadata/urls/zotero_translators/NTSB Accident Reports.js +0 -226
  911. scitex/scholar/.legacy/metadata/urls/zotero_translators/NYPL Menus.js +0 -275
  912. scitex/scholar/.legacy/metadata/urls/zotero_translators/NYPL Research Catalog.js +0 -458
  913. scitex/scholar/.legacy/metadata/urls/zotero_translators/NYTimes.com.js +0 -858
  914. scitex/scholar/.legacy/metadata/urls/zotero_translators/NZZ.ch.js +0 -272
  915. scitex/scholar/.legacy/metadata/urls/zotero_translators/Nagoya University OPAC.js +0 -336
  916. scitex/scholar/.legacy/metadata/urls/zotero_translators/National Academies Press.js +0 -243
  917. scitex/scholar/.legacy/metadata/urls/zotero_translators/National Agriculture Library.js +0 -524
  918. scitex/scholar/.legacy/metadata/urls/zotero_translators/National Archives of Australia.js +0 -522
  919. scitex/scholar/.legacy/metadata/urls/zotero_translators/National Archives of South Africa.js +0 -122
  920. scitex/scholar/.legacy/metadata/urls/zotero_translators/National Bureau of Economic Research.js +0 -363
  921. scitex/scholar/.legacy/metadata/urls/zotero_translators/National Diet Library Catalogue.js +0 -333
  922. scitex/scholar/.legacy/metadata/urls/zotero_translators/National Gallery of Art - USA.js +0 -149
  923. scitex/scholar/.legacy/metadata/urls/zotero_translators/National Gallery of Australia.js +0 -252
  924. scitex/scholar/.legacy/metadata/urls/zotero_translators/National Library of Australia (new catalog).js +0 -223
  925. scitex/scholar/.legacy/metadata/urls/zotero_translators/National Library of Belarus.js +0 -171
  926. scitex/scholar/.legacy/metadata/urls/zotero_translators/National Library of Norway.js +0 -310
  927. scitex/scholar/.legacy/metadata/urls/zotero_translators/National Library of Poland ISBN.js +0 -140
  928. scitex/scholar/.legacy/metadata/urls/zotero_translators/National Post.js +0 -186
  929. scitex/scholar/.legacy/metadata/urls/zotero_translators/National Technical Reports Library.js +0 -276
  930. scitex/scholar/.legacy/metadata/urls/zotero_translators/National Transportation Library ROSA P.js +0 -562
  931. scitex/scholar/.legacy/metadata/urls/zotero_translators/Nature Publishing Group.js +0 -3394
  932. scitex/scholar/.legacy/metadata/urls/zotero_translators/Neural Information Processing Systems.js +0 -385
  933. scitex/scholar/.legacy/metadata/urls/zotero_translators/New Left Review.js +0 -245
  934. scitex/scholar/.legacy/metadata/urls/zotero_translators/New Zealand Herald.js +0 -282
  935. scitex/scholar/.legacy/metadata/urls/zotero_translators/Newlines Magazine.js +0 -190
  936. scitex/scholar/.legacy/metadata/urls/zotero_translators/News Corp Australia.js +0 -251
  937. scitex/scholar/.legacy/metadata/urls/zotero_translators/NewsBank.js +0 -202
  938. scitex/scholar/.legacy/metadata/urls/zotero_translators/NewsnetTamedia.js +0 -509
  939. scitex/scholar/.legacy/metadata/urls/zotero_translators/Noor Digital Library.js +0 -267
  940. scitex/scholar/.legacy/metadata/urls/zotero_translators/Note HTML.js +0 -206
  941. scitex/scholar/.legacy/metadata/urls/zotero_translators/Note Markdown.js +0 -1638
  942. scitex/scholar/.legacy/metadata/urls/zotero_translators/Notre Dame Philosophical Reviews.js +0 -201
  943. scitex/scholar/.legacy/metadata/urls/zotero_translators/OAPEN.js +0 -331
  944. scitex/scholar/.legacy/metadata/urls/zotero_translators/OCLC WorldCat FirstSearch.js +0 -213
  945. scitex/scholar/.legacy/metadata/urls/zotero_translators/OECD.js +0 -216
  946. scitex/scholar/.legacy/metadata/urls/zotero_translators/ORCID.js +0 -104
  947. scitex/scholar/.legacy/metadata/urls/zotero_translators/OSF Preprints.js +0 -417
  948. scitex/scholar/.legacy/metadata/urls/zotero_translators/OSTI Energy Citations.js +0 -202
  949. scitex/scholar/.legacy/metadata/urls/zotero_translators/OVID Tagged.js +0 -1226
  950. scitex/scholar/.legacy/metadata/urls/zotero_translators/OZON.ru.js +0 -465
  951. scitex/scholar/.legacy/metadata/urls/zotero_translators/OhioLINK.js +0 -43
  952. scitex/scholar/.legacy/metadata/urls/zotero_translators/Old Bailey Online.js +0 -315
  953. scitex/scholar/.legacy/metadata/urls/zotero_translators/Open Conf.js +0 -172
  954. scitex/scholar/.legacy/metadata/urls/zotero_translators/Open Knowledge Repository.js +0 -811
  955. scitex/scholar/.legacy/metadata/urls/zotero_translators/Open WorldCat.js +0 -1401
  956. scitex/scholar/.legacy/metadata/urls/zotero_translators/OpenAlex JSON.js +0 -740
  957. scitex/scholar/.legacy/metadata/urls/zotero_translators/OpenAlex.js +0 -444
  958. scitex/scholar/.legacy/metadata/urls/zotero_translators/OpenEdition Books.js +0 -155
  959. scitex/scholar/.legacy/metadata/urls/zotero_translators/OpenEdition Journals.js +0 -432
  960. scitex/scholar/.legacy/metadata/urls/zotero_translators/Optical Society of America.js +0 -562
  961. scitex/scholar/.legacy/metadata/urls/zotero_translators/Optimization Online.js +0 -418
  962. scitex/scholar/.legacy/metadata/urls/zotero_translators/Ovid.js +0 -302
  963. scitex/scholar/.legacy/metadata/urls/zotero_translators/Oxford Dictionaries Premium.js +0 -194
  964. scitex/scholar/.legacy/metadata/urls/zotero_translators/Oxford English Dictionary.js +0 -122
  965. scitex/scholar/.legacy/metadata/urls/zotero_translators/Oxford Music and Art Online.js +0 -120
  966. scitex/scholar/.legacy/metadata/urls/zotero_translators/Oxford Reference.js +0 -202
  967. scitex/scholar/.legacy/metadata/urls/zotero_translators/Oxford University Press.js +0 -277
  968. scitex/scholar/.legacy/metadata/urls/zotero_translators/PC Gamer.js +0 -302
  969. scitex/scholar/.legacy/metadata/urls/zotero_translators/PC Games.js +0 -128
  970. scitex/scholar/.legacy/metadata/urls/zotero_translators/PEI Archival Information Network.js +0 -242
  971. scitex/scholar/.legacy/metadata/urls/zotero_translators/PEP Web.js +0 -165
  972. scitex/scholar/.legacy/metadata/urls/zotero_translators/PKP Catalog Systems.js +0 -1455
  973. scitex/scholar/.legacy/metadata/urls/zotero_translators/PLoS Journals.js +0 -284
  974. scitex/scholar/.legacy/metadata/urls/zotero_translators/PRC History Review.js +0 -298
  975. scitex/scholar/.legacy/metadata/urls/zotero_translators/Pajhwok Afghan News.js +0 -198
  976. scitex/scholar/.legacy/metadata/urls/zotero_translators/Papers Past.js +0 -297
  977. scitex/scholar/.legacy/metadata/urls/zotero_translators/Paris Review.js +0 -227
  978. scitex/scholar/.legacy/metadata/urls/zotero_translators/Pastebin.js +0 -199
  979. scitex/scholar/.legacy/metadata/urls/zotero_translators/Patents - USPTO.js +0 -210
  980. scitex/scholar/.legacy/metadata/urls/zotero_translators/Peeters.js +0 -587
  981. scitex/scholar/.legacy/metadata/urls/zotero_translators/Perceiving Systems.js +0 -350
  982. scitex/scholar/.legacy/metadata/urls/zotero_translators/Perlego.js +0 -416
  983. scitex/scholar/.legacy/metadata/urls/zotero_translators/PhilPapers.js +0 -249
  984. scitex/scholar/.legacy/metadata/urls/zotero_translators/Philosopher's Imprint.js +0 -169
  985. scitex/scholar/.legacy/metadata/urls/zotero_translators/Pleade.js +0 -329
  986. scitex/scholar/.legacy/metadata/urls/zotero_translators/Polygon.js +0 -270
  987. scitex/scholar/.legacy/metadata/urls/zotero_translators/Potsdamer Neueste Nachrichten.js +0 -188
  988. scitex/scholar/.legacy/metadata/urls/zotero_translators/Preprints.org.js +0 -305
  989. scitex/scholar/.legacy/metadata/urls/zotero_translators/Primo 2018.js +0 -126
  990. scitex/scholar/.legacy/metadata/urls/zotero_translators/Primo Normalized XML.js +0 -987
  991. scitex/scholar/.legacy/metadata/urls/zotero_translators/Primo.js +0 -322
  992. scitex/scholar/.legacy/metadata/urls/zotero_translators/ProMED.js +0 -66
  993. scitex/scholar/.legacy/metadata/urls/zotero_translators/ProQuest Ebook Central.js +0 -226
  994. scitex/scholar/.legacy/metadata/urls/zotero_translators/ProQuest PolicyFile.js +0 -115
  995. scitex/scholar/.legacy/metadata/urls/zotero_translators/ProQuest.js +0 -2210
  996. scitex/scholar/.legacy/metadata/urls/zotero_translators/Probing the Past.js +0 -151
  997. scitex/scholar/.legacy/metadata/urls/zotero_translators/Project Gutenberg.js +0 -191
  998. scitex/scholar/.legacy/metadata/urls/zotero_translators/Project MUSE.js +0 -451
  999. scitex/scholar/.legacy/metadata/urls/zotero_translators/Protein Data Bank.js +0 -445
  1000. scitex/scholar/.legacy/metadata/urls/zotero_translators/PubFactory Journals.js +0 -712
  1001. scitex/scholar/.legacy/metadata/urls/zotero_translators/PubMed Central.js +0 -577
  1002. scitex/scholar/.legacy/metadata/urls/zotero_translators/PubMed XML.js +0 -1139
  1003. scitex/scholar/.legacy/metadata/urls/zotero_translators/PubMed.js +0 -1317
  1004. scitex/scholar/.legacy/metadata/urls/zotero_translators/PubPub.js +0 -530
  1005. scitex/scholar/.legacy/metadata/urls/zotero_translators/Public Record Office Victoria.js +0 -252
  1006. scitex/scholar/.legacy/metadata/urls/zotero_translators/Publications Office of the European Union.js +0 -540
  1007. scitex/scholar/.legacy/metadata/urls/zotero_translators/Publications du Quebec.js +0 -225
  1008. scitex/scholar/.legacy/metadata/urls/zotero_translators/PyPI.js +0 -288
  1009. scitex/scholar/.legacy/metadata/urls/zotero_translators/Qatar Digital Library.js +0 -802
  1010. scitex/scholar/.legacy/metadata/urls/zotero_translators/Queensland State Archives.js +0 -303
  1011. scitex/scholar/.legacy/metadata/urls/zotero_translators/R-Packages.js +0 -410
  1012. scitex/scholar/.legacy/metadata/urls/zotero_translators/RAND.js +0 -283
  1013. scitex/scholar/.legacy/metadata/urls/zotero_translators/RDF.js +0 -1777
  1014. scitex/scholar/.legacy/metadata/urls/zotero_translators/REDALYC.js +0 -196
  1015. scitex/scholar/.legacy/metadata/urls/zotero_translators/RIS.js +0 -7265
  1016. scitex/scholar/.legacy/metadata/urls/zotero_translators/RSC Publishing.js +0 -250
  1017. scitex/scholar/.legacy/metadata/urls/zotero_translators/Radio Free Europe Radio Liberty.js +0 -706
  1018. scitex/scholar/.legacy/metadata/urls/zotero_translators/RePEc - Econpapers.js +0 -725
  1019. scitex/scholar/.legacy/metadata/urls/zotero_translators/RePEc - IDEAS.js +0 -337
  1020. scitex/scholar/.legacy/metadata/urls/zotero_translators/Rechtspraak.nl.js +0 -295
  1021. scitex/scholar/.legacy/metadata/urls/zotero_translators/RefWorks Tagged.js +0 -1185
  1022. scitex/scholar/.legacy/metadata/urls/zotero_translators/ReferBibIX.js +0 -463
  1023. scitex/scholar/.legacy/metadata/urls/zotero_translators/Regeringskansliet.js +0 -89
  1024. scitex/scholar/.legacy/metadata/urls/zotero_translators/Research Square.js +0 -335
  1025. scitex/scholar/.legacy/metadata/urls/zotero_translators/ResearchGate.js +0 -394
  1026. scitex/scholar/.legacy/metadata/urls/zotero_translators/Retsinformation.js +0 -348
  1027. scitex/scholar/.legacy/metadata/urls/zotero_translators/Reuters.js +0 -255
  1028. scitex/scholar/.legacy/metadata/urls/zotero_translators/Rock, Paper, Shotgun.js +0 -304
  1029. scitex/scholar/.legacy/metadata/urls/zotero_translators/Roll Call.js +0 -173
  1030. scitex/scholar/.legacy/metadata/urls/zotero_translators/Russian State Library.js +0 -1517
  1031. scitex/scholar/.legacy/metadata/urls/zotero_translators/SAE Papers.js +0 -241
  1032. scitex/scholar/.legacy/metadata/urls/zotero_translators/SAGE Journals.js +0 -427
  1033. scitex/scholar/.legacy/metadata/urls/zotero_translators/SAGE Knowledge.js +0 -505
  1034. scitex/scholar/.legacy/metadata/urls/zotero_translators/SAILDART.js +0 -364
  1035. scitex/scholar/.legacy/metadata/urls/zotero_translators/SALT Research Archives.js +0 -196
  1036. scitex/scholar/.legacy/metadata/urls/zotero_translators/SFU IPinCH.js +0 -946
  1037. scitex/scholar/.legacy/metadata/urls/zotero_translators/SIPRI.js +0 -256
  1038. scitex/scholar/.legacy/metadata/urls/zotero_translators/SIRS Knowledge Source.js +0 -546
  1039. scitex/scholar/.legacy/metadata/urls/zotero_translators/SLUB Dresden.js +0 -300
  1040. scitex/scholar/.legacy/metadata/urls/zotero_translators/SORA.js +0 -340
  1041. scitex/scholar/.legacy/metadata/urls/zotero_translators/SSOAR.js +0 -399
  1042. scitex/scholar/.legacy/metadata/urls/zotero_translators/SSRN.js +0 -235
  1043. scitex/scholar/.legacy/metadata/urls/zotero_translators/SVT Nyheter.js +0 -381
  1044. scitex/scholar/.legacy/metadata/urls/zotero_translators/Sacramento Bee.js +0 -274
  1045. scitex/scholar/.legacy/metadata/urls/zotero_translators/Safari Books Online.js +0 -391
  1046. scitex/scholar/.legacy/metadata/urls/zotero_translators/Scholars Portal Journals.js +0 -220
  1047. scitex/scholar/.legacy/metadata/urls/zotero_translators/Scholia.js +0 -189
  1048. scitex/scholar/.legacy/metadata/urls/zotero_translators/Schweizer Radio und Fernsehen SRF.js +0 -152
  1049. scitex/scholar/.legacy/metadata/urls/zotero_translators/SciELO.js +0 -440
  1050. scitex/scholar/.legacy/metadata/urls/zotero_translators/ScienceDirect.js +0 -1304
  1051. scitex/scholar/.legacy/metadata/urls/zotero_translators/Scopus.js +0 -418
  1052. scitex/scholar/.legacy/metadata/urls/zotero_translators/Semantic Scholar.js +0 -513
  1053. scitex/scholar/.legacy/metadata/urls/zotero_translators/Silverchair.js +0 -886
  1054. scitex/scholar/.legacy/metadata/urls/zotero_translators/Slate.js +0 -228
  1055. scitex/scholar/.legacy/metadata/urls/zotero_translators/SlideShare.js +0 -112
  1056. scitex/scholar/.legacy/metadata/urls/zotero_translators/Springer Link.js +0 -696
  1057. scitex/scholar/.legacy/metadata/urls/zotero_translators/Stack Exchange.js +0 -134
  1058. scitex/scholar/.legacy/metadata/urls/zotero_translators/Standard Ebooks.js +0 -198
  1059. scitex/scholar/.legacy/metadata/urls/zotero_translators/Stanford Encyclopedia of Philosophy.js +0 -285
  1060. scitex/scholar/.legacy/metadata/urls/zotero_translators/Stanford University Press.js +0 -343
  1061. scitex/scholar/.legacy/metadata/urls/zotero_translators/State Records Office of Western Australia.js +0 -439
  1062. scitex/scholar/.legacy/metadata/urls/zotero_translators/Stitcher.js +0 -141
  1063. scitex/scholar/.legacy/metadata/urls/zotero_translators/Store norske leksikon.js +0 -291
  1064. scitex/scholar/.legacy/metadata/urls/zotero_translators/Stuff.co.nz.js +0 -446
  1065. scitex/scholar/.legacy/metadata/urls/zotero_translators/Substack.js +0 -237
  1066. scitex/scholar/.legacy/metadata/urls/zotero_translators/Sud Ouest.js +0 -181
  1067. scitex/scholar/.legacy/metadata/urls/zotero_translators/Sueddeutsche.de.js +0 -205
  1068. scitex/scholar/.legacy/metadata/urls/zotero_translators/Summon 2.js +0 -117
  1069. scitex/scholar/.legacy/metadata/urls/zotero_translators/Superlib.js +0 -647
  1070. scitex/scholar/.legacy/metadata/urls/zotero_translators/Svenska Dagbladet.js +0 -274
  1071. scitex/scholar/.legacy/metadata/urls/zotero_translators/Sveriges radio.js +0 -416
  1072. scitex/scholar/.legacy/metadata/urls/zotero_translators/TEI.js +0 -648
  1073. scitex/scholar/.legacy/metadata/urls/zotero_translators/TV by the Numbers.js +0 -194
  1074. scitex/scholar/.legacy/metadata/urls/zotero_translators/TVNZ.js +0 -165
  1075. scitex/scholar/.legacy/metadata/urls/zotero_translators/Tagesspiegel.js +0 -249
  1076. scitex/scholar/.legacy/metadata/urls/zotero_translators/Talis Aspire.js +0 -316
  1077. scitex/scholar/.legacy/metadata/urls/zotero_translators/TalisPrism.js +0 -445
  1078. scitex/scholar/.legacy/metadata/urls/zotero_translators/Tatknigafund.js +0 -174
  1079. scitex/scholar/.legacy/metadata/urls/zotero_translators/Tatpressa.ru.js +0 -121
  1080. scitex/scholar/.legacy/metadata/urls/zotero_translators/Taylor & Francis eBooks.js +0 -334
  1081. scitex/scholar/.legacy/metadata/urls/zotero_translators/Taylor and Francis+NEJM.js +0 -813
  1082. scitex/scholar/.legacy/metadata/urls/zotero_translators/Tesis Doctorals en Xarxa.js +0 -233
  1083. scitex/scholar/.legacy/metadata/urls/zotero_translators/The Art Newspaper.js +0 -268
  1084. scitex/scholar/.legacy/metadata/urls/zotero_translators/The Atlantic.js +0 -535
  1085. scitex/scholar/.legacy/metadata/urls/zotero_translators/The Boston Globe.js +0 -285
  1086. scitex/scholar/.legacy/metadata/urls/zotero_translators/The Chronicle of Higher Education.js +0 -308
  1087. scitex/scholar/.legacy/metadata/urls/zotero_translators/The Daily Beast.js +0 -183
  1088. scitex/scholar/.legacy/metadata/urls/zotero_translators/The Economic Times - The Times of India.js +0 -305
  1089. scitex/scholar/.legacy/metadata/urls/zotero_translators/The Economist.js +0 -207
  1090. scitex/scholar/.legacy/metadata/urls/zotero_translators/The Free Dictionary.js +0 -58
  1091. scitex/scholar/.legacy/metadata/urls/zotero_translators/The Globe and Mail.js +0 -241
  1092. scitex/scholar/.legacy/metadata/urls/zotero_translators/The Guardian.js +0 -717
  1093. scitex/scholar/.legacy/metadata/urls/zotero_translators/The Hamilton Spectator.js +0 -129
  1094. scitex/scholar/.legacy/metadata/urls/zotero_translators/The Hindu.js +0 -318
  1095. scitex/scholar/.legacy/metadata/urls/zotero_translators/The Independent.js +0 -184
  1096. scitex/scholar/.legacy/metadata/urls/zotero_translators/The Intercept.js +0 -258
  1097. scitex/scholar/.legacy/metadata/urls/zotero_translators/The Met.js +0 -300
  1098. scitex/scholar/.legacy/metadata/urls/zotero_translators/The Microfinance Gateway.js +0 -174
  1099. scitex/scholar/.legacy/metadata/urls/zotero_translators/The Nation.js +0 -188
  1100. scitex/scholar/.legacy/metadata/urls/zotero_translators/The National Archives (UK).js +0 -242
  1101. scitex/scholar/.legacy/metadata/urls/zotero_translators/The New Republic.js +0 -160
  1102. scitex/scholar/.legacy/metadata/urls/zotero_translators/The New York Review of Books.js +0 -467
  1103. scitex/scholar/.legacy/metadata/urls/zotero_translators/The New Yorker.js +0 -360
  1104. scitex/scholar/.legacy/metadata/urls/zotero_translators/The Open Library.js +0 -220
  1105. scitex/scholar/.legacy/metadata/urls/zotero_translators/The Straits Times.js +0 -528
  1106. scitex/scholar/.legacy/metadata/urls/zotero_translators/The Telegraph.js +0 -337
  1107. scitex/scholar/.legacy/metadata/urls/zotero_translators/The Times and Sunday Times.js +0 -180
  1108. scitex/scholar/.legacy/metadata/urls/zotero_translators/The Times of Israel.js +0 -151
  1109. scitex/scholar/.legacy/metadata/urls/zotero_translators/TheMarker.js +0 -108
  1110. scitex/scholar/.legacy/metadata/urls/zotero_translators/Theory of Computing.js +0 -488
  1111. scitex/scholar/.legacy/metadata/urls/zotero_translators/ThesesFR.js +0 -298
  1112. scitex/scholar/.legacy/metadata/urls/zotero_translators/Thieme.js +0 -326
  1113. scitex/scholar/.legacy/metadata/urls/zotero_translators/Time.com.js +0 -557
  1114. scitex/scholar/.legacy/metadata/urls/zotero_translators/TimesMachine.js +0 -222
  1115. scitex/scholar/.legacy/metadata/urls/zotero_translators/Tony Blair Institute for Global Change.js +0 -195
  1116. scitex/scholar/.legacy/metadata/urls/zotero_translators/Toronto Star.js +0 -331
  1117. scitex/scholar/.legacy/metadata/urls/zotero_translators/Transportation Research Board.js +0 -253
  1118. scitex/scholar/.legacy/metadata/urls/zotero_translators/Treesearch.js +0 -535
  1119. scitex/scholar/.legacy/metadata/urls/zotero_translators/Trove.js +0 -616
  1120. scitex/scholar/.legacy/metadata/urls/zotero_translators/Tumblr.js +0 -179
  1121. scitex/scholar/.legacy/metadata/urls/zotero_translators/Twitter.js +0 -413
  1122. scitex/scholar/.legacy/metadata/urls/zotero_translators/UChicago VuFind.js +0 -907
  1123. scitex/scholar/.legacy/metadata/urls/zotero_translators/UNZ Print Archive.js +0 -276
  1124. scitex/scholar/.legacy/metadata/urls/zotero_translators/UPCommons.js +0 -227
  1125. scitex/scholar/.legacy/metadata/urls/zotero_translators/US National Archives Research Catalog.js +0 -275
  1126. scitex/scholar/.legacy/metadata/urls/zotero_translators/USENIX.js +0 -151
  1127. scitex/scholar/.legacy/metadata/urls/zotero_translators/Ubiquity Journals.js +0 -228
  1128. scitex/scholar/.legacy/metadata/urls/zotero_translators/University Press Scholarship.js +0 -301
  1129. scitex/scholar/.legacy/metadata/urls/zotero_translators/University of California Press Books.js +0 -403
  1130. scitex/scholar/.legacy/metadata/urls/zotero_translators/University of Chicago Press Books.js +0 -378
  1131. scitex/scholar/.legacy/metadata/urls/zotero_translators/University of Wisconsin-Madison Libraries Catalog.js +0 -298
  1132. scitex/scholar/.legacy/metadata/urls/zotero_translators/Unqualified Dublin Core RDF.js +0 -153
  1133. scitex/scholar/.legacy/metadata/urls/zotero_translators/UpToDate References.js +0 -203
  1134. scitex/scholar/.legacy/metadata/urls/zotero_translators/Vanity Fair.js +0 -242
  1135. scitex/scholar/.legacy/metadata/urls/zotero_translators/Verniana-Jules Verne Studies.js +0 -190
  1136. scitex/scholar/.legacy/metadata/urls/zotero_translators/Verso Books.js +0 -311
  1137. scitex/scholar/.legacy/metadata/urls/zotero_translators/Vice.js +0 -445
  1138. scitex/scholar/.legacy/metadata/urls/zotero_translators/Victoria & Albert Museum.js +0 -277
  1139. scitex/scholar/.legacy/metadata/urls/zotero_translators/Vimeo.js +0 -188
  1140. scitex/scholar/.legacy/metadata/urls/zotero_translators/VoxEU.js +0 -151
  1141. scitex/scholar/.legacy/metadata/urls/zotero_translators/WHO.js +0 -458
  1142. scitex/scholar/.legacy/metadata/urls/zotero_translators/WIPO.js +0 -189
  1143. scitex/scholar/.legacy/metadata/urls/zotero_translators/Wall Street Journal.js +0 -525
  1144. scitex/scholar/.legacy/metadata/urls/zotero_translators/Wanfang Data.js +0 -310
  1145. scitex/scholar/.legacy/metadata/urls/zotero_translators/Washington Monthly.js +0 -195
  1146. scitex/scholar/.legacy/metadata/urls/zotero_translators/Washington Post.js +0 -447
  1147. scitex/scholar/.legacy/metadata/urls/zotero_translators/Web of Science Nextgen.js +0 -715
  1148. scitex/scholar/.legacy/metadata/urls/zotero_translators/Web of Science Tagged.js +0 -1242
  1149. scitex/scholar/.legacy/metadata/urls/zotero_translators/Web of Science.js +0 -228
  1150. scitex/scholar/.legacy/metadata/urls/zotero_translators/Welt Online.js +0 -161
  1151. scitex/scholar/.legacy/metadata/urls/zotero_translators/WestLaw UK.js +0 -190
  1152. scitex/scholar/.legacy/metadata/urls/zotero_translators/WikiLeaks PlusD.js +0 -182
  1153. scitex/scholar/.legacy/metadata/urls/zotero_translators/Wikidata QuickStatements.js +0 -306
  1154. scitex/scholar/.legacy/metadata/urls/zotero_translators/Wikidata.js +0 -911
  1155. scitex/scholar/.legacy/metadata/urls/zotero_translators/Wikimedia Commons.js +0 -285
  1156. scitex/scholar/.legacy/metadata/urls/zotero_translators/Wikipedia Citation Templates.js +0 -432
  1157. scitex/scholar/.legacy/metadata/urls/zotero_translators/Wikipedia.js +0 -385
  1158. scitex/scholar/.legacy/metadata/urls/zotero_translators/Wikisource.js +0 -399
  1159. scitex/scholar/.legacy/metadata/urls/zotero_translators/Wikiwand.js +0 -122
  1160. scitex/scholar/.legacy/metadata/urls/zotero_translators/Wiktionary.js +0 -141
  1161. scitex/scholar/.legacy/metadata/urls/zotero_translators/Wildlife Biology in Practice.js +0 -172
  1162. scitex/scholar/.legacy/metadata/urls/zotero_translators/Wiley Online Library.js +0 -1412
  1163. scitex/scholar/.legacy/metadata/urls/zotero_translators/Wilson Center Digital Archive.js +0 -321
  1164. scitex/scholar/.legacy/metadata/urls/zotero_translators/Winnipeg Free Press.js +0 -204
  1165. scitex/scholar/.legacy/metadata/urls/zotero_translators/Wired.js +0 -249
  1166. scitex/scholar/.legacy/metadata/urls/zotero_translators/Womennews.js +0 -230
  1167. scitex/scholar/.legacy/metadata/urls/zotero_translators/World Digital Library.js +0 -403
  1168. scitex/scholar/.legacy/metadata/urls/zotero_translators/World History Connected.js +0 -185
  1169. scitex/scholar/.legacy/metadata/urls/zotero_translators/World Shakespeare Bibliography Online.js +0 -595
  1170. scitex/scholar/.legacy/metadata/urls/zotero_translators/WorldCat Discovery Service.js +0 -630
  1171. scitex/scholar/.legacy/metadata/urls/zotero_translators/XML ContextObject.js +0 -274
  1172. scitex/scholar/.legacy/metadata/urls/zotero_translators/YPSF.js +0 -224
  1173. scitex/scholar/.legacy/metadata/urls/zotero_translators/Yandex Books.js +0 -265
  1174. scitex/scholar/.legacy/metadata/urls/zotero_translators/Ynet.js +0 -171
  1175. scitex/scholar/.legacy/metadata/urls/zotero_translators/YouTube.js +0 -209
  1176. scitex/scholar/.legacy/metadata/urls/zotero_translators/ZIPonline.js +0 -267
  1177. scitex/scholar/.legacy/metadata/urls/zotero_translators/ZOBODAT.js +0 -341
  1178. scitex/scholar/.legacy/metadata/urls/zotero_translators/Zotero RDF.js +0 -583
  1179. scitex/scholar/.legacy/metadata/urls/zotero_translators/ZoteroBib.js +0 -94
  1180. scitex/scholar/.legacy/metadata/urls/zotero_translators/arXiv.org.js +0 -1099
  1181. scitex/scholar/.legacy/metadata/urls/zotero_translators/artnet.js +0 -207
  1182. scitex/scholar/.legacy/metadata/urls/zotero_translators/beck-online.js +0 -1339
  1183. scitex/scholar/.legacy/metadata/urls/zotero_translators/clinicaltrials.gov.js +0 -331
  1184. scitex/scholar/.legacy/metadata/urls/zotero_translators/dLibra.js +0 -367
  1185. scitex/scholar/.legacy/metadata/urls/zotero_translators/dejure.org.js +0 -242
  1186. scitex/scholar/.legacy/metadata/urls/zotero_translators/deleted.txt +0 -132
  1187. scitex/scholar/.legacy/metadata/urls/zotero_translators/dhistory.js +0 -103
  1188. scitex/scholar/.legacy/metadata/urls/zotero_translators/digibib.net.js +0 -245
  1189. scitex/scholar/.legacy/metadata/urls/zotero_translators/eLibrary.ru.js +0 -867
  1190. scitex/scholar/.legacy/metadata/urls/zotero_translators/eLife.js +0 -462
  1191. scitex/scholar/.legacy/metadata/urls/zotero_translators/eMJA.js +0 -246
  1192. scitex/scholar/.legacy/metadata/urls/zotero_translators/eMedicine.js +0 -123
  1193. scitex/scholar/.legacy/metadata/urls/zotero_translators/ePrint IACR.js +0 -608
  1194. scitex/scholar/.legacy/metadata/urls/zotero_translators/ebrary.js +0 -140
  1195. scitex/scholar/.legacy/metadata/urls/zotero_translators/etatar.ru.js +0 -104
  1196. scitex/scholar/.legacy/metadata/urls/zotero_translators/feb-web.ru.js +0 -167
  1197. scitex/scholar/.legacy/metadata/urls/zotero_translators/fishpond.co.nz.js +0 -224
  1198. scitex/scholar/.legacy/metadata/urls/zotero_translators/fr-online.de.js +0 -209
  1199. scitex/scholar/.legacy/metadata/urls/zotero_translators/govinfo.js +0 -189
  1200. scitex/scholar/.legacy/metadata/urls/zotero_translators/index.d.ts +0 -1646
  1201. scitex/scholar/.legacy/metadata/urls/zotero_translators/informIT database.js +0 -248
  1202. scitex/scholar/.legacy/metadata/urls/zotero_translators/io-port.js +0 -68
  1203. scitex/scholar/.legacy/metadata/urls/zotero_translators/jsconfig.json +0 -10
  1204. scitex/scholar/.legacy/metadata/urls/zotero_translators/jurion.js +0 -377
  1205. scitex/scholar/.legacy/metadata/urls/zotero_translators/mEDRA.js +0 -597
  1206. scitex/scholar/.legacy/metadata/urls/zotero_translators/magazines.russ.ru.js +0 -120
  1207. scitex/scholar/.legacy/metadata/urls/zotero_translators/medes.js +0 -284
  1208. scitex/scholar/.legacy/metadata/urls/zotero_translators/newshub.co.nz.js +0 -206
  1209. scitex/scholar/.legacy/metadata/urls/zotero_translators/newspapers.com.js +0 -335
  1210. scitex/scholar/.legacy/metadata/urls/zotero_translators/openJur.js +0 -161
  1211. scitex/scholar/.legacy/metadata/urls/zotero_translators/package-lock.json +0 -2345
  1212. scitex/scholar/.legacy/metadata/urls/zotero_translators/package.json +0 -24
  1213. scitex/scholar/.legacy/metadata/urls/zotero_translators/reddit.js +0 -275
  1214. scitex/scholar/.legacy/metadata/urls/zotero_translators/sbn.it.js +0 -186
  1215. scitex/scholar/.legacy/metadata/urls/zotero_translators/scinapse.js +0 -273
  1216. scitex/scholar/.legacy/metadata/urls/zotero_translators/semantics Visual Library.js +0 -643
  1217. scitex/scholar/.legacy/metadata/urls/zotero_translators/taz.de.js +0 -200
  1218. scitex/scholar/.legacy/metadata/urls/zotero_translators/unAPI.js +0 -481
  1219. scitex/scholar/.legacy/metadata/urls/zotero_translators/wiso.js +0 -314
  1220. scitex/scholar/.legacy/metadata/urls/zotero_translators/zbMATH.js +0 -278
  1221. scitex/scholar/.legacy/metadata/urls/zotero_translators/zotero.org.js +0 -311
  1222. scitex/scholar/.legacy/search/README.md +0 -205
  1223. scitex/scholar/.legacy/search/_Embedder.py +0 -329
  1224. scitex/scholar/.legacy/search/_SemanticSearch.py +0 -278
  1225. scitex/scholar/.legacy/search/_SemanticSearchEngine.py +0 -452
  1226. scitex/scholar/.legacy/search/_UnifiedSearcher.py +0 -1353
  1227. scitex/scholar/.legacy/search/_VectorDatabase.py +0 -443
  1228. scitex/scholar/.legacy/search/__init__.py +0 -25
  1229. scitex/scholar/.legacy/storage/_EnhancedStorageManager.py +0 -617
  1230. scitex/scholar/.legacy/storage/__init__.py +0 -19
  1231. scitex/scholar/CLAUDE.md +0 -257
  1232. scitex/scholar/TODO.md +0 -174
  1233. scitex/scholar/_mcp_handlers.py +0 -685
  1234. scitex/scholar/_mcp_tool_schemas.py +0 -339
  1235. scitex/scholar/docs/backup/papers-orig.bib +0 -698
  1236. scitex/scholar/docs/backup/papers.bib.zip +0 -0
  1237. scitex/scholar/docs/to_claude/bin/elisp/check_parens.sh +0 -56
  1238. scitex/scholar/docs/to_claude/bin/elisp/elisp-ci/README.md +0 -412
  1239. scitex/scholar/docs/to_claude/bin/elisp/elisp-ci/elisp-ci +0 -622
  1240. scitex/scholar/docs/to_claude/bin/elisp/elisp-ci/elisp-ci-simple +0 -105
  1241. scitex/scholar/docs/to_claude/bin/elisp/find_incorrect_require_provide_statements.sh +0 -113
  1242. scitex/scholar/docs/to_claude/bin/elisp/run_tests_elisp.sh +0 -532
  1243. scitex/scholar/docs/to_claude/bin/elisp/run_tests_elisp_v02.sh +0 -555
  1244. scitex/scholar/docs/to_claude/bin/elisp/sync_elisp_tdd.sh +0 -626
  1245. scitex/scholar/docs/to_claude/bin/general/claude_emacs_server.sh +0 -192
  1246. scitex/scholar/docs/to_claude/bin/general/create_github_release.sh +0 -36
  1247. scitex/scholar/docs/to_claude/bin/general/find_errors.sh +0 -75
  1248. scitex/scholar/docs/to_claude/bin/general/rename.sh +0 -145
  1249. scitex/scholar/docs/to_claude/bin/general/render_mermaid.sh +0 -116
  1250. scitex/scholar/docs/to_claude/bin/general/safe_rm.sh +0 -75
  1251. scitex/scholar/docs/to_claude/bin/general/view_repo.sh +0 -4
  1252. scitex/scholar/docs/to_claude/bin/general/wsl2-buzzer.sh +0 -73
  1253. scitex/scholar/docs/to_claude/bin/python/black_all.sh +0 -41
  1254. scitex/scholar/docs/to_claude/bin/python/run_tests_python_pip_package.sh +0 -291
  1255. scitex/scholar/docs/to_claude/bin/safe_rm.sh +0 -3
  1256. scitex/scholar/docs/to_claude/bin/slurm/README.md +0 -54
  1257. scitex/scholar/docs/to_claude/bin/slurm/login.sh +0 -23
  1258. scitex/scholar/docs/to_claude/bin/slurm/request.sh +0 -62
  1259. scitex/scholar/docs/to_claude/bin/slurm/run.sh +0 -73
  1260. scitex/scholar/docs/to_claude/examples/README.md +0 -9
  1261. scitex/scholar/docs/to_claude/examples/example-elisp-project-emacs-hello-world/ELISP-TEST-REPORT-20250513-012234-48-PASSED-49-TOTAL-97-PERCENT.org +0 -105
  1262. scitex/scholar/docs/to_claude/examples/example-elisp-project-emacs-hello-world/LATEST-ELISP-REPORT.org +0 -105
  1263. scitex/scholar/docs/to_claude/examples/example-elisp-project-emacs-hello-world/README.md +0 -11
  1264. scitex/scholar/docs/to_claude/examples/example-elisp-project-emacs-hello-world/run_tests.sh +0 -652
  1265. scitex/scholar/docs/to_claude/examples/example-elisp-project-emacs-hello-world/tests/test-ehw-core/ELISP-TEST-REPORT-20250512-235622-0-SUCCESS-4-TOTAL-0-PERCENT.org +0 -25
  1266. scitex/scholar/docs/to_claude/examples/example-elisp-project-emacs-hello-world/tests/test-ehw-friends/ELISP-TEST-REPORT-20250512-235622-0-SUCCESS-34-TOTAL-0-PERCENT.org +0 -66
  1267. scitex/scholar/docs/to_claude/examples/example-elisp-project-emacs-hello-world/tests/test-ehw-prep/ELISP-TEST-REPORT-20250512-235622-0-SUCCESS-5-TOTAL-0-PERCENT.org +0 -26
  1268. scitex/scholar/docs/to_claude/examples/example-elisp-project-emacs-hello-world/tests/test-ehw-utils/ELISP-TEST-REPORT-20250512-235622-0-SUCCESS-4-TOTAL-0-PERCENT.org +0 -25
  1269. scitex/scholar/docs/to_claude/examples/example-python-project-scitex/.gitignore +0 -626
  1270. scitex/scholar/docs/to_claude/examples/example-python-project-scitex/README.md +0 -155
  1271. scitex/scholar/docs/to_claude/examples/example-python-project-scitex/config/MNIST.yaml +0 -24
  1272. scitex/scholar/docs/to_claude/examples/example-python-project-scitex/config/PATH.yaml +0 -30
  1273. scitex/scholar/docs/to_claude/examples/example-python-project-scitex/data/.gitkeep +0 -0
  1274. scitex/scholar/docs/to_claude/examples/example-python-project-scitex/scripts/mnist/clf_svm.py +0 -124
  1275. scitex/scholar/docs/to_claude/examples/example-python-project-scitex/scripts/mnist/download.py +0 -165
  1276. scitex/scholar/docs/to_claude/examples/example-python-project-scitex/scripts/mnist/main.sh +0 -26
  1277. scitex/scholar/docs/to_claude/examples/example-python-project-scitex/scripts/mnist/plot_conf_mat.py +0 -86
  1278. scitex/scholar/docs/to_claude/examples/example-python-project-scitex/scripts/mnist/plot_digits.py +0 -118
  1279. scitex/scholar/docs/to_claude/examples/example-python-project-scitex/scripts/mnist/plot_umap_space.py +0 -110
  1280. scitex/scholar/docs/to_claude/guidelines/README.md +0 -9
  1281. scitex/scholar/docs/to_claude/guidelines/USER_PHILOSOPHY/01_DEVELOPMENT_CYCLE.md +0 -47
  1282. scitex/scholar/docs/to_claude/guidelines/USER_PHILOSOPHY/02_NAMING_CONVENSIONS.md +0 -91
  1283. scitex/scholar/docs/to_claude/guidelines/USER_PHILOSOPHY/03_ARCHITECTUAL_AGREEMENT_PROCESS.md +0 -86
  1284. scitex/scholar/docs/to_claude/guidelines/USER_PHILOSOPHY/04_ARCHITECTURE_PREDEFINED.md +0 -77
  1285. scitex/scholar/docs/to_claude/guidelines/USER_PHILOSOPHY/05_PRIORITY_CONFIG.md +0 -22
  1286. scitex/scholar/docs/to_claude/guidelines/USER_PHILOSOPHY/06_MULTIPLE_SPECIAL_AGENTS.md +0 -35
  1287. scitex/scholar/docs/to_claude/guidelines/USER_PHILOSOPHY/07_DEBUGGING_TECHNIQUES.md +0 -153
  1288. scitex/scholar/docs/to_claude/guidelines/command/IMPORTANT-rm.md +0 -69
  1289. scitex/scholar/docs/to_claude/guidelines/command/IMPORTANT-tree.md +0 -162
  1290. scitex/scholar/docs/to_claude/guidelines/elisp/IMPORTANT-ELISP-01-basic.md +0 -65
  1291. scitex/scholar/docs/to_claude/guidelines/elisp/IMPORTANT-ELISP-02-project-structure.md +0 -97
  1292. scitex/scholar/docs/to_claude/guidelines/elisp/IMPORTANT-ELISP-03-file-template.md +0 -70
  1293. scitex/scholar/docs/to_claude/guidelines/elisp/IMPORTANT-ELISP-04-coding-style.md +0 -42
  1294. scitex/scholar/docs/to_claude/guidelines/elisp/IMPORTANT-ELISP-05-testing-guide.md +0 -190
  1295. scitex/scholar/docs/to_claude/guidelines/elisp/IMPORTANT-ELISP-99-example-project.md +0 -15
  1296. scitex/scholar/docs/to_claude/guidelines/elisp/ci.md +0 -650
  1297. scitex/scholar/docs/to_claude/guidelines/elisp/testing-with-docker.md +0 -243
  1298. scitex/scholar/docs/to_claude/guidelines/programming_common/EXAMPLE-README-MODULE-ROOT.md +0 -32
  1299. scitex/scholar/docs/to_claude/guidelines/programming_common/EXAMPLE-README-REPOSITORY-ROOT.md +0 -60
  1300. scitex/scholar/docs/to_claude/guidelines/programming_common/IMPORTANT-art-of-readable-code.md +0 -1317
  1301. scitex/scholar/docs/to_claude/guidelines/programming_common/IMPORTANT-art-of-testing.md +0 -799
  1302. scitex/scholar/docs/to_claude/guidelines/programming_common/IMPORTANT-cleanliness.md +0 -18
  1303. scitex/scholar/docs/to_claude/guidelines/programming_common/IMPORTANT-documentation-performance-claims.md +0 -163
  1304. scitex/scholar/docs/to_claude/guidelines/programming_common/IMPORTANT-general.md +0 -156
  1305. scitex/scholar/docs/to_claude/guidelines/programming_common/IMPORTANT-refactoring.md +0 -32
  1306. scitex/scholar/docs/to_claude/guidelines/programming_common/IMPORTANT-regression-prevention.md +0 -14
  1307. scitex/scholar/docs/to_claude/guidelines/programming_common/IMPORTANT-slurm.md +0 -73
  1308. scitex/scholar/docs/to_claude/guidelines/programming_common/IMPORTANT-start-from-small.md +0 -30
  1309. scitex/scholar/docs/to_claude/guidelines/programming_common/IMPORTANT-test-driven-workflow.md +0 -80
  1310. scitex/scholar/docs/to_claude/guidelines/programming_common/IMPORTANT-version-control.md +0 -47
  1311. scitex/scholar/docs/to_claude/guidelines/programming_common/clean-code.md +0 -305
  1312. scitex/scholar/docs/to_claude/guidelines/programming_common/debugging-message.md +0 -52
  1313. scitex/scholar/docs/to_claude/guidelines/programming_common/do-not-repeat-yourself.md +0 -27
  1314. scitex/scholar/docs/to_claude/guidelines/programming_common/emacs-server.md +0 -39
  1315. scitex/scholar/docs/to_claude/guidelines/programming_common/keep-it-simple-stupid.md +0 -19
  1316. scitex/scholar/docs/to_claude/guidelines/programming_common/renaming-and-cleaning-workflow.md +0 -311
  1317. scitex/scholar/docs/to_claude/guidelines/programming_common/screen.md +0 -32
  1318. scitex/scholar/docs/to_claude/guidelines/project/IMPORTANT-CLAUDE_ID.md +0 -15
  1319. scitex/scholar/docs/to_claude/guidelines/project/IMPORTANT-beyond-control.md +0 -14
  1320. scitex/scholar/docs/to_claude/guidelines/project/IMPORTANT-bug-report.md +0 -43
  1321. scitex/scholar/docs/to_claude/guidelines/project/IMPORTANT-cleanliness.md +0 -162
  1322. scitex/scholar/docs/to_claude/guidelines/project/IMPORTANT-communication.md +0 -13
  1323. scitex/scholar/docs/to_claude/guidelines/project/IMPORTANT-do-not-create-any-new-file-nor-directory-in-project-root.md +0 -9
  1324. scitex/scholar/docs/to_claude/guidelines/project/IMPORTANT-documentation.md +0 -11
  1325. scitex/scholar/docs/to_claude/guidelines/project/IMPORTANT-feature-request.md +0 -33
  1326. scitex/scholar/docs/to_claude/guidelines/project/IMPORTANT-general-multi-agent-coordination.md +0 -311
  1327. scitex/scholar/docs/to_claude/guidelines/project/IMPORTANT-multi-agent-protocol.md +0 -97
  1328. scitex/scholar/docs/to_claude/guidelines/project/IMPORTANT-project-management-bulletin-board.md +0 -48
  1329. scitex/scholar/docs/to_claude/guidelines/project/IMPORTANT-project-management-markdown.md +0 -156
  1330. scitex/scholar/docs/to_claude/guidelines/project/IMPORTANT-project-management-org.org +0 -161
  1331. scitex/scholar/docs/to_claude/guidelines/project/IMPORTANT-tools.md +0 -10
  1332. scitex/scholar/docs/to_claude/guidelines/project/IMPORTANT-understand-message-in-filename.md +0 -12
  1333. scitex/scholar/docs/to_claude/guidelines/project/general.md +0 -7
  1334. scitex/scholar/docs/to_claude/guidelines/project/report.md +0 -50
  1335. scitex/scholar/docs/to_claude/guidelines/project/timeline-gantt-chart.md +0 -49
  1336. scitex/scholar/docs/to_claude/guidelines/python/CHECKLIST.md +0 -51
  1337. scitex/scholar/docs/to_claude/guidelines/python/HOW-TO-DEBUG-with-MULTIPLE_AGENTS.md +0 -191
  1338. scitex/scholar/docs/to_claude/guidelines/python/Machine-Learning.md +0 -15
  1339. scitex/scholar/docs/to_claude/guidelines/python/NOT-FULL-PYTEST-BUT-PARTIAL-PYTEST.md +0 -21
  1340. scitex/scholar/docs/to_claude/guidelines/python/django.md +0 -217
  1341. scitex/scholar/docs/to_claude/guidelines/python/env.md +0 -10
  1342. scitex/scholar/docs/to_claude/guidelines/python/general.md +0 -55
  1343. scitex/scholar/docs/to_claude/guidelines/python/official/cipdb-README.md +0 -219
  1344. scitex/scholar/docs/to_claude/guidelines/python/official/fastmcp-README.md +0 -442
  1345. scitex/scholar/docs/to_claude/guidelines/python/official/fastmcp-TESTING.md +0 -146
  1346. scitex/scholar/docs/to_claude/guidelines/python/official/icecream-README.md +0 -433
  1347. scitex/scholar/docs/to_claude/guidelines/python/official/priority_config-README.md +0 -126
  1348. scitex/scholar/docs/to_claude/guidelines/python/scitex/01-basic.md +0 -42
  1349. scitex/scholar/docs/to_claude/guidelines/python/scitex/02-file-template.md +0 -132
  1350. scitex/scholar/docs/to_claude/guidelines/python/scitex/03-configuration.md +0 -53
  1351. scitex/scholar/docs/to_claude/guidelines/python/scitex/04-coding-style.md +0 -126
  1352. scitex/scholar/docs/to_claude/guidelines/python/scitex/05-testing-guide.md +0 -56
  1353. scitex/scholar/docs/to_claude/guidelines/python/scitex/06-examples-guide.md +0 -42
  1354. scitex/scholar/docs/to_claude/guidelines/python/scitex/11-gen-module.md +0 -15
  1355. scitex/scholar/docs/to_claude/guidelines/python/scitex/11-session-module.md +0 -24
  1356. scitex/scholar/docs/to_claude/guidelines/python/scitex/12-io-module.md +0 -112
  1357. scitex/scholar/docs/to_claude/guidelines/python/scitex/13-plt-module.md +0 -101
  1358. scitex/scholar/docs/to_claude/guidelines/python/scitex/14-dsp-module.md +0 -78
  1359. scitex/scholar/docs/to_claude/guidelines/python/scitex/15-pd-module.md +0 -24
  1360. scitex/scholar/docs/to_claude/guidelines/python/scitex/16-stats-module.md +0 -79
  1361. scitex/scholar/docs/to_claude/guidelines/python/scitex/17-other-modules.md +0 -23
  1362. scitex/scholar/docs/to_claude/guidelines/python/scitex/17-str-module.md +0 -24
  1363. scitex/scholar/docs/to_claude/guidelines/python/scitex/18-directory-structure-for-scientific-work.md +0 -48
  1364. scitex/scholar/docs/to_claude/guidelines/python/scitex/19-directory-structure-for-pip-package.md +0 -234
  1365. scitex/scholar/docs/to_claude/guidelines/python/scitex/99-example-project.md +0 -19
  1366. scitex/scholar/docs/to_claude/guidelines/python/zen_of_python.md +0 -82
  1367. scitex/scholar/docs/to_claude/guidelines/science/IMPORTANT-general.md +0 -16
  1368. scitex/scholar/docs/to_claude/guidelines/science/IMPORTANT-scientific-attitude.md +0 -25
  1369. scitex/scholar/docs/to_claude/guidelines/science/scientific-writing-abstract.md +0 -93
  1370. scitex/scholar/docs/to_claude/guidelines/science/scientific-writing-discussion.md +0 -116
  1371. scitex/scholar/docs/to_claude/guidelines/science/scientific-writing-general-1.md +0 -157
  1372. scitex/scholar/docs/to_claude/guidelines/science/scientific-writing-general-2.md +0 -83
  1373. scitex/scholar/docs/to_claude/guidelines/science/scientific-writing-introduction.md +0 -123
  1374. scitex/scholar/docs/to_claude/guidelines/science/scientific-writing-methods.md +0 -88
  1375. scitex/scholar/docs/to_claude/guidelines/shell/IMPORTANT-general.md +0 -196
  1376. scitex/scholar/examples/SUGGESTIONS.md +0 -865
  1377. scitex/scholar/examples/dev.py +0 -38
  1378. scitex/scholar/library/neurovista/info/bibtex/seizure_prediction_enriched.bib +0 -1092
  1379. scitex/stats/_mcp_handlers.py +0 -1191
  1380. scitex/stats/_mcp_tool_schemas.py +0 -384
  1381. scitex/template/.legacy/_clone_project.py +0 -267
  1382. scitex/template/_mcp_handlers.py +0 -259
  1383. scitex/template/_mcp_tool_schemas.py +0 -112
  1384. scitex/writer/.legacy/Writer_v01-refactored.py +0 -189
  1385. scitex/writer/.legacy/_compile.py +0 -342
  1386. scitex/writer/_compile_async.py +0 -126
  1387. scitex/writer/_validate_tree_structures.py +0 -197
  1388. scitex/writer/dataclasses/config/_WriterConfig.py +0 -175
  1389. scitex/writer/dataclasses/contents/_ManuscriptContents.py +0 -236
  1390. scitex/writer/dataclasses/core/_Document.py +0 -146
  1391. scitex/writer/dataclasses/core/_DocumentSection.py +0 -546
  1392. scitex/writer/dataclasses/results/_CompilationResult.py +0 -165
  1393. scitex/writer/dataclasses/results/_LaTeXIssue.py +0 -102
  1394. scitex/writer/dataclasses/tree/MINIMUM_FILES.md +0 -121
  1395. scitex/writer/tests/__init__.py +0 -3
  1396. scitex/writer/tests/test_diff_between.py +0 -451
  1397. scitex/writer/tests/test_document_section.py +0 -311
  1398. scitex/writer/tests/test_document_workflow.py +0 -393
  1399. scitex/writer/tests/test_writer.py +0 -361
  1400. scitex/writer/tests/test_writer_integration.py +0 -303
  1401. scitex-2.13.0.dist-info/METADATA +0 -1231
  1402. scitex-2.13.0.dist-info/RECORD +0 -3402
  1403. scitex-2.13.0.dist-info/entry_points.txt +0 -11
  1404. /scitex/scholar/docs/{SUMMARY.md → 00_SUMMARY.md} +0 -0
  1405. /scitex/scholar/docs/{STORAGE_ARCHITECTURE.md → 01_STORAGE_ARCHITECTURE.md} +0 -0
  1406. /scitex/scholar/docs/{PIPELINE_ORGANIZATION.md → 02_PIPELINE_ORGANIZATION.md} +0 -0
  1407. /scitex/scholar/docs/{PIPELINE_IMPLEMENTATION_PLAN.md → 03_PIPELINE_IMPLEMENTATION_PLAN.md} +0 -0
  1408. /scitex/scholar/docs/{PIPELINE_IMPLEMENTATION_COMPLETE.md → 04_PIPELINE_IMPLEMENTATION_COMPLETE.md} +0 -0
  1409. /scitex/scholar/docs/{DETAILS_FOR_DEVELOPERS.md → 05_DETAILS_FOR_DEVELOPERS.md} +0 -0
  1410. /scitex/scholar/docs/{IMPACT_FACTOR_CITATION_INTEGRATION.md → 06_IMPACT_FACTOR_CITATION_INTEGRATION.md} +0 -0
  1411. /scitex/writer/{dataclasses → _dataclasses}/__init__.py +0 -0
  1412. /scitex/writer/{dataclasses → _dataclasses}/config/_CONSTANTS.py +0 -0
  1413. /scitex/writer/{dataclasses → _dataclasses}/config/__init__.py +0 -0
  1414. /scitex/writer/{dataclasses → _dataclasses}/contents/_RevisionContents.py +0 -0
  1415. /scitex/writer/{dataclasses → _dataclasses}/contents/_SupplementaryContents.py +0 -0
  1416. /scitex/writer/{dataclasses → _dataclasses}/contents/__init__.py +0 -0
  1417. /scitex/writer/{dataclasses → _dataclasses}/core/__init__.py +0 -0
  1418. /scitex/writer/{dataclasses → _dataclasses}/results/_SaveSectionsResponse.py +0 -0
  1419. /scitex/writer/{dataclasses → _dataclasses}/results/_SectionReadResponse.py +0 -0
  1420. /scitex/writer/{dataclasses → _dataclasses}/results/__init__.py +0 -0
  1421. /scitex/writer/{dataclasses → _dataclasses}/tree/_ConfigTree.py +0 -0
  1422. /scitex/writer/{dataclasses → _dataclasses}/tree/_ManuscriptTree.py +0 -0
  1423. /scitex/writer/{dataclasses → _dataclasses}/tree/_RevisionTree.py +0 -0
  1424. /scitex/writer/{dataclasses → _dataclasses}/tree/_ScriptsTree.py +0 -0
  1425. /scitex/writer/{dataclasses → _dataclasses}/tree/_SharedTree.py +0 -0
  1426. /scitex/writer/{dataclasses → _dataclasses}/tree/_SupplementaryTree.py +0 -0
  1427. /scitex/writer/{dataclasses → _dataclasses}/tree/__init__.py +0 -0
  1428. {scitex-2.13.0.dist-info → scitex-2.15.1.dist-info}/WHEEL +0 -0
  1429. {scitex-2.13.0.dist-info → scitex-2.15.1.dist-info}/licenses/LICENSE +0 -0
@@ -1,37 +1,110 @@
1
1
  #!/usr/bin/env python3
2
- # -*- coding: utf-8 -*-
3
- # Timestamp: "2025-10-08 05:41:15 (ywatanabe)"
4
- # File: /home/ywatanabe/proj/scitex_repo/src/scitex/scholar/storage/_LibraryManager.py
5
- # ----------------------------------------
6
- from __future__ import annotations
7
- import os
8
-
9
- __FILE__ = "./src/scitex/scholar/storage/_LibraryManager.py"
10
- __DIR__ = os.path.dirname(__FILE__)
11
- # ----------------------------------------
2
+ # Timestamp: "2026-01-24 (ywatanabe)"
3
+ # File: /home/ywatanabe/proj/scitex-python/src/scitex/scholar/storage/_LibraryManager.py
4
+
5
+ """
6
+ Unified manager for Scholar library structure and paper storage.
7
+
8
+ This module provides a comprehensive library manager that:
9
+ - Manages paper storage in the master library
10
+ - Handles metadata conversion and standardization
11
+ - Creates project symlinks for organization
12
+ - Generates BibTeX entries and structures
13
+ - Resolves DOIs and updates library metadata
14
+
15
+ The main class inherits from multiple mixins for modular functionality:
16
+ - StorageHelpersMixin: Storage helper methods (has_*, load, save)
17
+ - MetadataConversionMixin: Metadata conversion utilities
18
+ - PaperSavingMixin: Paper saving methods
19
+ - ResolutionMixin: DOI resolution and library structure creation
20
+ - SymlinkHandlersMixin: Symlink generation and management
21
+ - BibtexHandlersMixin: BibTeX structure and entry generation
22
+ - LibraryOperationsMixin: Library operations (update, validate)
23
+ """
12
24
 
13
- __FILE__ = __file__
25
+ from __future__ import annotations
14
26
 
15
- import asyncio
16
- import copy
17
- import json
18
- import re
19
- from collections import OrderedDict
20
- from datetime import datetime
21
- from pathlib import Path
22
- from typing import Any, Dict, List, Optional
27
+ from typing import Optional
23
28
 
24
29
  from scitex import logging
25
30
  from scitex.scholar.config import ScholarConfig
26
- from scitex.scholar.metadata_engines.utils import BASE_STRUCTURE, standardize_metadata
27
31
  from scitex.scholar.storage._DeduplicationManager import DeduplicationManager
28
- from scitex.scholar.utils import TextNormalizer
32
+
33
+ from ._mixins import (
34
+ BibtexHandlersMixin,
35
+ LibraryOperationsMixin,
36
+ MetadataConversionMixin,
37
+ PaperSavingMixin,
38
+ ResolutionMixin,
39
+ StorageHelpersMixin,
40
+ SymlinkHandlersMixin,
41
+ )
29
42
 
30
43
  logger = logging.getLogger(__name__)
31
44
 
32
45
 
33
- class LibraryManager:
34
- """Unified manager for Scholar library structure and paper storage."""
46
+ class LibraryManager(
47
+ StorageHelpersMixin,
48
+ MetadataConversionMixin,
49
+ PaperSavingMixin,
50
+ ResolutionMixin,
51
+ SymlinkHandlersMixin,
52
+ BibtexHandlersMixin,
53
+ LibraryOperationsMixin,
54
+ ):
55
+ """
56
+ Unified manager for Scholar library structure and paper storage.
57
+
58
+ This class provides comprehensive functionality for managing the Scholar
59
+ library, including:
60
+ - Storage helpers (check metadata, URLs, PDFs)
61
+ - Paper loading and incremental saving
62
+ - Metadata conversion to standardized format
63
+ - DOI resolution and library structure creation
64
+ - Project symlink management
65
+ - BibTeX entry generation
66
+ - Library validation and updates
67
+
68
+ Parameters
69
+ ----------
70
+ project : str, optional
71
+ Project name for organizing papers
72
+ single_doi_resolver : object, optional
73
+ DOI resolver instance for resolving DOIs from metadata
74
+ config : ScholarConfig, optional
75
+ Configuration object for Scholar settings
76
+
77
+ Attributes
78
+ ----------
79
+ config : ScholarConfig
80
+ Configuration object
81
+ project : str
82
+ Current project name
83
+ library_master_dir : Path
84
+ Path to the master library directory
85
+ single_doi_resolver : object
86
+ DOI resolver instance
87
+ dedup_manager : DeduplicationManager
88
+ Deduplication manager instance
89
+
90
+ Examples
91
+ --------
92
+ >>> # Basic usage
93
+ >>> manager = LibraryManager(project="my_research")
94
+ >>> paper_id = manager.save_resolved_paper(
95
+ ... title="My Paper",
96
+ ... doi="10.1234/example",
97
+ ... authors=["Author One", "Author Two"],
98
+ ... year=2024,
99
+ ... )
100
+
101
+ >>> # Check if paper exists
102
+ >>> has_pdf = manager.has_pdf(paper_id)
103
+ >>> has_meta = manager.has_metadata(paper_id)
104
+
105
+ >>> # Load paper
106
+ >>> paper = manager.load_paper_from_id(paper_id)
107
+ """
35
108
 
36
109
  def __init__(
37
110
  self,
@@ -47,1679 +120,8 @@ class LibraryManager:
47
120
  self._source_filename = "papers"
48
121
  self.dedup_manager = DeduplicationManager(config=self.config)
49
122
 
50
- # =========================================================================
51
- # Storage Helper Methods (Phase 1)
52
- # =========================================================================
53
-
54
- def has_metadata(self, paper_id: str) -> bool:
55
- """Check if metadata.json exists for paper.
56
-
57
- Args:
58
- paper_id: 8-digit paper ID
59
-
60
- Returns:
61
- True if metadata.json exists, False otherwise
62
- """
63
- metadata_file = self.library_master_dir / paper_id / "metadata.json"
64
- return metadata_file.exists()
65
-
66
- def has_urls(self, paper_id: str) -> bool:
67
- """Check if PDF URLs exist in metadata.
68
-
69
- Args:
70
- paper_id: 8-digit paper ID
71
-
72
- Returns:
73
- True if metadata has PDF URLs, False otherwise
74
- """
75
- if not self.has_metadata(paper_id):
76
- return False
77
-
78
- metadata_file = self.library_master_dir / paper_id / "metadata.json"
79
- try:
80
- with open(metadata_file, "r") as f:
81
- data = json.load(f)
82
-
83
- # Check nested structure: metadata.url.pdfs
84
- urls = data.get("metadata", {}).get("url", {}).get("pdfs", [])
85
- return len(urls) > 0
86
- except Exception:
87
- return False
88
-
89
- def has_pdf(self, paper_id: str) -> bool:
90
- """Check if PDF file exists in storage.
91
-
92
- Args:
93
- paper_id: 8-digit paper ID
94
-
95
- Returns:
96
- True if any PDF file exists, False otherwise
97
- """
98
- paper_dir = self.library_master_dir / paper_id
99
- if not paper_dir.exists():
100
- return False
101
-
102
- # Check for any PDF files
103
- pdf_files = list(paper_dir.glob("*.pdf"))
104
- return len(pdf_files) > 0
105
-
106
- def load_paper_from_id(self, paper_id: str) -> Optional["Paper"]:
107
- """Load Paper object from storage by ID.
108
-
109
- Args:
110
- paper_id: 8-digit paper ID
111
-
112
- Returns:
113
- Paper object if found, None otherwise
114
- """
115
- from scitex.scholar.core.Paper import Paper
116
-
117
- metadata_file = self.library_master_dir / paper_id / "metadata.json"
118
-
119
- if not metadata_file.exists():
120
- return None
121
-
122
- try:
123
- with open(metadata_file, "r") as f:
124
- data = json.load(f)
125
-
126
- # Use Paper.from_dict() which handles Pydantic validation
127
- paper = Paper.from_dict(data)
128
- return paper
129
-
130
- except Exception as e:
131
- logger.error(f"Failed to load paper {paper_id}: {e}")
132
- return None
133
-
134
- def save_paper_incremental(self, paper_id: str, paper: "Paper") -> None:
135
- """Save Paper object to storage (incremental update).
136
-
137
- This saves the complete Paper object to metadata.json,
138
- preserving existing data and updating with new fields.
139
-
140
- Args:
141
- paper_id: 8-digit paper ID
142
- paper: Paper object to save
143
- """
144
- storage_path = self.library_master_dir / paper_id
145
- storage_path.mkdir(parents=True, exist_ok=True)
146
-
147
- metadata_file = storage_path / "metadata.json"
148
-
149
- # Load existing metadata if it exists
150
- existing_data = {}
151
- if metadata_file.exists():
152
- try:
153
- with open(metadata_file, "r") as f:
154
- existing_data = json.load(f)
155
- except Exception:
156
- pass
157
-
158
- # Get new data from Paper object
159
- new_data = paper.model_dump()
160
-
161
- # Merge: new data takes precedence for non-None values
162
- merged_data = self._merge_metadata(existing_data, new_data)
163
-
164
- # Update timestamps
165
- if "container" not in merged_data:
166
- merged_data["container"] = {}
167
- merged_data["container"]["updated_at"] = datetime.now().isoformat()
168
-
169
- # Save to file
170
- with open(metadata_file, "w") as f:
171
- json.dump(merged_data, f, indent=2, ensure_ascii=False)
172
-
173
- logger.debug(f"Saved paper {paper_id} to storage")
174
-
175
- def _merge_metadata(self, existing: Dict, new: Dict) -> Dict:
176
- """Recursively merge metadata dicts, preferring new non-None values."""
177
- result = existing.copy()
178
-
179
- for key, new_value in new.items():
180
- if key not in result:
181
- result[key] = new_value
182
- elif new_value is None:
183
- # Keep existing value if new is None
184
- pass
185
- elif isinstance(new_value, dict) and isinstance(result[key], dict):
186
- # Recursively merge nested dicts
187
- result[key] = self._merge_metadata(result[key], new_value)
188
- elif isinstance(new_value, list) and len(new_value) > 0:
189
- # Update lists if new list is not empty
190
- result[key] = new_value
191
- elif new_value:
192
- # Update with new non-empty value
193
- result[key] = new_value
194
-
195
- return result
196
-
197
- # =========================================================================
198
- # Existing Methods
199
- # =========================================================================
200
-
201
- def _dotdict_to_dict(self, obj):
202
- """Recursively convert DotDict to plain dict for JSON serialization."""
203
- from scitex.dict import DotDict
204
-
205
- if isinstance(obj, DotDict):
206
- return {k: self._dotdict_to_dict(v) for k, v in obj._data.items()}
207
- elif isinstance(obj, dict):
208
- return {k: self._dotdict_to_dict(v) for k, v in obj.items()}
209
- elif isinstance(obj, list):
210
- return [self._dotdict_to_dict(item) for item in obj]
211
- else:
212
- return obj
213
-
214
- def _add_engine_to_list(self, engines_list: list, source: str) -> None:
215
- """Helper to add source to engines list if not already present."""
216
- if source and source not in engines_list:
217
- engines_list.append(source)
218
-
219
- def _convert_to_standardized_metadata(self, flat_metadata: Dict) -> OrderedDict:
220
- """Convert flat metadata dict to standardized nested structure with _engines tracking."""
221
- standardized = copy.deepcopy(BASE_STRUCTURE)
222
-
223
- # Map flat fields to standardized structure
224
- # ID section
225
- if "doi" in flat_metadata:
226
- standardized["id"]["doi"] = flat_metadata["doi"]
227
- self._add_engine_to_list(
228
- standardized["id"]["doi_engines"],
229
- flat_metadata.get("doi_source"),
230
- )
231
- if "scitex_id" in flat_metadata:
232
- standardized["id"]["scholar_id"] = flat_metadata["scitex_id"]
233
-
234
- # Basic section
235
- if "title" in flat_metadata:
236
- standardized["basic"]["title"] = flat_metadata["title"]
237
- self._add_engine_to_list(
238
- standardized["basic"]["title_engines"],
239
- flat_metadata.get("title_source"),
240
- )
241
- if "authors" in flat_metadata:
242
- standardized["basic"]["authors"] = flat_metadata["authors"]
243
- self._add_engine_to_list(
244
- standardized["basic"]["authors_engines"],
245
- flat_metadata.get("authors_source"),
246
- )
247
- if "year" in flat_metadata:
248
- standardized["basic"]["year"] = flat_metadata["year"]
249
- self._add_engine_to_list(
250
- standardized["basic"]["year_engines"],
251
- flat_metadata.get("year_source"),
252
- )
253
- if "abstract" in flat_metadata:
254
- standardized["basic"]["abstract"] = flat_metadata["abstract"]
255
- self._add_engine_to_list(
256
- standardized["basic"]["abstract_engines"],
257
- flat_metadata.get("abstract_source"),
258
- )
259
-
260
- # Citation count section
261
- if "citation_count" in flat_metadata:
262
- cc_value = flat_metadata["citation_count"]
263
- # Handle both scalar (4) and dict ({"total": 4}) formats
264
- if isinstance(cc_value, dict):
265
- # If it's a dict, extract the total value
266
- standardized["citation_count"]["total"] = cc_value.get("total")
267
- self._add_engine_to_list(
268
- standardized["citation_count"]["total_engines"],
269
- cc_value.get("total_source"),
270
- )
271
- # Copy yearly breakdowns if present
272
- for year in [
273
- "2025",
274
- "2024",
275
- "2023",
276
- "2022",
277
- "2021",
278
- "2020",
279
- "2019",
280
- "2018",
281
- "2017",
282
- "2016",
283
- "2015",
284
- ]:
285
- if year in cc_value:
286
- standardized["citation_count"][year] = cc_value[year]
287
- if f"{year}_source" in cc_value:
288
- self._add_engine_to_list(
289
- standardized["citation_count"][f"{year}_engines"],
290
- cc_value.get(f"{year}_source"),
291
- )
292
- else:
293
- # If it's a scalar, just assign it to total
294
- standardized["citation_count"]["total"] = cc_value
295
- self._add_engine_to_list(
296
- standardized["citation_count"]["total_engines"],
297
- flat_metadata.get("citation_count_source"),
298
- )
299
-
300
- # Publication section
301
- if "journal" in flat_metadata:
302
- standardized["publication"]["journal"] = flat_metadata["journal"]
303
- self._add_engine_to_list(
304
- standardized["publication"]["journal_engines"],
305
- flat_metadata.get("journal_source"),
306
- )
307
- if "short_journal" in flat_metadata:
308
- standardized["publication"]["short_journal"] = flat_metadata[
309
- "short_journal"
310
- ]
311
- if "impact_factor" in flat_metadata:
312
- standardized["publication"]["impact_factor"] = flat_metadata[
313
- "impact_factor"
314
- ]
315
- if "issn" in flat_metadata:
316
- standardized["publication"]["issn"] = flat_metadata["issn"]
317
- if "volume" in flat_metadata:
318
- standardized["publication"]["volume"] = flat_metadata["volume"]
319
- if "issue" in flat_metadata:
320
- standardized["publication"]["issue"] = flat_metadata["issue"]
321
- if "pages" in flat_metadata:
322
- # Split pages into first_page and last_page if needed
323
- pages = flat_metadata["pages"]
324
- if pages and "-" in str(pages):
325
- first, last = str(pages).split("-", 1)
326
- standardized["publication"]["first_page"] = first.strip()
327
- standardized["publication"]["last_page"] = last.strip()
328
- if "publisher" in flat_metadata:
329
- standardized["publication"]["publisher"] = flat_metadata["publisher"]
330
-
331
- # URL section
332
- if "url_doi" in flat_metadata:
333
- standardized["url"]["doi"] = flat_metadata["url_doi"]
334
- if "url_publisher" in flat_metadata:
335
- standardized["url"]["publisher"] = flat_metadata["url_publisher"]
336
- self._add_engine_to_list(
337
- standardized["url"]["publisher_engines"], "ScholarURLFinder"
338
- )
339
- if "url_openurl_query" in flat_metadata:
340
- standardized["url"]["openurl_query"] = flat_metadata["url_openurl_query"]
341
- if "url_openurl_resolved" in flat_metadata:
342
- standardized["url"]["openurl_resolved"] = flat_metadata[
343
- "url_openurl_resolved"
344
- ]
345
- self._add_engine_to_list(
346
- standardized["url"]["openurl_resolved_engines"],
347
- "ScholarURLFinder",
348
- )
349
- if "urls_pdf" in flat_metadata:
350
- standardized["url"]["pdfs"] = flat_metadata["urls_pdf"]
351
- self._add_engine_to_list(
352
- standardized["url"]["pdfs_engines"], "ScholarURLFinder"
353
- )
354
-
355
- # Path section
356
- if "pdf_path" in flat_metadata:
357
- standardized["path"]["pdfs"] = [flat_metadata["pdf_path"]]
358
- self._add_engine_to_list(
359
- standardized["path"]["pdfs_engines"],
360
- "ScholarPDFDownloaderWithScreenshotsParallel",
361
- )
362
-
363
- return standardized
364
-
365
- def _call_path_manager_get_storage_paths(
366
- self, paper_info: Dict, collection_name: str = "MASTER"
367
- ) -> Dict[str, Any]:
368
- """Helper to call PathManager's get_paper_storage_paths with proper parameters."""
369
- # Extract parameters from paper_info dict
370
- doi = paper_info.get("doi")
371
- title = paper_info.get("title")
372
- authors = paper_info.get("authors", [])
373
- year = paper_info.get("year")
374
- journal = paper_info.get("journal")
375
-
376
- # Call PathManager with individual parameters
377
- storage_path, readable_name, paper_id = (
378
- self.config.path_manager.get_paper_storage_paths(
379
- doi=doi,
380
- title=title,
381
- authors=authors,
382
- year=year,
383
- journal=journal,
384
- project=collection_name,
385
- )
386
- )
387
-
388
- # Return in the expected dict format
389
- return {
390
- "storage_path": storage_path,
391
- "readable_name": readable_name,
392
- "unique_id": paper_id,
393
- }
394
-
395
- def check_library_for_doi(
396
- self, title: str, year: Optional[int] = None
397
- ) -> Optional[str]:
398
- """Check if DOI already exists in master Scholar library."""
399
-
400
- try:
401
- for paper_dir in self.library_master_dir.iterdir():
402
- if not paper_dir.is_dir():
403
- continue
404
-
405
- metadata_file = paper_dir / "metadata.json"
406
- if metadata_file.exists():
407
- try:
408
- with open(metadata_file, "r") as file_:
409
- metadata = json.load(file_)
410
-
411
- stored_title = metadata.get("title", "")
412
- stored_year = metadata.get("year")
413
- stored_doi = metadata.get("doi")
414
-
415
- title_match = self._is_title_similar(title, stored_title)
416
- year_match = (
417
- not year
418
- or not stored_year
419
- or abs(int(stored_year) - int(year)) <= 1
420
- if isinstance(stored_year, (int, str))
421
- and str(stored_year).isdigit()
422
- else stored_year == year
423
- )
424
-
425
- if title_match and year_match and stored_doi:
426
- logger.info(
427
- f"DOI found in master Scholar library: {stored_doi} (paper_id: {paper_dir.name})"
428
- )
429
- return stored_doi
430
-
431
- except (
432
- json.JSONDecodeError,
433
- KeyError,
434
- ValueError,
435
- ) as exc_:
436
- logger.debug(
437
- f"Error reading metadata from {metadata_file}: {exc_}"
438
- )
439
- continue
440
-
441
- return None
442
-
443
- except Exception as exc_:
444
- logger.debug(f"Error checking master Scholar library: {exc_}")
445
- return None
446
-
447
- def save_resolved_paper(
448
- self,
449
- # Can accept either a Paper object or individual fields
450
- paper_data: Optional["Paper"] = None,
451
- # Required bibliographic fields (if not providing paper_data)
452
- title: Optional[str] = None,
453
- doi: Optional[str] = None,
454
- # Optional bibliographic fields
455
- authors: Optional[List[str]] = None,
456
- year: Optional[int] = None,
457
- journal: Optional[str] = None,
458
- abstract: Optional[str] = None,
459
- # Additional bibliographic fields
460
- volume: Optional[str] = None,
461
- issue: Optional[str] = None,
462
- pages: Optional[str] = None,
463
- publisher: Optional[str] = None,
464
- issn: Optional[str] = None,
465
- short_journal: Optional[str] = None,
466
- # Enrichment fields
467
- citation_count: Optional[int] = None,
468
- impact_factor: Optional[float] = None,
469
- # Source tracking (which engine/database provided this info)
470
- doi_source: Optional[str] = None,
471
- title_source: Optional[str] = None,
472
- abstract_source: Optional[str] = None,
473
- authors_source: Optional[str] = None,
474
- year_source: Optional[str] = None,
475
- journal_source: Optional[str] = None,
476
- # Library management
477
- library_id: Optional[str] = None,
478
- project: Optional[str] = None,
479
- # Legacy support (will be removed)
480
- metadata: Optional[Dict] = None,
481
- bibtex_source: Optional[str] = None,
482
- source: Optional[str] = None, # Legacy doi_source
483
- paper_id: Optional[str] = None, # Legacy library_id
484
- **kwargs, # For backward compatibility
485
- ) -> str:
486
- """Save successfully resolved paper to Scholar library."""
487
-
488
- # If paper_data is provided, extract fields from it
489
- if paper_data is not None:
490
- if hasattr(paper_data, "metadata"):
491
- # Pydantic Paper object
492
- title = title or (paper_data.metadata.basic.title or "")
493
- doi = doi or (paper_data.metadata.id.doi or "")
494
- authors = authors or paper_data.metadata.basic.authors
495
- year = year or paper_data.metadata.basic.year
496
- journal = journal or paper_data.metadata.publication.journal
497
- abstract = abstract or paper_data.metadata.basic.abstract
498
- publisher = publisher or paper_data.metadata.publication.publisher
499
- impact_factor = (
500
- impact_factor or paper_data.metadata.publication.impact_factor
501
- )
502
- library_id = library_id or paper_data.container.library_id
503
- elif isinstance(paper_data, dict):
504
- # Dict paper object
505
- title = title or paper_data.get("title", "")
506
- doi = doi or paper_data.get("doi", "")
507
- authors = authors or paper_data.get("authors", [])
508
- year = year or paper_data.get("year")
509
- journal = journal or paper_data.get("journal")
510
- abstract = abstract or paper_data.get("abstract")
511
- publisher = publisher or paper_data.get("publisher")
512
- impact_factor = impact_factor or paper_data.get("impact_factor")
513
- library_id = (
514
- library_id
515
- or paper_data.get("scitex_id")
516
- or paper_data.get("scholar_id")
517
- )
518
-
519
- # Handle legacy parameters
520
- if paper_id and not library_id:
521
- library_id = paper_id
522
- if source and not doi_source:
523
- doi_source = source
524
-
525
- # Build paper_info with explicit parameters (not metadata dict)
526
- paper_info = {
527
- "title": title,
528
- "year": year,
529
- "authors": authors or [],
530
- "doi": doi,
531
- "journal": journal,
532
- }
533
-
534
- # Only use metadata dict as fallback for backward compatibility
535
- if metadata:
536
- if not journal:
537
- journal = metadata.get("journal")
538
- paper_info["journal"] = journal
539
- if not year:
540
- year = metadata.get("year")
541
- paper_info["year"] = year
542
- if not authors:
543
- authors = metadata.get("authors")
544
- paper_info["authors"] = authors or []
545
-
546
- # Check for existing paper first (deduplication)
547
- check_metadata = {
548
- "doi": doi,
549
- "title": title,
550
- "authors": authors or [],
551
- "year": year,
552
- }
553
- existing_paper_dir = self.dedup_manager.check_for_existing_paper(check_metadata)
554
-
555
- if existing_paper_dir:
556
- logger.info(f"Found existing paper: {existing_paper_dir.name}")
557
- # Update existing paper instead of creating new
558
- master_storage_path = existing_paper_dir
559
- paper_id = existing_paper_dir.name
560
- readable_name = None # Will be determined from existing symlinks
561
- else:
562
- # Call PathManager with individual parameters for new paper
563
- storage_path, readable_name, paper_id = (
564
- self.config.path_manager.get_paper_storage_paths(
565
- doi=doi,
566
- title=title,
567
- authors=authors or [],
568
- year=year,
569
- journal=journal,
570
- project="MASTER",
571
- )
572
- )
573
- master_storage_path = storage_path
574
-
575
- # Use provided library_id if available, otherwise use generated paper_id
576
- if library_id:
577
- paper_id = library_id
578
-
579
- master_metadata_file = master_storage_path / "metadata.json"
580
-
581
- existing_metadata = {}
582
- if master_metadata_file.exists():
583
- try:
584
- with open(master_metadata_file, "r") as file_:
585
- existing_metadata = json.load(file_)
586
- except (json.JSONDecodeError, IOError):
587
- existing_metadata = {}
588
-
589
- # Clean text fields
590
- clean_title = TextNormalizer.clean_metadata_text(
591
- existing_metadata.get("title", title)
592
- )
593
-
594
- # Use explicit abstract parameter first, then metadata dict, then existing
595
- clean_abstract = None
596
- if abstract:
597
- clean_abstract = TextNormalizer.clean_metadata_text(abstract)
598
- elif metadata and metadata.get("abstract"):
599
- clean_abstract = TextNormalizer.clean_metadata_text(metadata["abstract"])
600
- elif existing_metadata.get("abstract"):
601
- clean_abstract = TextNormalizer.clean_metadata_text(
602
- existing_metadata["abstract"]
603
- )
604
-
605
- # Handle doi_source - explicit parameter takes precedence
606
- doi_source_value = doi_source or existing_metadata.get("doi_source")
607
- if not doi_source_value and source:
608
- # Normalize legacy source parameter
609
- if "crossref" in source.lower():
610
- doi_source_value = "crossref"
611
- elif "semantic" in source.lower():
612
- doi_source_value = "semantic_scholar"
613
- elif "pubmed" in source.lower():
614
- doi_source_value = "pubmed"
615
- elif "openalex" in source.lower():
616
- doi_source_value = "openalex"
617
- else:
618
- doi_source_value = source
619
-
620
- comprehensive_metadata = {
621
- # Core bibliographic fields
622
- "title": clean_title,
623
- "title_source": title_source
624
- or existing_metadata.get("title_source", "input"),
625
- "doi": existing_metadata.get("doi", doi),
626
- "doi_source": doi_source_value,
627
- "year": existing_metadata.get("year", year),
628
- "year_source": year_source
629
- or existing_metadata.get("year_source", "input" if year else None),
630
- "authors": existing_metadata.get("authors", authors or []),
631
- "authors_source": authors_source
632
- or existing_metadata.get("authors_source", "input" if authors else None),
633
- "journal": existing_metadata.get("journal", journal),
634
- "journal_source": journal_source
635
- or existing_metadata.get("journal_source", "input" if journal else None),
636
- # Additional bibliographic fields from explicit parameters
637
- "volume": existing_metadata.get("volume", volume),
638
- "issue": existing_metadata.get("issue", issue),
639
- "pages": existing_metadata.get("pages", pages),
640
- "publisher": existing_metadata.get("publisher", publisher),
641
- "issn": existing_metadata.get("issn", issn),
642
- "short_journal": existing_metadata.get("short_journal", short_journal),
643
- # Abstract with source tracking
644
- "abstract": existing_metadata.get("abstract", clean_abstract),
645
- "abstract_source": abstract_source
646
- or existing_metadata.get("abstract_source", "input" if abstract else None),
647
- # Enrichment fields
648
- "citation_count": existing_metadata.get("citation_count", citation_count),
649
- "impact_factor": existing_metadata.get("impact_factor", impact_factor),
650
- "scitex_id": existing_metadata.get(
651
- "scitex_id", existing_metadata.get("scholar_id", paper_id)
652
- ),
653
- "created_at": existing_metadata.get(
654
- "created_at", datetime.now().isoformat()
655
- ),
656
- "created_by": existing_metadata.get("created_by", "SciTeX Scholar"),
657
- "updated_at": datetime.now().isoformat(),
658
- "projects": existing_metadata.get(
659
- "projects", [] if self.project == "master" else [self.project]
660
- ),
661
- "master_storage_path": str(master_storage_path),
662
- "readable_name": readable_name,
663
- "metadata_file": str(master_metadata_file),
664
- }
665
-
666
- # Store plain dict version for JSON serialization
667
- comprehensive_metadata_plain = self._dotdict_to_dict(comprehensive_metadata)
668
-
669
- # Convert to standardized format before saving
670
- standardized_metadata = self._convert_to_standardized_metadata(
671
- comprehensive_metadata_plain
672
- )
673
-
674
- # Wrap with Paper container properties
675
- final_structure = OrderedDict(
676
- [
677
- ("metadata", standardized_metadata),
678
- (
679
- "container",
680
- OrderedDict(
681
- [
682
- (
683
- "scitex_id",
684
- comprehensive_metadata_plain.get("scitex_id"),
685
- ),
686
- ("library_id", paper_id),
687
- (
688
- "created_at",
689
- comprehensive_metadata_plain.get("created_at"),
690
- ),
691
- (
692
- "created_by",
693
- comprehensive_metadata_plain.get("created_by"),
694
- ),
695
- (
696
- "updated_at",
697
- comprehensive_metadata_plain.get("updated_at"),
698
- ),
699
- (
700
- "projects",
701
- comprehensive_metadata_plain.get("projects", []),
702
- ),
703
- ("master_storage_path", str(master_storage_path)),
704
- ("readable_name", readable_name),
705
- ("metadata_file", str(master_metadata_file)),
706
- (
707
- "pdf_downloaded_at",
708
- comprehensive_metadata_plain.get("pdf_downloaded_at"),
709
- ),
710
- (
711
- "pdf_size_bytes",
712
- comprehensive_metadata_plain.get("pdf_size_bytes"),
713
- ),
714
- ]
715
- ),
716
- ),
717
- ]
718
- )
719
-
720
- with open(master_metadata_file, "w") as file_:
721
- json.dump(final_structure, file_, indent=2, ensure_ascii=False)
722
-
723
- logger.success(f"Saved paper to MASTER Scholar library: {paper_id}")
724
-
725
- # Create project symlink if project is specified and not MASTER
726
- if self.project and self.project not in ["master", "MASTER"]:
727
- try:
728
- # Use centralized naming logic - use original comprehensive_metadata (not plain)
729
- readable_name = self._generate_readable_name(
730
- comprehensive_metadata=comprehensive_metadata,
731
- master_storage_path=master_storage_path,
732
- authors=authors,
733
- year=year,
734
- journal=journal,
735
- )
736
-
737
- self._create_project_symlink(
738
- master_storage_path=master_storage_path,
739
- project=self.project,
740
- readable_name=readable_name,
741
- )
742
- except Exception as exc_:
743
- logger.error(f"Failed to create symlink for {paper_id}: {exc_}")
744
-
745
- return paper_id
746
-
747
- def save_unresolved_paper(
748
- self,
749
- title: str,
750
- year: Optional[int] = None,
751
- authors: Optional[List[str]] = None,
752
- reason: str = "DOI not found",
753
- bibtex_source: Optional[str] = None,
754
- ) -> None:
755
- """Save paper that couldn't be resolved to unresolved directory."""
756
- clean_title = TextNormalizer.clean_metadata_text(title) if title else ""
757
- unresolved_info = {
758
- "title": clean_title,
759
- "year": year,
760
- "authors": authors or [],
761
- "reason": reason,
762
- "bibtex_source": bibtex_source,
763
- "project": self.project,
764
- "created_at": datetime.now().isoformat(),
765
- "created_by": "SciTeX Scholar",
766
- }
767
-
768
- project_lib_path = (
769
- self.config.path_manager.get_scholar_library_path() / self.project
770
- )
771
- unresolved_dir = project_lib_path / "unresolved"
772
- unresolved_dir.mkdir(parents=True, exist_ok=True)
773
-
774
- safe_title = title or "untitled"
775
- safe_title = re.sub(r"[^\w\s-]", "", safe_title)[:50]
776
- safe_title = re.sub(r"[-\s]+", "_", safe_title)
777
- timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
778
- unresolved_file = unresolved_dir / f"{safe_title}_{timestamp}.json"
779
-
780
- with open(unresolved_file, "w") as file_:
781
- json.dump(unresolved_info, file_, indent=2, ensure_ascii=False)
782
-
783
- logger.warning(f"Saved unresolved entry: {unresolved_file.name}")
784
-
785
- async def resolve_and_create_library_structure_async(
786
- self,
787
- papers: List[Dict[str, Any]],
788
- project: str,
789
- sources: Optional[List[str]] = None,
790
- ) -> Dict[str, Dict[str, str]]:
791
- """Resolve DOIs and create full Scholar library structure with proper paths."""
792
- if not self.single_doi_resolver:
793
- raise ValueError("SingleDOIResolver is required for resolving DOIs")
794
-
795
- results = {}
796
- for paper in papers:
797
- title = paper.get("title")
798
- if not title:
799
- logger.warning(f"Skipping paper without title: {paper}")
800
- continue
801
-
802
- logger.info(f"Processing: {title[:50]}...")
803
-
804
- try:
805
- doi_result = await self.single_doi_resolver.metadata2doi_async(
806
- title=title,
807
- year=paper.get("year"),
808
- authors=paper.get("authors"),
809
- sources=sources,
810
- )
811
-
812
- enhanced_metadata = self._extract_enhanced_metadata(doi_result, paper)
813
- paper_info = {**paper, **enhanced_metadata}
814
-
815
- storage_paths = self._call_path_manager_get_storage_paths(
816
- paper_info=paper_info, collection_name="MASTER"
817
- )
818
- paper_id = storage_paths["unique_id"]
819
- storage_path = storage_paths["storage_path"]
820
- metadata_file = storage_path / "metadata.json"
821
-
822
- complete_metadata = self._create_complete_metadata(
823
- paper, doi_result, paper_id, enhanced_metadata
824
- )
825
-
826
- with open(metadata_file, "w") as file_:
827
- json.dump(complete_metadata, file_, indent=2)
828
-
829
- logger.success(
830
- f"Saved metadata.json for {paper_id} ({len(complete_metadata)} fields)"
831
- )
832
-
833
- project_symlink_path = self._create_project_symlink(
834
- master_storage_path=storage_path,
835
- project=project,
836
- readable_name=storage_paths["readable_name"],
837
- )
838
-
839
- bibtex_source_filename = getattr(self, "_source_filename", "papers")
840
- info_dir = self._create_bibtex_info_structure(
841
- project=project,
842
- paper_info={**paper, **enhanced_metadata},
843
- complete_metadata=complete_metadata,
844
- bibtex_source_filename=bibtex_source_filename,
845
- )
846
-
847
- results[title] = {
848
- "scitex_id": paper_id,
849
- "scholar_id": paper_id,
850
- "doi": complete_metadata.get("doi"),
851
- "master_storage_path": str(storage_path),
852
- "project_symlink_path": (
853
- str(project_symlink_path) if project_symlink_path else None
854
- ),
855
- "readable_name": storage_paths["readable_name"],
856
- "metadata_file": str(metadata_file),
857
- "info_dir": str(info_dir) if info_dir else None,
858
- }
859
-
860
- logger.info(f"Created library entry: {paper_id}")
861
- if complete_metadata.get("doi"):
862
- logger.info(f" DOI: {complete_metadata['doi']}")
863
- logger.info(f" Storage: {storage_path}")
864
-
865
- except Exception as exc_:
866
- logger.error(f"❌ Error processing '{title[:30]}...': {exc_}")
867
-
868
- logger.success(
869
- f"Created Scholar library entries for {len(results)}/{len(papers)} papers"
870
- )
871
- return results
872
-
873
- async def resolve_and_create_library_structure_with_source_async(
874
- self,
875
- papers: List[Dict[str, Any]],
876
- project: str,
877
- sources: Optional[List[str]] = None,
878
- bibtex_source_filename: str = "papers",
879
- ) -> Dict[str, Dict[str, str]]:
880
- """Enhanced version that passes source filename for BibTeX structure."""
881
- self._source_filename = bibtex_source_filename
882
- return await self.resolve_and_create_library_structure_async(
883
- papers=papers, project=project, sources=sources
884
- )
885
-
886
- def _extract_enhanced_metadata(
887
- self, doi_result: Optional[Dict], paper: Dict
888
- ) -> Dict[str, Any]:
889
- """Extract enhanced metadata from DOI resolution result."""
890
- enhanced = {}
891
- if doi_result and isinstance(doi_result, dict):
892
- metadata_source = doi_result.get("metadata", {})
893
- enhanced.update(
894
- {
895
- "doi": doi_result.get("doi"),
896
- "journal": metadata_source.get("journal")
897
- or doi_result.get("journal")
898
- or paper.get("journal"),
899
- "authors": metadata_source.get("authors")
900
- or doi_result.get("authors")
901
- or paper.get("authors"),
902
- "year": metadata_source.get("year")
903
- or doi_result.get("year")
904
- or paper.get("year"),
905
- "title": metadata_source.get("title")
906
- or doi_result.get("title")
907
- or paper.get("title"),
908
- "abstract": metadata_source.get("abstract")
909
- or doi_result.get("abstract"),
910
- "publisher": metadata_source.get("publisher")
911
- or doi_result.get("publisher"),
912
- "volume": metadata_source.get("volume") or doi_result.get("volume"),
913
- "issue": metadata_source.get("issue") or doi_result.get("issue"),
914
- "pages": metadata_source.get("pages") or doi_result.get("pages"),
915
- "issn": metadata_source.get("issn") or doi_result.get("issn"),
916
- "short_journal": metadata_source.get("short_journal")
917
- or doi_result.get("short_journal"),
918
- }
919
- )
920
-
921
- if doi_result.get("doi"):
922
- logger.success(
923
- f"Enhanced metadata from DOI source: {dict(metadata_source)}"
924
- )
925
-
926
- return enhanced
927
-
928
- def _create_complete_metadata(
929
- self,
930
- paper: Dict,
931
- doi_result: Optional[Dict],
932
- paper_id: str,
933
- enhanced_metadata: Dict,
934
- ) -> Dict[str, Any]:
935
- """Create complete metadata dictionary with source tracking."""
936
- raw_title = enhanced_metadata.get("title") or paper.get("title")
937
- clean_title = TextNormalizer.clean_metadata_text(raw_title) if raw_title else ""
938
- raw_abstract = None
939
- if enhanced_metadata.get("abstract"):
940
- raw_abstract = TextNormalizer.clean_metadata_text(
941
- enhanced_metadata["abstract"]
942
- )
943
-
944
- doi_source_value = None
945
- if doi_result and doi_result.get("source"):
946
- source = doi_result["source"]
947
- if "crossref" in source.lower():
948
- doi_source_value = "crossref"
949
- elif "semantic" in source.lower():
950
- doi_source_value = "semantic_scholar"
951
- elif "pubmed" in source.lower():
952
- doi_source_value = "pubmed"
953
- elif "openalex" in source.lower():
954
- doi_source_value = "openalex"
955
- else:
956
- doi_source_value = source
957
-
958
- complete_metadata = {
959
- "title": clean_title,
960
- "title_source": (
961
- doi_source_value
962
- if enhanced_metadata.get("title") != paper.get("title")
963
- else "manual"
964
- ),
965
- "authors": enhanced_metadata.get("authors") or paper.get("authors"),
966
- "authors_source": (
967
- doi_source_value
968
- if enhanced_metadata.get("authors") != paper.get("authors")
969
- else ("manual" if paper.get("authors") else None)
970
- ),
971
- "year": enhanced_metadata.get("year") or paper.get("year"),
972
- "year_source": (
973
- doi_source_value
974
- if enhanced_metadata.get("year") != paper.get("year")
975
- else ("manual" if paper.get("year") else None)
976
- ),
977
- "journal": enhanced_metadata.get("journal") or paper.get("journal"),
978
- "journal_source": (
979
- doi_source_value
980
- if enhanced_metadata.get("journal") != paper.get("journal")
981
- else ("manual" if paper.get("journal") else None)
982
- ),
983
- "abstract": raw_abstract,
984
- "abstract_source": (
985
- doi_source_value if enhanced_metadata.get("abstract") else None
986
- ),
987
- "scitex_id": paper_id,
988
- "created_at": datetime.now().isoformat(),
989
- "created_by": "SciTeX Scholar",
990
- }
991
-
992
- if doi_result and isinstance(doi_result, dict):
993
- safe_fields = [
994
- "publisher",
995
- "volume",
996
- "issue",
997
- "pages",
998
- "issn",
999
- "short_journal",
1000
- ]
1001
- for field in safe_fields:
1002
- value = enhanced_metadata.get(field)
1003
- if value is not None:
1004
- complete_metadata[field] = value
1005
- complete_metadata[f"{field}_source"] = (
1006
- doi_source_value or "unknown_api"
1007
- )
1008
-
1009
- if doi_result and doi_result.get("doi"):
1010
- complete_metadata.update(
1011
- {"doi": doi_result["doi"], "doi_source": doi_source_value}
1012
- )
1013
- logger.success(f"DOI resolved for {paper_id}: {doi_result['doi']}")
1014
- else:
1015
- complete_metadata.update(
1016
- {
1017
- "doi": None,
1018
- "doi_source": None,
1019
- "doi_resolution_failed": True,
1020
- }
1021
- )
1022
- logger.warning(
1023
- f"DOI resolution failed for {paper_id}: {paper.get('title', '')[:40]}..."
1024
- )
1025
-
1026
- standard_fields = {
1027
- "keywords": None,
1028
- "references": None,
1029
- "venue": None,
1030
- "publisher": None,
1031
- "volume": None,
1032
- "issue": None,
1033
- "pages": None,
1034
- "issn": None,
1035
- "short_journal": None,
1036
- }
1037
-
1038
- missing_fields = []
1039
- for field, default_value in standard_fields.items():
1040
- if field not in complete_metadata or complete_metadata[field] is None:
1041
- complete_metadata[field] = default_value
1042
- missing_fields.append(field)
1043
-
1044
- if missing_fields:
1045
- logger.info(
1046
- f"Missing fields for future enhancement: {', '.join(missing_fields)}"
1047
- )
1048
-
1049
- storage_paths = self._call_path_manager_get_storage_paths(
1050
- paper_info={**paper, **enhanced_metadata}, collection_name="MASTER"
1051
- )
1052
- storage_path = storage_paths["storage_path"]
1053
-
1054
- complete_metadata.update(
1055
- {
1056
- "master_storage_path": str(storage_path),
1057
- "readable_name": storage_paths["readable_name"],
1058
- "metadata_file": str(storage_path / "metadata.json"),
1059
- }
1060
- )
1061
-
1062
- return complete_metadata
1063
-
1064
- def _generate_readable_name(
1065
- self,
1066
- comprehensive_metadata: Dict,
1067
- master_storage_path: Path,
1068
- authors: Optional[List[str]] = None,
1069
- year: Optional[int] = None,
1070
- journal: Optional[str] = None,
1071
- ) -> str:
1072
- """Generate readable symlink name from metadata.
1073
-
1074
- Single source of truth for symlink naming format.
1075
- """
1076
- # Extract author
1077
- first_author = "Unknown"
1078
- if authors and len(authors) > 0:
1079
- author_parts = authors[0].split()
1080
- first_author = (
1081
- author_parts[-1] if len(author_parts) > 1 else author_parts[0]
1082
- )
1083
- first_author = "".join(c for c in first_author if c.isalnum() or c == "-")[
1084
- :20
1085
- ]
1086
-
1087
- # Format year (handle DotDict and other non-int types)
1088
- from scitex.dict import DotDict
1089
-
1090
- if isinstance(year, DotDict):
1091
- # Extract value if it's a DotDict
1092
- year = None # Can't extract year from DotDict structure, use Unknown
1093
-
1094
- # Convert to int if it's a string representation
1095
- if isinstance(year, str) and year.isdigit():
1096
- year = int(year)
1097
-
1098
- # Only use year if it's actually an int
1099
- if isinstance(year, int):
1100
- year_str = f"{year:04d}"
1101
- else:
1102
- year_str = "0000"
1103
-
1104
- # Clean journal name using PathManager (single source of truth)
1105
- journal_clean = "Unknown"
1106
- if journal:
1107
- journal_clean = self.config.path_manager._sanitize_filename(journal)[:30]
1108
- if not journal_clean:
1109
- journal_clean = "Unknown"
1110
-
1111
- # Get citation count and impact factor (handle both flat and nested formats)
1112
- # Check if this is the nested structure from file (has "metadata" key)
1113
- if "metadata" in comprehensive_metadata:
1114
- # Nested structure from file
1115
- metadata_section = comprehensive_metadata.get("metadata", {})
1116
-
1117
- # Extract citation count from nested structure
1118
- cc_val = metadata_section.get("citation_count", {})
1119
- if isinstance(cc_val, dict):
1120
- cc = cc_val.get("total", 0) or 0
1121
- else:
1122
- cc = cc_val or 0
1123
-
1124
- # Extract impact factor from nested structure
1125
- publication_section = metadata_section.get("publication", {})
1126
- if_val = publication_section.get("impact_factor", 0.0) or 0.0
1127
-
1128
- else:
1129
- # Flat structure (during initial save)
1130
- cc_val = comprehensive_metadata.get("citation_count", 0)
1131
- if isinstance(cc_val, dict):
1132
- cc = cc_val.get("total", 0) or 0
1133
- else:
1134
- cc = cc_val or 0
1135
-
1136
- # Try multiple paths for impact_factor
1137
- if_val = (
1138
- comprehensive_metadata.get("journal_impact_factor")
1139
- or comprehensive_metadata.get("impact_factor")
1140
- or comprehensive_metadata.get("publication", {}).get("impact_factor")
1141
- )
1142
- if isinstance(if_val, dict):
1143
- if_val = if_val.get("value", 0.0) or 0.0
1144
- else:
1145
- if_val = if_val or 0.0
1146
-
1147
- # Check PDF status with more granular states
1148
- pdf_files = list(master_storage_path.glob("*.pdf"))
1149
- screenshot_dir = master_storage_path / "screenshots"
1150
- has_screenshots = screenshot_dir.exists() and any(screenshot_dir.iterdir())
1151
- downloading_marker = master_storage_path / ".downloading"
1152
- attempted_marker = master_storage_path / ".download_attempted"
1153
-
1154
- # Extract DOI from metadata to check availability
1155
- doi = None
1156
- if "metadata" in comprehensive_metadata:
1157
- # Nested structure from file
1158
- doi = comprehensive_metadata.get("metadata", {}).get("id", {}).get("doi")
1159
- else:
1160
- # Flat structure (during initial save)
1161
- doi = comprehensive_metadata.get("doi")
1162
-
1163
- if downloading_marker.exists():
1164
- # Download in progress
1165
- pdf_status_letter = "r"
1166
- elif pdf_files:
1167
- # Has PDF = Successful
1168
- pdf_status_letter = "s"
1169
- elif has_screenshots:
1170
- # Has screenshots but no PDF = Failed (attempted but failed)
1171
- pdf_status_letter = "f"
1172
- elif attempted_marker.exists():
1173
- # Download was attempted but failed early (before screenshots)
1174
- pdf_status_letter = "f"
1175
- elif not doi:
1176
- # No DOI = Failed (cannot download without identifier)
1177
- pdf_status_letter = "f"
1178
- else:
1179
- # No PDF, no screenshots, no attempts, has DOI = Pending (not attempted yet)
1180
- pdf_status_letter = "p"
1181
-
1182
- pdf_status_id_map = {
1183
- "p": 0,
1184
- "r": 1,
1185
- "f": 2,
1186
- "s": 3,
1187
- }
1188
- pdf_status_str = f"{pdf_status_id_map[pdf_status_letter]}{pdf_status_letter}"
1189
- # Format: CC_000000-PDF_s-IF_032-2016-Author-Journal
1190
- # PDF status: r=running, s=successful, f=failed, p=pending
1191
- # readable_name = f"CC_{cc:06d}-PDF_{pdf_status_letter}-IF_{int(if_val):03d}-{year_str}-{first_author}-{journal_clean}"
1192
- readable_name = f"PDF-{pdf_status_str}_CC-{cc:06d}_IF-{int(if_val):03d}_{year_str}_{first_author}_{journal_clean}"
1193
-
1194
- return readable_name
1195
-
1196
- def update_symlink(
1197
- self,
1198
- master_storage_path: Path,
1199
- project: str,
1200
- metadata: Optional[Dict] = None,
1201
- ) -> Optional[Path]:
1202
- """Update project symlink to reflect current paper status.
1203
-
1204
- This should be called whenever paper status changes (pending → running → success/failed).
1205
- Generates new readable name based on current state (checking .downloading marker, PDFs, etc.)
1206
- and updates the symlink accordingly.
1207
-
1208
- Args:
1209
- master_storage_path: Path to paper in master library
1210
- project: Project name
1211
- metadata: Optional metadata dict (if not provided, will read from file)
1212
-
1213
- Returns:
1214
- Path to the created symlink, or None if failed
1215
- """
1216
- try:
1217
- # Load metadata if not provided
1218
- if metadata is None:
1219
- metadata_file = master_storage_path / "metadata.json"
1220
- if metadata_file.exists():
1221
- import json
1222
-
1223
- with open(metadata_file, "r") as f:
1224
- metadata = json.load(f)
1225
- else:
1226
- logger.warning(f"No metadata found for {master_storage_path.name}")
1227
- return None
1228
-
1229
- # Extract metadata from nested structure if needed
1230
- # Metadata file has structure: {"metadata": {"basic": {...}, "id": {...}, ...}, "container": {...}}
1231
- if "metadata" in metadata:
1232
- # Nested structure from file
1233
- meta_section = metadata.get("metadata", {})
1234
- basic_section = meta_section.get("basic", {})
1235
- pub_section = meta_section.get("publication", {})
1236
-
1237
- authors = basic_section.get("authors")
1238
- year = basic_section.get("year")
1239
- journal = pub_section.get("journal")
1240
- else:
1241
- # Flat structure (should not happen when reading from file, but handle it)
1242
- authors = metadata.get("authors")
1243
- year = metadata.get("year")
1244
- journal = metadata.get("journal")
1245
-
1246
- # Generate readable name based on current state
1247
- readable_name = self._generate_readable_name(
1248
- comprehensive_metadata=metadata,
1249
- master_storage_path=master_storage_path,
1250
- authors=authors,
1251
- year=year,
1252
- journal=journal,
1253
- )
1254
-
1255
- # Create/update symlink
1256
- return self._create_project_symlink(
1257
- master_storage_path=master_storage_path,
1258
- project=project,
1259
- readable_name=readable_name,
1260
- )
1261
- except Exception as exc_:
1262
- logger.error(
1263
- f"Failed to update symlink for {master_storage_path.name}: {exc_}"
1264
- )
1265
- return None
1266
-
1267
- def _create_project_symlink(
1268
- self, master_storage_path: Path, project: str, readable_name: str
1269
- ) -> Optional[Path]:
1270
- """Create symlink in project directory pointing to master storage.
1271
-
1272
- Removes old symlinks for the same paper with different statuses
1273
- (e.g., removes PDF_p when creating PDF_s).
1274
- """
1275
-
1276
- try:
1277
- project_dir = self.config.path_manager.get_library_project_dir(project)
1278
- symlink_path = project_dir / readable_name
1279
-
1280
- # Extract the master ID from the target path to find old symlinks
1281
- master_id = master_storage_path.name
1282
-
1283
- # Remove old symlinks pointing to the same master entry
1284
- # but with different statuses (PDF_p, PDF_f, PDF_s)
1285
- for existing_link in project_dir.iterdir():
1286
- if not existing_link.is_symlink():
1287
- continue
1288
-
1289
- # Check if this symlink points to the same master entry
1290
- try:
1291
- target = existing_link.resolve()
1292
- if target.name == master_id and existing_link.name != readable_name:
1293
- # This is an old symlink for the same paper
1294
- logger.debug(f"Removing old symlink: {existing_link.name}")
1295
- existing_link.unlink()
1296
- except Exception as e:
1297
- # Handle broken symlinks
1298
- logger.debug(f"Skipping broken symlink {existing_link.name}: {e}")
1299
- continue
1300
-
1301
- # Create new symlink
1302
- if not symlink_path.exists():
1303
- relative_path = os.path.relpath(master_storage_path, project_dir)
1304
- symlink_path.symlink_to(relative_path)
1305
- logger.success(
1306
- f"Created project symlink: {symlink_path} -> {relative_path}"
1307
- )
1308
- else:
1309
- logger.debug(f"Project symlink already exists: {symlink_path}")
1310
-
1311
- return symlink_path
1312
-
1313
- except Exception as exc_:
1314
- logger.warning(f"Failed to create project symlink: {exc_}")
1315
- return None
1316
-
1317
- def _create_bibtex_info_structure(
1318
- self,
1319
- project: str,
1320
- paper_info: Dict[str, Any],
1321
- complete_metadata: Dict[str, Any],
1322
- bibtex_source_filename: str = "papers",
1323
- ) -> Optional[Path]:
1324
- """Create info/papers_bib/pac.bib structure."""
1325
- try:
1326
- project_dir = self.config.path_manager.get_library_project_dir(project)
1327
- info_dir = project_dir / "info" / f"{bibtex_source_filename}_bib"
1328
- info_dir.mkdir(parents=True, exist_ok=True)
1329
-
1330
- bibtex_file = info_dir / f"{bibtex_source_filename}.bib"
1331
- unresolved_dir = info_dir / "unresolved"
1332
- unresolved_dir.mkdir(parents=True, exist_ok=True)
1333
-
1334
- first_author = "unknown"
1335
- if complete_metadata.get("authors"):
1336
- authors = complete_metadata["authors"]
1337
- if isinstance(authors, list) and authors:
1338
- first_author = str(authors[0]).split()[-1].lower()
1339
- elif isinstance(authors, str):
1340
- first_author = authors.split()[-1].lower()
1341
-
1342
- year = complete_metadata.get("year", "unknown")
1343
- entry_key = f"{first_author}{year}"
1344
-
1345
- bibtex_entry = self._generate_bibtex_entry(complete_metadata, entry_key)
1346
-
1347
- if bibtex_file.exists():
1348
- with open(bibtex_file, "a", encoding="utf-8") as file_:
1349
- file_.write(f"\n{bibtex_entry}")
1350
- else:
1351
- with open(bibtex_file, "w", encoding="utf-8") as file_:
1352
- file_.write(bibtex_entry)
1353
-
1354
- if not complete_metadata.get("doi"):
1355
- unresolved_file = unresolved_dir / f"{entry_key}.json"
1356
- unresolved_data = {
1357
- "title": complete_metadata.get("title", ""),
1358
- "authors": complete_metadata.get("authors", []),
1359
- "year": complete_metadata.get("year", ""),
1360
- "journal": complete_metadata.get("journal", ""),
1361
- "scholar_id": complete_metadata.get("scholar_id", ""),
1362
- "resolution_failed": True,
1363
- "timestamp": complete_metadata.get("created_at", ""),
1364
- }
1365
- with open(unresolved_file, "w", encoding="utf-8") as file_:
1366
- json.dump(unresolved_data, file_, indent=2)
1367
- logger.info(f"Added unresolved entry: {unresolved_file}")
1368
-
1369
- logger.success(f"Updated BibTeX info structure: {bibtex_file}")
1370
- return info_dir
1371
-
1372
- except Exception as exc_:
1373
- logger.warning(f"Failed to create BibTeX info structure: {exc_}")
1374
- return None
1375
-
1376
- def _generate_bibtex_entry(self, metadata: Dict[str, Any], entry_key: str) -> str:
1377
- """Generate BibTeX entry from metadata."""
1378
- entry_type = "article"
1379
- if metadata.get("journal"):
1380
- entry_type = "article"
1381
- elif metadata.get("booktitle"):
1382
- entry_type = "inproceedings"
1383
- elif metadata.get("publisher") and not metadata.get("journal"):
1384
- entry_type = "book"
1385
-
1386
- bibtex = f"@{entry_type}{{{entry_key},\n"
1387
-
1388
- field_mappings = {
1389
- "title": "title",
1390
- "authors": "author",
1391
- "year": "year",
1392
- "journal": "journal",
1393
- "doi": "doi",
1394
- "volume": "volume",
1395
- "issue": "number",
1396
- "pages": "pages",
1397
- "publisher": "publisher",
1398
- "booktitle": "booktitle",
1399
- "abstract": "abstract",
1400
- }
1401
-
1402
- for meta_field, bibtex_field in field_mappings.items():
1403
- value = metadata.get(meta_field)
1404
- if value:
1405
- if isinstance(value, list):
1406
- value = " and ".join(str(val_) for val_ in value)
1407
- value_escaped = str(value).replace("{", "\\{").replace("}", "\\}")
1408
- bibtex += f" {bibtex_field} = {{{value_escaped}}},\n"
1409
-
1410
- source_field = f"{meta_field}_source"
1411
- if source_field in metadata:
1412
- bibtex += f" % {bibtex_field}_source = {metadata[source_field]}\n"
1413
-
1414
- bibtex += f" % scholar_id = {metadata.get('scholar_id', 'unknown')},\n"
1415
- bibtex += f" % created_at = {metadata.get('created_at', 'unknown')},\n"
1416
- bibtex += f" % created_by = {metadata.get('created_by', 'unknown')},\n"
1417
- bibtex += "}\n"
1418
-
1419
- return bibtex
1420
-
1421
- # def _ensure_project_symlink(
1422
- # self,
1423
- # title: str,
1424
- # year: Optional[int] = None,
1425
- # authors: Optional[List[str]] = None,
1426
- # paper_id: str = None,
1427
- # master_storage_path: Path = None,
1428
- # ) -> None:
1429
- # """Ensure project symlink exists for paper in master library."""
1430
- # try:
1431
- # if not paper_id or not master_storage_path:
1432
- # return
1433
-
1434
- # project_lib_path = (
1435
- # self.config.path_manager.get_scholar_library_path()
1436
- # / self.project
1437
- # )
1438
- # project_lib_path.mkdir(parents=True, exist_ok=True)
1439
-
1440
- # paper_info = {
1441
- # "title": title,
1442
- # "year": year,
1443
- # "authors": authors or [],
1444
- # }
1445
- # readable_paths = self.config.path_manager.get_paper_storage_paths(
1446
- # paper_info=paper_info, collection_name=self.project
1447
- # )
1448
- # readable_name = readable_paths["readable_name"]
1449
- # symlink_path = project_lib_path / readable_name
1450
-
1451
- # relative_path = f"../MASTER/{paper_id}"
1452
- # if not symlink_path.exists():
1453
- # symlink_path.symlink_to(relative_path)
1454
- # logger.info(
1455
- # f"Created project symlink: {readable_name} -> {relative_path}"
1456
- # )
1457
-
1458
- # except Exception as exc_:
1459
- # logger.debug(f"Error creating project symlink: {exc_}")
1460
-
1461
- def _ensure_project_symlink(
1462
- self,
1463
- title: str,
1464
- year: Optional[int] = None,
1465
- authors: Optional[List[str]] = None,
1466
- paper_id: str = None,
1467
- master_storage_path: Path = None,
1468
- ) -> None:
1469
- try:
1470
- if not paper_id or not master_storage_path:
1471
- return
1472
-
1473
- project_lib_path = (
1474
- self.config.path_manager.get_scholar_library_path() / self.project
1475
- )
1476
- project_lib_path.mkdir(parents=True, exist_ok=True)
1477
-
1478
- paper_info = {
1479
- "title": title,
1480
- "year": year,
1481
- "authors": authors or [],
1482
- }
1483
- readable_paths = self._call_path_manager_get_storage_paths(
1484
- paper_info=paper_info, collection_name=self.project
1485
- )
1486
- readable_name = readable_paths["readable_name"]
1487
- symlink_path = project_lib_path / readable_name
1488
- relative_path = f"../MASTER/{paper_id}"
1489
-
1490
- if not symlink_path.exists():
1491
- symlink_path.symlink_to(relative_path)
1492
- logger.info(
1493
- f"Created project symlink: {readable_name} -> {relative_path}"
1494
- )
1495
- except Exception as exc_:
1496
- logger.debug(f"Error creating project symlink: {exc_}")
1497
-
1498
- def _is_title_similar(
1499
- self, title1: str, title2: str, threshold: float = 0.7
1500
- ) -> bool:
1501
- """Check if two titles are similar enough to be considered the same paper."""
1502
- if not title1 or not title2:
1503
- return False
1504
-
1505
- def normalize_title(title: str) -> str:
1506
- title = title.lower()
1507
- title = re.sub(r"[^\w\s]", " ", title)
1508
- title = re.sub(r"\s+", " ", title)
1509
- return title.strip()
1510
-
1511
- norm_title1 = normalize_title(title1)
1512
- norm_title2 = normalize_title(title2)
1513
-
1514
- words1 = set(norm_title1.split())
1515
- words2 = set(norm_title2.split())
1516
-
1517
- if not words1 or not words2:
1518
- return False
1519
-
1520
- intersection = len(words1.intersection(words2))
1521
- union = len(words1.union(words2))
1522
- similarity = intersection / union if union > 0 else 0.0
1523
-
1524
- return similarity >= threshold
1525
-
1526
- def update_library_metadata(
1527
- self,
1528
- paper_id: str,
1529
- project: str,
1530
- doi: str,
1531
- metadata: Dict[str, Any],
1532
- create_structure: bool = True,
1533
- ) -> bool:
1534
- """Update Scholar library metadata.json with resolved DOI."""
1535
- try:
1536
- library_path = self.config.path_manager.library_dir
1537
- paper_dir = library_path / project / paper_id
1538
- metadata_file = paper_dir / "metadata.json"
1539
-
1540
- if create_structure and not paper_dir.exists():
1541
- self.config.path_manager._ensure_directory(paper_dir)
1542
- logger.info(f"Created Scholar library structure: {paper_dir}")
1543
-
1544
- existing_metadata = {}
1545
- if metadata_file.exists():
1546
- try:
1547
- with open(metadata_file, "r") as file_:
1548
- existing_metadata = json.load(file_)
1549
- except Exception as exc_:
1550
- logger.warning(f"Error loading existing metadata: {exc_}")
1551
-
1552
- updated_metadata = {
1553
- **existing_metadata,
1554
- **metadata,
1555
- "doi": doi,
1556
- "doi_resolved_at": datetime.now().isoformat(),
1557
- "doi_source": "batch_doi_resolver",
1558
- }
1559
-
1560
- with open(metadata_file, "w") as file_:
1561
- json.dump(updated_metadata, file_, indent=2)
1562
-
1563
- logger.success(f"Updated metadata for {paper_id}: DOI {doi}")
1564
- return True
1565
-
1566
- except Exception as exc_:
1567
- logger.error(f"Error updating library metadata for {paper_id}: {exc_}")
1568
- return False
1569
-
1570
- def create_writer_directory_structure(self, paper_id: str, project: str) -> Path:
1571
- """Create basic paper directory structure."""
1572
- library_path = self.config.path_manager.library_dir
1573
- paper_dir = library_path / project / paper_id
1574
-
1575
- self.config.path_manager._ensure_directory(paper_dir)
1576
-
1577
- for subdir in ["attachments", "screenshots"]:
1578
- subdir_path = paper_dir / subdir
1579
- self.config.path_manager._ensure_directory(subdir_path)
1580
-
1581
- logger.info(f"Created Scholar library structure: {paper_dir}")
1582
- return paper_dir
1583
-
1584
- def validate_library_structure(self, project: str) -> Dict[str, Any]:
1585
- """Validate existing library structure for a project."""
1586
- validation = {
1587
- "valid": True,
1588
- "warnings": [],
1589
- "errors": [],
1590
- "paper_count": 0,
1591
- "missing_metadata": [],
1592
- }
1593
-
1594
- library_path = self.config.path_manager.library_dir
1595
- project_dir = library_path / project
1596
-
1597
- if not project_dir.exists():
1598
- validation["errors"].append(
1599
- f"Project directory does not exist: {project_dir}"
1600
- )
1601
- validation["valid"] = False
1602
- return validation
1603
-
1604
- for paper_dir in project_dir.iterdir():
1605
- if paper_dir.is_dir() and len(paper_dir.name) == 8:
1606
- validation["paper_count"] += 1
1607
-
1608
- metadata_file = paper_dir / "metadata.json"
1609
- if not metadata_file.exists():
1610
- validation["missing_metadata"].append(paper_dir.name)
1611
- validation["warnings"].append(
1612
- f"Missing metadata.json: {paper_dir.name}"
1613
- )
1614
-
1615
- return validation
1616
-
1617
- def resolve_and_update_library(
1618
- self,
1619
- papers_with_ids: List[Dict[str, Any]],
1620
- project: str,
1621
- sources: Optional[List[str]] = None,
1622
- ) -> Dict[str, str]:
1623
- """Resolve DOIs and update Scholar library metadata.json files."""
1624
- if not self.single_doi_resolver:
1625
- raise ValueError("SingleDOIResolver is required for resolving DOIs")
1626
-
1627
- results = {}
1628
- for paper in papers_with_ids:
1629
- paper_id = paper.get("paper_id")
1630
- if not paper_id:
1631
- logger.warning(
1632
- f"Skipping paper without paper_id: {paper.get('title', 'Unknown')}"
1633
- )
1634
- continue
1635
-
1636
- title = paper.get("title")
1637
- if not title:
1638
- logger.warning(f"Skipping paper {paper_id} without title")
1639
- continue
1640
-
1641
- logger.info(f"Resolving DOI for {paper_id}: {title[:50]}...")
1642
-
1643
- try:
1644
- result = asyncio.run(
1645
- self.single_doi_resolver.metadata2doi_async(
1646
- title=title,
1647
- year=paper.get("year"),
1648
- authors=paper.get("authors"),
1649
- sources=sources,
1650
- )
1651
- )
1652
-
1653
- if result and isinstance(result, dict) and result.get("doi"):
1654
- doi = result["doi"]
1655
-
1656
- success = self.update_library_metadata(
1657
- paper_id=paper_id,
1658
- project=project,
1659
- doi=doi,
1660
- metadata={
1661
- "title": title,
1662
- "title_source": "input",
1663
- "year": paper.get("year"),
1664
- "year_source": ("input" if paper.get("year") else None),
1665
- "authors": paper.get("authors"),
1666
- "authors_source": (
1667
- "input" if paper.get("authors") else None
1668
- ),
1669
- "journal": paper.get("journal"),
1670
- "journal_source": (
1671
- "input" if paper.get("journal") else None
1672
- ),
1673
- "doi_resolution_source": result.get("source"),
1674
- },
1675
- )
1676
-
1677
- if success:
1678
- results[paper_id] = doi
1679
- logger.success(f"✅ {paper_id}: {doi}")
1680
- else:
1681
- logger.error(
1682
- f"❌ {paper_id}: DOI resolved but metadata update failed"
1683
- )
1684
- else:
1685
- logger.warning(f"⚠️ {paper_id}: No DOI found")
1686
-
1687
- except Exception as exc_:
1688
- logger.error(f"❌ {paper_id}: Error during resolution: {exc_}")
1689
-
1690
- logger.success(
1691
- f"Resolved {len(results)}/{len(papers_with_ids)} DOIs and updated library metadata"
1692
- )
1693
- return results
1694
-
1695
- def resolve_and_create_library_structure(
1696
- self,
1697
- papers: List[Dict[str, Any]],
1698
- project: str,
1699
- sources: Optional[List[str]] = None,
1700
- ) -> Dict[str, Dict[str, str]]:
1701
- """Synchronous wrapper for resolve_and_create_library_structure_async."""
1702
- try:
1703
- loop = asyncio.get_event_loop()
1704
- if loop.is_running():
1705
- raise RuntimeError(
1706
- "Cannot run synchronous version in async context. "
1707
- "Use resolve_and_create_library_structure_async() instead."
1708
- )
1709
- else:
1710
- return loop.run_until_complete(
1711
- self.resolve_and_create_library_structure_async(
1712
- papers, project, sources
1713
- )
1714
- )
1715
- except RuntimeError:
1716
- return asyncio.run(
1717
- self.resolve_and_create_library_structure_async(
1718
- papers, project, sources
1719
- )
1720
- )
1721
-
1722
123
 
1723
124
  __all__ = ["LibraryManager"]
1724
125
 
126
+
1725
127
  # EOF