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,7 +1,6 @@
1
1
  #!/usr/bin/env python3
2
- # -*- coding: utf-8 -*-
3
- # Timestamp: "2025-12-12 (ywatanabe)"
4
- # File: scitex/plt/utils/_hitmap.py
2
+ # Timestamp: "2026-01-24 (ywatanabe)"
3
+ # File: /home/ywatanabe/proj/scitex-python/src/scitex/plt/utils/_hitmap.py
5
4
 
6
5
  """
7
6
  Hit map generation utilities for interactive element selection.
@@ -20,1624 +19,55 @@ Based on experimental results (see FIGZ_PLTZ_STATSZ.md):
20
19
  Reserved colors:
21
20
  - Black (#000000, ID=0): Background/no element
22
21
  - Dark gray (#010101, ID=65793): Non-selectable axes elements (spines, labels, ticks)
22
+
23
+ This module re-exports all functions from the _hitmap package for backward
24
+ compatibility. The actual implementation is in the _hitmap/ subpackage.
23
25
  """
24
26
 
25
- import warnings
26
- from typing import Dict, List, Any, Optional, Tuple
27
- import numpy as np
27
+ # Re-export all public API from the _hitmap package
28
+ from ._hitmap import (
29
+ HITMAP_AXES_COLOR,
30
+ HITMAP_BACKGROUND_COLOR,
31
+ _apply_id_color,
32
+ _id_to_rgb,
33
+ _prepare_hitmap_figure,
34
+ _restore_figure_props,
35
+ _rgb_to_id_lookup,
36
+ _to_native,
37
+ apply_hitmap_colors,
38
+ detect_logical_groups,
39
+ extract_path_data,
40
+ extract_selectable_regions,
41
+ generate_hitmap_id_colors,
42
+ generate_hitmap_with_bbox_tight,
43
+ get_all_artists,
44
+ get_all_artists_with_groups,
45
+ query_hitmap_neighborhood,
46
+ restore_original_colors,
47
+ save_hitmap_png,
48
+ )
28
49
 
29
50
  __all__ = [
30
- 'get_all_artists',
31
- 'get_all_artists_with_groups',
32
- 'detect_logical_groups',
33
- 'generate_hitmap_id_colors',
34
- 'extract_path_data',
35
- 'extract_selectable_regions',
36
- 'query_hitmap_neighborhood',
37
- 'save_hitmap_png',
38
- 'apply_hitmap_colors',
39
- 'restore_original_colors',
40
- 'generate_hitmap_with_bbox_tight',
41
- 'HITMAP_BACKGROUND_COLOR',
42
- 'HITMAP_AXES_COLOR',
43
- '_rgb_to_id_lookup',
51
+ "get_all_artists",
52
+ "get_all_artists_with_groups",
53
+ "detect_logical_groups",
54
+ "generate_hitmap_id_colors",
55
+ "extract_path_data",
56
+ "extract_selectable_regions",
57
+ "query_hitmap_neighborhood",
58
+ "save_hitmap_png",
59
+ "apply_hitmap_colors",
60
+ "restore_original_colors",
61
+ "generate_hitmap_with_bbox_tight",
62
+ "HITMAP_BACKGROUND_COLOR",
63
+ "HITMAP_AXES_COLOR",
64
+ "_rgb_to_id_lookup",
65
+ "_to_native",
66
+ "_id_to_rgb",
67
+ "_apply_id_color",
68
+ "_prepare_hitmap_figure",
69
+ "_restore_figure_props",
44
70
  ]
45
71
 
46
72
 
47
- def _to_native(obj: Any) -> Any:
48
- """Convert numpy types to native Python types for JSON serialization."""
49
- if isinstance(obj, np.integer):
50
- return int(obj)
51
- elif isinstance(obj, np.floating):
52
- return float(obj)
53
- elif isinstance(obj, np.ndarray):
54
- return obj.tolist()
55
- elif isinstance(obj, dict):
56
- return {k: _to_native(v) for k, v in obj.items()}
57
- elif isinstance(obj, list):
58
- return [_to_native(v) for v in obj]
59
- return obj
60
-
61
-
62
- def get_all_artists(fig, include_text: bool = False) -> List[Tuple[Any, int, str]]:
63
- """
64
- Extract all selectable artists from a figure.
65
-
66
- Parameters
67
- ----------
68
- fig : matplotlib.figure.Figure
69
- The figure to extract artists from.
70
- include_text : bool
71
- Whether to include text elements.
72
-
73
- Returns
74
- -------
75
- list of tuple
76
- List of (artist, axes_index, artist_type) tuples.
77
- """
78
- artists = []
79
-
80
- for ax_idx, ax in enumerate(fig.axes):
81
- # Lines (Line2D)
82
- for line in ax.get_lines():
83
- label = line.get_label()
84
- if not label.startswith('_'): # Skip internal lines
85
- artists.append((line, ax_idx, 'line'))
86
-
87
- # Scatter plots (PathCollection)
88
- for coll in ax.collections:
89
- coll_type = type(coll).__name__
90
- if 'PathCollection' in coll_type:
91
- artists.append((coll, ax_idx, 'scatter'))
92
- elif 'PolyCollection' in coll_type or 'FillBetween' in coll_type:
93
- artists.append((coll, ax_idx, 'fill'))
94
- elif 'QuadMesh' in coll_type:
95
- artists.append((coll, ax_idx, 'mesh'))
96
-
97
- # Bars (Rectangle patches in containers)
98
- for container in ax.containers:
99
- if hasattr(container, 'patches') and container.patches:
100
- artists.append((container, ax_idx, 'bar'))
101
-
102
- # Individual patches (rectangles, circles, etc.)
103
- for patch in ax.patches:
104
- patch_type = type(patch).__name__
105
- if patch_type == 'Rectangle':
106
- artists.append((patch, ax_idx, 'rectangle'))
107
- elif patch_type in ('Circle', 'Ellipse'):
108
- artists.append((patch, ax_idx, 'circle'))
109
- elif patch_type == 'Polygon':
110
- artists.append((patch, ax_idx, 'polygon'))
111
-
112
- # Images
113
- for img in ax.images:
114
- artists.append((img, ax_idx, 'image'))
115
-
116
- # Text (optional)
117
- if include_text:
118
- for text in ax.texts:
119
- if text.get_text():
120
- artists.append((text, ax_idx, 'text'))
121
-
122
- return artists
123
-
124
-
125
- def detect_logical_groups(fig) -> Dict[str, Dict[str, Any]]:
126
- """
127
- Detect logical groups in a matplotlib figure.
128
-
129
- Logical groups represent high-level plot elements that may consist of
130
- multiple physical matplotlib artists. For example:
131
- - Histogram: Many Rectangle patches grouped as one "histogram"
132
- - Bar series: BarContainer with multiple bars
133
- - Box plot: Box, whiskers, caps, median, fliers as one "boxplot"
134
- - Error bars: Line + error caps as one "errorbar"
135
-
136
- Parameters
137
- ----------
138
- fig : matplotlib.figure.Figure
139
- The figure to analyze.
140
-
141
- Returns
142
- -------
143
- dict
144
- Dictionary mapping group_id to group info:
145
- {
146
- "histogram_0": {
147
- "type": "histogram",
148
- "label": "...",
149
- "axes_index": 0,
150
- "artists": [list of matplotlib artists],
151
- "role": "logical"
152
- },
153
- ...
154
- }
155
- """
156
- groups = {}
157
- group_counter = {} # Track count per type for unique IDs
158
-
159
- def get_group_id(group_type: str, ax_idx: int) -> str:
160
- """Generate unique group ID."""
161
- key = f"{group_type}_{ax_idx}"
162
- if key not in group_counter:
163
- group_counter[key] = 0
164
- idx = group_counter[key]
165
- group_counter[key] += 1
166
- return f"{group_type}_{ax_idx}_{idx}"
167
-
168
- for ax_idx, ax in enumerate(fig.axes):
169
- # 1. Detect BarContainers (covers bar charts and histograms)
170
- # First, count how many BarContainers exist on this axis
171
- bar_containers = [c for c in ax.containers if 'BarContainer' in type(c).__name__]
172
- n_bar_containers = len(bar_containers)
173
-
174
- for container in ax.containers:
175
- container_type = type(container).__name__
176
-
177
- if 'BarContainer' in container_type:
178
- # Determine if it's a histogram, grouped bar series, or simple categorical bar
179
- patches = list(container.patches) if hasattr(container, 'patches') else []
180
- if not patches:
181
- continue
182
-
183
- # Check if bars are adjacent (histogram) or spaced (bar chart)
184
- is_histogram = False
185
- if len(patches) > 1:
186
- # Check if bars are adjacent (no gaps between them)
187
- widths = [p.get_width() for p in patches]
188
- x_positions = [p.get_x() for p in patches]
189
- if len(x_positions) > 1:
190
- gaps = [x_positions[i+1] - (x_positions[i] + widths[i])
191
- for i in range(len(x_positions)-1)]
192
- # If gaps are very small relative to bar width, it's a histogram
193
- avg_width = sum(widths) / len(widths)
194
- is_histogram = all(abs(g) < avg_width * 0.1 for g in gaps)
195
-
196
- if is_histogram:
197
- # Histogram: group all bins together
198
- group_type = 'histogram'
199
- group_id = get_group_id(group_type, ax_idx)
200
-
201
- label = ''
202
- if hasattr(container, 'get_label'):
203
- label = container.get_label()
204
- if not label or label.startswith('_'):
205
- label = f"{group_type}_{len([g for g in groups if group_type in g])}"
206
-
207
- groups[group_id] = {
208
- 'type': group_type,
209
- 'label': label,
210
- 'axes_index': ax_idx,
211
- 'artists': patches,
212
- 'artist_types': ['rectangle'] * len(patches),
213
- 'role': 'logical',
214
- 'member_count': len(patches),
215
- }
216
-
217
- elif n_bar_containers > 1:
218
- # Multiple bar containers = grouped bar chart
219
- # Group bars by series (each container is a series)
220
- group_type = 'bar_series'
221
- group_id = get_group_id(group_type, ax_idx)
222
-
223
- label = ''
224
- if hasattr(container, 'get_label'):
225
- label = container.get_label()
226
- if not label or label.startswith('_'):
227
- label = f"{group_type}_{len([g for g in groups if group_type in g])}"
228
-
229
- groups[group_id] = {
230
- 'type': group_type,
231
- 'label': label,
232
- 'axes_index': ax_idx,
233
- 'artists': patches,
234
- 'artist_types': ['rectangle'] * len(patches),
235
- 'role': 'logical',
236
- 'member_count': len(patches),
237
- }
238
-
239
- # else: Single bar container with spaced bars = simple categorical bar chart
240
- # Don't create a group - each bar is standalone and selectable individually
241
-
242
- elif 'ErrorbarContainer' in container_type:
243
- # Error bar container
244
- group_id = get_group_id('errorbar', ax_idx)
245
- artists = []
246
- artist_types = []
247
-
248
- if hasattr(container, 'lines'):
249
- data_line, caplines, barlinecols = container.lines
250
- if data_line:
251
- artists.append(data_line)
252
- artist_types.append('line')
253
- artists.extend(caplines)
254
- artist_types.extend(['line'] * len(caplines))
255
- artists.extend(barlinecols)
256
- artist_types.extend(['line_collection'] * len(barlinecols))
257
-
258
- label = container.get_label() if hasattr(container, 'get_label') else ''
259
- if not label or label.startswith('_'):
260
- label = f"errorbar_{len([g for g in groups if 'errorbar' in g])}"
261
-
262
- groups[group_id] = {
263
- 'type': 'errorbar',
264
- 'label': label,
265
- 'axes_index': ax_idx,
266
- 'artists': artists,
267
- 'artist_types': artist_types,
268
- 'role': 'logical',
269
- 'member_count': len(artists),
270
- }
271
-
272
- # 2. Detect box plots (look for specific pattern of artists)
273
- # Box plots create: boxes (Rectangle), whiskers (Line2D), caps (Line2D),
274
- # medians (Line2D), fliers (Line2D)
275
- # They are typically created via ax.bxp() or ax.boxplot()
276
- if hasattr(ax, '_boxplot_info'):
277
- # Some matplotlib versions store boxplot info
278
- pass # Handle if available
279
-
280
- # 3. Detect pie charts (Wedge patches)
281
- wedges = [p for p in ax.patches if type(p).__name__ == 'Wedge']
282
- if wedges:
283
- group_id = get_group_id('pie', ax_idx)
284
- groups[group_id] = {
285
- 'type': 'pie',
286
- 'label': 'Pie Chart',
287
- 'axes_index': ax_idx,
288
- 'artists': wedges,
289
- 'artist_types': ['wedge'] * len(wedges),
290
- 'role': 'logical',
291
- 'member_count': len(wedges),
292
- }
293
-
294
- # 4. Detect contour sets (multiple PolyCollections from same contour call)
295
- # Contours typically have collections with increasing/decreasing levels
296
- poly_collections = [c for c in ax.collections
297
- if 'PolyCollection' in type(c).__name__
298
- and hasattr(c, 'get_array')
299
- and c.get_array() is not None]
300
- if len(poly_collections) > 2:
301
- # Likely a contour plot
302
- group_id = get_group_id('contour', ax_idx)
303
- groups[group_id] = {
304
- 'type': 'contour',
305
- 'label': 'Contour Plot',
306
- 'axes_index': ax_idx,
307
- 'artists': poly_collections,
308
- 'artist_types': ['poly_collection'] * len(poly_collections),
309
- 'role': 'logical',
310
- 'member_count': len(poly_collections),
311
- }
312
-
313
- return groups
314
-
315
-
316
- def get_all_artists_with_groups(
317
- fig,
318
- include_text: bool = False
319
- ) -> Tuple[List[Tuple[Any, int, str, Optional[str]]], Dict[str, Dict[str, Any]]]:
320
- """
321
- Extract all selectable artists from a figure with logical group information.
322
-
323
- This is an enhanced version of get_all_artists() that also detects and
324
- returns logical groups (e.g., histogram bins grouped as one element).
325
-
326
- Parameters
327
- ----------
328
- fig : matplotlib.figure.Figure
329
- The figure to extract artists from.
330
- include_text : bool
331
- Whether to include text elements.
332
-
333
- Returns
334
- -------
335
- tuple
336
- (artists_list, groups_dict) where:
337
- - artists_list: List of (artist, axes_index, artist_type, group_id) tuples
338
- - groups_dict: Dictionary of logical groups
339
-
340
- Examples
341
- --------
342
- >>> artists, groups = get_all_artists_with_groups(fig)
343
- >>> for artist, ax_idx, atype, group_id in artists:
344
- ... if group_id:
345
- ... print(f"{atype} belongs to group {group_id}")
346
- """
347
- # First, detect logical groups
348
- groups = detect_logical_groups(fig)
349
-
350
- # Create a mapping from artist to group_id
351
- artist_to_group = {}
352
- for group_id, group_info in groups.items():
353
- for artist in group_info['artists']:
354
- artist_to_group[id(artist)] = group_id
355
-
356
- # Now get all artists with group information
357
- artists_with_groups = []
358
-
359
- for ax_idx, ax in enumerate(fig.axes):
360
- # Lines (Line2D)
361
- for line in ax.get_lines():
362
- label = line.get_label()
363
- if not label.startswith('_'): # Skip internal lines
364
- group_id = artist_to_group.get(id(line))
365
- artists_with_groups.append((line, ax_idx, 'line', group_id))
366
-
367
- # Scatter plots (PathCollection)
368
- for coll in ax.collections:
369
- coll_type = type(coll).__name__
370
- group_id = artist_to_group.get(id(coll))
371
- if 'PathCollection' in coll_type:
372
- artists_with_groups.append((coll, ax_idx, 'scatter', group_id))
373
- elif 'PolyCollection' in coll_type or 'FillBetween' in coll_type:
374
- artists_with_groups.append((coll, ax_idx, 'fill', group_id))
375
- elif 'QuadMesh' in coll_type:
376
- artists_with_groups.append((coll, ax_idx, 'mesh', group_id))
377
-
378
- # Bars - handle both container level and individual patches
379
- processed_patches = set()
380
- for container in ax.containers:
381
- if hasattr(container, 'patches') and container.patches:
382
- # Check if first patch belongs to a group
383
- group_id = artist_to_group.get(id(container.patches[0]))
384
-
385
- if group_id:
386
- # Grouped bars (histogram or bar_series): add container as single element
387
- artists_with_groups.append((container, ax_idx, 'bar', group_id))
388
- # Mark patches as processed
389
- for patch in container.patches:
390
- processed_patches.add(id(patch))
391
- else:
392
- # Simple categorical bar: add each patch individually (standalone)
393
- for patch in container.patches:
394
- artists_with_groups.append((patch, ax_idx, 'rectangle', None))
395
- processed_patches.add(id(patch))
396
-
397
- # Individual patches (rectangles, circles, etc.) not in containers
398
- for patch in ax.patches:
399
- if id(patch) in processed_patches:
400
- continue
401
- patch_type = type(patch).__name__
402
- group_id = artist_to_group.get(id(patch))
403
- if patch_type == 'Rectangle':
404
- artists_with_groups.append((patch, ax_idx, 'rectangle', group_id))
405
- elif patch_type in ('Circle', 'Ellipse'):
406
- artists_with_groups.append((patch, ax_idx, 'circle', group_id))
407
- elif patch_type == 'Polygon':
408
- artists_with_groups.append((patch, ax_idx, 'polygon', group_id))
409
- elif patch_type == 'Wedge':
410
- artists_with_groups.append((patch, ax_idx, 'wedge', group_id))
411
-
412
- # Images
413
- for img in ax.images:
414
- group_id = artist_to_group.get(id(img))
415
- artists_with_groups.append((img, ax_idx, 'image', group_id))
416
-
417
- # Text (optional)
418
- if include_text:
419
- for text in ax.texts:
420
- if text.get_text():
421
- group_id = artist_to_group.get(id(text))
422
- artists_with_groups.append((text, ax_idx, 'text', group_id))
423
-
424
- return artists_with_groups, groups
425
-
426
-
427
- def _id_to_rgb(element_id: int) -> Tuple[int, int, int]:
428
- """
429
- Convert element ID to unique, human-readable RGB color using hash-based generation.
430
-
431
- Uses a hash function to generate visually distinct colors that are:
432
- 1. Deterministic (same ID always gives same color)
433
- 2. Visually distinct (spread across the color space)
434
- 3. Bright and saturated (easy to see)
435
-
436
- The first 12 elements use a hand-picked palette for maximum distinctness.
437
- Beyond that, uses hash-based HSV generation with high saturation.
438
-
439
- Parameters
440
- ----------
441
- element_id : int
442
- Element ID (1-based). ID 0 is reserved for background.
443
-
444
- Returns
445
- -------
446
- tuple
447
- (R, G, B) values (0-255)
448
-
449
- Notes
450
- -----
451
- The hash ensures:
452
- - Same element_id always maps to the same color
453
- - Colors are well-distributed across the spectrum
454
- - Avoids dark colors (reserved for background/axes)
455
- """
456
- import colorsys
457
- import hashlib
458
-
459
- if element_id <= 0:
460
- return (0, 0, 0) # Background
461
-
462
- # Hand-picked palette for first 12 elements (most common case)
463
- # These are maximally distinct primary/secondary colors
464
- DISTINCT_COLORS = [
465
- (255, 0, 0), # 1: Red
466
- (0, 200, 0), # 2: Green (slightly darker for visibility)
467
- (0, 100, 255), # 3: Blue (lighter for visibility)
468
- (255, 200, 0), # 4: Yellow/Gold
469
- (255, 0, 200), # 5: Magenta/Pink
470
- (0, 220, 220), # 6: Cyan
471
- (255, 100, 0), # 7: Orange
472
- (150, 0, 255), # 8: Purple
473
- (0, 255, 100), # 9: Spring Green
474
- (255, 100, 150), # 10: Salmon/Rose
475
- (100, 255, 0), # 11: Lime
476
- (100, 150, 255), # 12: Sky Blue
477
- ]
478
-
479
- if element_id <= len(DISTINCT_COLORS):
480
- return DISTINCT_COLORS[element_id - 1]
481
-
482
- # For IDs > 12, use hash-based color generation
483
- # Hash the ID to get a pseudo-random but deterministic value
484
- hash_bytes = hashlib.md5(str(element_id).encode()).digest()
485
-
486
- # Use hash bytes to generate HSV values
487
- # Hue: full range (0-1) for variety
488
- hue = int.from_bytes(hash_bytes[0:2], 'big') / 65535.0
489
-
490
- # Saturation: high (0.7-1.0) for vivid colors
491
- saturation = 0.7 + (int.from_bytes(hash_bytes[2:3], 'big') / 255.0) * 0.3
492
-
493
- # Value: high (0.75-1.0) to avoid dark colors
494
- value = 0.75 + (int.from_bytes(hash_bytes[3:4], 'big') / 255.0) * 0.25
495
-
496
- r, g, b = colorsys.hsv_to_rgb(hue, saturation, value)
497
- return (int(r * 255), int(g * 255), int(b * 255))
498
-
499
-
500
- def _rgb_to_id_lookup(r: int, g: int, b: int, color_map: dict) -> int:
501
- """
502
- Convert RGB color back to element ID using the color map.
503
-
504
- Since we use human-readable colors, we need to look up in the map.
505
-
506
- Parameters
507
- ----------
508
- r, g, b : int
509
- RGB values (0-255)
510
- color_map : dict
511
- Color map from generate_hitmap_id_colors (maps ID -> info with 'rgb' key)
512
-
513
- Returns
514
- -------
515
- int
516
- Element ID, or 0 if not found
517
- """
518
- rgb = [r, g, b]
519
- for element_id, info in color_map.items():
520
- if info.get('rgb') == rgb:
521
- return element_id
522
- return 0
523
-
524
-
525
- # Reserved colors for hitmap (human-readable)
526
- HITMAP_BACKGROUND_COLOR = '#1a1a1a' # Dark gray (not pure black, easier to see)
527
- HITMAP_AXES_COLOR = '#404040' # Medium gray (non-selectable axes elements)
528
-
529
-
530
- def _rgb_to_id(r: int, g: int, b: int) -> int:
531
- """Convert RGB color back to element ID."""
532
- return (r << 16) | (g << 8) | b
533
-
534
-
535
- def generate_hitmap_id_colors(
536
- fig,
537
- dpi: int = 100,
538
- include_text: bool = False,
539
- ) -> Tuple[np.ndarray, Dict[int, Dict[str, Any]]]:
540
- """
541
- Generate a hit map using unique ID colors (fastest method).
542
-
543
- Assigns unique RGB colors to each element, renders once, and creates
544
- a pixel-perfect hit map where each pixel's RGB values encode the
545
- element ID using 24-bit color space (~16.7M unique IDs).
546
-
547
- Parameters
548
- ----------
549
- fig : matplotlib.figure.Figure
550
- The figure to generate hit map for.
551
- dpi : int
552
- Resolution for hit map rendering.
553
- include_text : bool
554
- Whether to include text elements in hit map.
555
-
556
- Returns
557
- -------
558
- tuple
559
- (hitmap_array, color_map) where:
560
- - hitmap_array: uint32 array with element IDs (0 = background)
561
- - color_map: dict mapping ID to element info
562
-
563
- Notes
564
- -----
565
- Performance: ~89ms for complex figures (33x faster than sequential)
566
- Uses RGB 24-bit encoding for up to ~16.7 million unique element IDs.
567
- """
568
- import matplotlib.pyplot as plt
569
- import copy
570
-
571
- # Get all artists
572
- artists = get_all_artists(fig, include_text)
573
-
574
- if not artists:
575
- h = int(fig.get_figheight() * dpi)
576
- w = int(fig.get_figwidth() * dpi)
577
- return np.zeros((h, w), dtype=np.uint32), {}
578
-
579
- # Store original properties for restoration
580
- original_props = []
581
-
582
- # Build color map
583
- color_map = {}
584
-
585
- for i, (artist, ax_idx, artist_type) in enumerate(artists):
586
- element_id = i + 1
587
- # Use full RGB 24-bit encoding for unique ID colors
588
- r, g, b = _id_to_rgb(element_id)
589
- hex_color = f"#{r:02x}{g:02x}{b:02x}"
590
-
591
- # Store original properties
592
- props = {'artist': artist, 'type': artist_type}
593
- try:
594
- if hasattr(artist, 'get_color'):
595
- props['color'] = artist.get_color()
596
- if hasattr(artist, 'get_facecolor'):
597
- props['facecolor'] = artist.get_facecolor()
598
- if hasattr(artist, 'get_edgecolor'):
599
- props['edgecolor'] = artist.get_edgecolor()
600
- if hasattr(artist, 'get_alpha'):
601
- props['alpha'] = artist.get_alpha()
602
- if hasattr(artist, 'get_antialiased'):
603
- props['antialiased'] = artist.get_antialiased()
604
- except Exception:
605
- pass
606
- original_props.append(props)
607
-
608
- # Build color map entry (use element_id as key)
609
- label = ''
610
- if hasattr(artist, 'get_label'):
611
- label = artist.get_label()
612
- if label.startswith('_'):
613
- label = f'{artist_type}_{i}'
614
-
615
- color_map[element_id] = {
616
- 'id': element_id,
617
- 'type': artist_type,
618
- 'label': label,
619
- 'axes_index': ax_idx,
620
- 'rgb': [r, g, b],
621
- }
622
-
623
- # Apply ID color and disable anti-aliasing
624
- try:
625
- _apply_id_color(artist, hex_color)
626
- except Exception:
627
- pass
628
-
629
- # Make non-artist elements the reserved axes color (NOT black)
630
- # This distinguishes axes from background while making them non-selectable
631
- axes_color = HITMAP_AXES_COLOR
632
- for ax in fig.axes:
633
- ax.grid(False)
634
- for spine in ax.spines.values():
635
- spine.set_color(axes_color)
636
- ax.set_facecolor(HITMAP_BACKGROUND_COLOR)
637
- ax.tick_params(colors=axes_color, labelcolor=axes_color)
638
- ax.xaxis.label.set_color(axes_color)
639
- ax.yaxis.label.set_color(axes_color)
640
- ax.title.set_color(axes_color)
641
- if ax.get_legend():
642
- ax.get_legend().set_visible(False)
643
-
644
- fig.patch.set_facecolor(HITMAP_BACKGROUND_COLOR)
645
-
646
- # Render
647
- fig.canvas.draw()
648
- img = np.array(fig.canvas.buffer_rgba())
649
- # Convert RGB to element ID using 24-bit encoding
650
- hitmap = (img[:, :, 0].astype(np.uint32) << 16) | \
651
- (img[:, :, 1].astype(np.uint32) << 8) | \
652
- img[:, :, 2].astype(np.uint32)
653
-
654
- # Restore original properties
655
- for props in original_props:
656
- artist = props['artist']
657
- try:
658
- if 'color' in props and hasattr(artist, 'set_color'):
659
- artist.set_color(props['color'])
660
- if 'facecolor' in props and hasattr(artist, 'set_facecolor'):
661
- artist.set_facecolor(props['facecolor'])
662
- if 'edgecolor' in props and hasattr(artist, 'set_edgecolor'):
663
- artist.set_edgecolor(props['edgecolor'])
664
- if 'alpha' in props and hasattr(artist, 'set_alpha'):
665
- artist.set_alpha(props['alpha'])
666
- if 'antialiased' in props and hasattr(artist, 'set_antialiased'):
667
- artist.set_antialiased(props['antialiased'])
668
- except Exception:
669
- pass
670
-
671
- return hitmap, color_map
672
-
673
-
674
- def _apply_id_color(artist, hex_color: str):
675
- """Apply ID color to an artist, handling different artist types."""
676
- artist_type = type(artist).__name__
677
-
678
- if hasattr(artist, 'set_color'):
679
- artist.set_color(hex_color)
680
- if hasattr(artist, 'set_antialiased'):
681
- artist.set_antialiased(False)
682
-
683
- elif hasattr(artist, 'set_facecolor'):
684
- artist.set_facecolor(hex_color)
685
- if hasattr(artist, 'set_edgecolor'):
686
- artist.set_edgecolor(hex_color)
687
- if hasattr(artist, 'set_alpha'):
688
- artist.set_alpha(1.0)
689
- if hasattr(artist, 'set_antialiased'):
690
- artist.set_antialiased(False)
691
-
692
- # Handle BarContainer
693
- if hasattr(artist, 'patches'):
694
- for patch in artist.patches:
695
- patch.set_facecolor(hex_color)
696
- patch.set_edgecolor(hex_color)
697
- if hasattr(patch, 'set_antialiased'):
698
- patch.set_antialiased(False)
699
-
700
-
701
- def _prepare_hitmap_figure(
702
- fig,
703
- include_text: bool = False,
704
- ) -> Tuple[Dict[int, Dict[str, Any]], List[Dict[str, Any]]]:
705
- """
706
- Prepare a figure for hitmap rendering by coloring elements with unique IDs.
707
-
708
- This function modifies the figure in-place by:
709
- 1. Assigning unique RGB colors to each artist (24-bit ID encoding)
710
- 2. Hiding non-selectable elements (axes, spines, grid, etc.)
711
- 3. Setting background to black (ID = 0)
712
-
713
- Parameters
714
- ----------
715
- fig : matplotlib.figure.Figure
716
- The figure to prepare for hitmap rendering.
717
- include_text : bool
718
- Whether to include text elements.
719
-
720
- Returns
721
- -------
722
- tuple
723
- (color_map, original_props) where:
724
- - color_map: dict mapping ID to element info
725
- - original_props: list of dicts with original artist properties (for restoration)
726
-
727
- Notes
728
- -----
729
- After calling this function, you can render the figure using savefig()
730
- with bbox_inches='tight' to get a pixel-perfect hitmap.
731
- Call _restore_figure_props(original_props) to restore the figure.
732
- """
733
- artists = get_all_artists(fig, include_text)
734
-
735
- if not artists:
736
- return {}, []
737
-
738
- # Store original properties for restoration
739
- original_props = []
740
-
741
- # Build color map
742
- color_map = {}
743
-
744
- for i, (artist, ax_idx, artist_type) in enumerate(artists):
745
- element_id = i + 1
746
- # Use full RGB 24-bit encoding for unique ID colors
747
- r, g, b = _id_to_rgb(element_id)
748
- hex_color = f"#{r:02x}{g:02x}{b:02x}"
749
-
750
- # Store original properties
751
- props = {'artist': artist, 'type': artist_type}
752
- try:
753
- if hasattr(artist, 'get_color'):
754
- props['color'] = artist.get_color()
755
- if hasattr(artist, 'get_facecolor'):
756
- props['facecolor'] = artist.get_facecolor()
757
- if hasattr(artist, 'get_edgecolor'):
758
- props['edgecolor'] = artist.get_edgecolor()
759
- if hasattr(artist, 'get_alpha'):
760
- props['alpha'] = artist.get_alpha()
761
- if hasattr(artist, 'get_antialiased'):
762
- props['antialiased'] = artist.get_antialiased()
763
- except Exception:
764
- pass
765
- original_props.append(props)
766
-
767
- # Build color map entry
768
- label = ''
769
- if hasattr(artist, 'get_label'):
770
- label = artist.get_label()
771
- if label.startswith('_'):
772
- label = f'{artist_type}_{i}'
773
-
774
- color_map[element_id] = {
775
- 'id': element_id,
776
- 'type': artist_type,
777
- 'label': label,
778
- 'axes_index': ax_idx,
779
- 'rgb': [r, g, b],
780
- }
781
-
782
- # Apply ID color and disable anti-aliasing
783
- try:
784
- _apply_id_color(artist, hex_color)
785
- except Exception:
786
- pass
787
-
788
- # Hide non-artist elements (we need to save these for restoration too)
789
- axes_props = []
790
- for ax in fig.axes:
791
- ax_props = {
792
- 'ax': ax,
793
- 'grid_visible': ax.xaxis.get_gridlines()[0].get_visible() if ax.xaxis.get_gridlines() else False,
794
- 'facecolor': ax.get_facecolor(),
795
- 'spines_visible': {k: v.get_visible() for k, v in ax.spines.items()},
796
- 'xlabel': ax.get_xlabel(),
797
- 'ylabel': ax.get_ylabel(),
798
- 'title': ax.get_title(),
799
- 'legend_visible': ax.get_legend().get_visible() if ax.get_legend() else None,
800
- 'tick_params': {}, # Complex to save/restore, skip for now
801
- }
802
- axes_props.append(ax_props)
803
-
804
- ax.grid(False)
805
- for spine in ax.spines.values():
806
- spine.set_color(HITMAP_AXES_COLOR)
807
- ax.set_facecolor(HITMAP_BACKGROUND_COLOR)
808
- ax.tick_params(colors=HITMAP_AXES_COLOR, labelcolor=HITMAP_AXES_COLOR)
809
- ax.xaxis.label.set_color(HITMAP_AXES_COLOR)
810
- ax.yaxis.label.set_color(HITMAP_AXES_COLOR)
811
- ax.title.set_color(HITMAP_AXES_COLOR)
812
- if ax.get_legend():
813
- ax.get_legend().set_visible(False)
814
-
815
- # Save figure background
816
- original_props.append({
817
- 'type': '_figure_patch',
818
- 'facecolor': fig.patch.get_facecolor(),
819
- 'axes_props': axes_props,
820
- })
821
- fig.patch.set_facecolor(HITMAP_BACKGROUND_COLOR)
822
-
823
- return color_map, original_props
824
-
825
-
826
- def _restore_figure_props(original_props: List[Dict[str, Any]]):
827
- """
828
- Restore figure properties after hitmap rendering.
829
-
830
- Parameters
831
- ----------
832
- original_props : list
833
- List of property dicts from _prepare_hitmap_figure().
834
- """
835
- for props in original_props:
836
- if props.get('type') == '_figure_patch':
837
- # Restore axes and figure background
838
- if 'axes_props' in props:
839
- for ax_props in props['axes_props']:
840
- ax = ax_props['ax']
841
- ax.set_facecolor(ax_props['facecolor'])
842
- for spine_name, visible in ax_props['spines_visible'].items():
843
- ax.spines[spine_name].set_visible(visible)
844
- ax.set_xlabel(ax_props['xlabel'])
845
- ax.set_ylabel(ax_props['ylabel'])
846
- ax.set_title(ax_props['title'])
847
- if ax_props['legend_visible'] is not None and ax.get_legend():
848
- ax.get_legend().set_visible(ax_props['legend_visible'])
849
- continue
850
-
851
- artist = props.get('artist')
852
- if not artist:
853
- continue
854
-
855
- try:
856
- if 'color' in props and hasattr(artist, 'set_color'):
857
- artist.set_color(props['color'])
858
- if 'facecolor' in props and hasattr(artist, 'set_facecolor'):
859
- artist.set_facecolor(props['facecolor'])
860
- if 'edgecolor' in props and hasattr(artist, 'set_edgecolor'):
861
- artist.set_edgecolor(props['edgecolor'])
862
- if 'alpha' in props and hasattr(artist, 'set_alpha'):
863
- artist.set_alpha(props['alpha'])
864
- if 'antialiased' in props and hasattr(artist, 'set_antialiased'):
865
- artist.set_antialiased(props['antialiased'])
866
- except Exception:
867
- pass
868
-
869
-
870
- def extract_path_data(
871
- fig,
872
- include_text: bool = False,
873
- ) -> Dict[str, Any]:
874
- """
875
- Extract path/geometry data for client-side hit testing.
876
-
877
- Extracts bounding boxes and path coordinates for all selectable elements,
878
- enabling JavaScript-based hit testing in web editors.
879
-
880
- Parameters
881
- ----------
882
- fig : matplotlib.figure.Figure
883
- The figure to extract data from.
884
- include_text : bool
885
- Whether to include text elements.
886
-
887
- Returns
888
- -------
889
- dict
890
- Exported data structure with figure info and artist geometries.
891
-
892
- Notes
893
- -----
894
- Performance: ~192ms extraction, ~0.01ms client-side queries
895
- Supports: resize/zoom (transform coordinates client-side)
896
- """
897
- with warnings.catch_warnings():
898
- warnings.filterwarnings("ignore", message=".*tight_layout.*")
899
- fig.canvas.draw() # Ensure transforms are computed
900
-
901
- artists = get_all_artists(fig, include_text)
902
-
903
- dpi = fig.dpi
904
- fig_width_px = int(fig.get_figwidth() * dpi)
905
- fig_height_px = int(fig.get_figheight() * dpi)
906
-
907
- export = {
908
- 'figure': {
909
- 'width_px': fig_width_px,
910
- 'height_px': fig_height_px,
911
- 'dpi': dpi,
912
- },
913
- 'axes': [],
914
- 'artists': [],
915
- }
916
-
917
- # Export axes info
918
- for ax in fig.axes:
919
- bbox = ax.get_position()
920
- export['axes'].append({
921
- 'xlim': list(ax.get_xlim()),
922
- 'ylim': list(ax.get_ylim()),
923
- 'bbox_norm': {
924
- 'x0': bbox.x0,
925
- 'y0': bbox.y0,
926
- 'x1': bbox.x1,
927
- 'y1': bbox.y1,
928
- },
929
- 'bbox_px': {
930
- 'x0': int(bbox.x0 * fig_width_px),
931
- 'y0': int((1 - bbox.y1) * fig_height_px),
932
- 'x1': int(bbox.x1 * fig_width_px),
933
- 'y1': int((1 - bbox.y0) * fig_height_px),
934
- },
935
- })
936
-
937
- # Export artist geometries
938
- renderer = fig.canvas.get_renderer()
939
-
940
- for i, (artist, ax_idx, artist_type) in enumerate(artists):
941
- artist_data = {
942
- 'id': i,
943
- 'type': artist_type,
944
- 'axes_index': ax_idx,
945
- 'label': '',
946
- }
947
-
948
- # Get label
949
- if hasattr(artist, 'get_label'):
950
- label = artist.get_label()
951
- artist_data['label'] = label if not label.startswith('_') else f'{artist_type}_{i}'
952
-
953
- # Get bounding box
954
- try:
955
- bbox = artist.get_window_extent(renderer)
956
- artist_data['bbox_px'] = {
957
- 'x0': float(bbox.x0),
958
- 'y0': float(fig_height_px - bbox.y1), # Flip Y
959
- 'x1': float(bbox.x1),
960
- 'y1': float(fig_height_px - bbox.y0),
961
- }
962
- except Exception:
963
- artist_data['bbox_px'] = None
964
-
965
- # Extract type-specific geometry
966
- try:
967
- if artist_type == 'line' and hasattr(artist, 'get_xydata'):
968
- xy = artist.get_xydata()
969
- transform = artist.get_transform()
970
- xy_px = transform.transform(xy)
971
- # Flip Y and limit points for JSON size
972
- xy_px[:, 1] = fig_height_px - xy_px[:, 1]
973
- # Sample if too many points
974
- if len(xy_px) > 100:
975
- indices = np.linspace(0, len(xy_px) - 1, 100, dtype=int)
976
- xy_px = xy_px[indices]
977
- artist_data['path_px'] = xy_px.tolist()
978
- artist_data['linewidth'] = artist.get_linewidth()
979
-
980
- elif artist_type == 'scatter' and hasattr(artist, 'get_offsets'):
981
- offsets = artist.get_offsets()
982
- transform = artist.get_transform()
983
- offsets_px = transform.transform(offsets)
984
- offsets_px[:, 1] = fig_height_px - offsets_px[:, 1]
985
- artist_data['points_px'] = offsets_px.tolist()
986
- sizes = artist.get_sizes()
987
- artist_data['sizes'] = sizes.tolist() if len(sizes) > 0 else [36]
988
-
989
- elif artist_type == 'fill' and hasattr(artist, 'get_paths'):
990
- paths = artist.get_paths()
991
- if paths:
992
- transform = artist.get_transform()
993
- vertices = paths[0].vertices
994
- vertices_px = transform.transform(vertices)
995
- vertices_px[:, 1] = fig_height_px - vertices_px[:, 1]
996
- # Sample if too many vertices
997
- if len(vertices_px) > 100:
998
- indices = np.linspace(0, len(vertices_px) - 1, 100, dtype=int)
999
- vertices_px = vertices_px[indices]
1000
- artist_data['polygon_px'] = vertices_px.tolist()
1001
-
1002
- elif artist_type == 'bar' and hasattr(artist, 'patches'):
1003
- bars = []
1004
- ax = fig.axes[ax_idx]
1005
- for patch in artist.patches:
1006
- # Get data coordinates
1007
- x_data = patch.get_x()
1008
- y_data = patch.get_y()
1009
- w_data = patch.get_width()
1010
- h_data = patch.get_height()
1011
- bars.append({
1012
- 'x': x_data,
1013
- 'y': y_data,
1014
- 'width': w_data,
1015
- 'height': h_data,
1016
- })
1017
- artist_data['bars_data'] = bars
1018
-
1019
- elif artist_type == 'rectangle':
1020
- artist_data['rectangle'] = {
1021
- 'x': artist.get_x(),
1022
- 'y': artist.get_y(),
1023
- 'width': artist.get_width(),
1024
- 'height': artist.get_height(),
1025
- }
1026
-
1027
- except Exception as e:
1028
- artist_data['error'] = str(e)
1029
-
1030
- export['artists'].append(artist_data)
1031
-
1032
- # Convert all numpy types to native Python for JSON serialization
1033
- return _to_native(export)
1034
-
1035
-
1036
- def extract_selectable_regions(fig) -> Dict[str, Any]:
1037
- """
1038
- Extract bounding boxes for axis/annotation elements (non-data elements).
1039
-
1040
- This provides a complementary approach to the color-based hitmap:
1041
- - Data elements: Use hitmap color lookup (pixel-perfect)
1042
- - Axis elements: Use bounding box hit testing (calculated)
1043
-
1044
- The client-side hit test logic:
1045
- 1. Check selectable_regions bounding boxes first (fast rectangle test)
1046
- 2. If no match, sample hitmap color for data elements
1047
-
1048
- Parameters
1049
- ----------
1050
- fig : matplotlib.figure.Figure
1051
- The figure to extract regions from.
1052
-
1053
- Returns
1054
- -------
1055
- dict
1056
- Dictionary with selectable regions:
1057
- {
1058
- "axes": [{
1059
- "index": 0,
1060
- "title": {"bbox_px": [x0, y0, x1, y1], "text": "..."},
1061
- "xlabel": {"bbox_px": [...], "text": "..."},
1062
- "ylabel": {"bbox_px": [...], "text": "..."},
1063
- "xaxis": {
1064
- "spine": {"bbox_px": [...]},
1065
- "ticks": [{"bbox_px": [...], "position": 0.0}, ...],
1066
- "ticklabels": [{"bbox_px": [...], "text": "0"}, ...]
1067
- },
1068
- "yaxis": {...},
1069
- "legend": {
1070
- "bbox_px": [...],
1071
- "entries": [{"bbox_px": [...], "label": "Series A"}, ...]
1072
- }
1073
- }]
1074
- }
1075
- """
1076
- with warnings.catch_warnings():
1077
- warnings.filterwarnings("ignore", message=".*tight_layout.*")
1078
- fig.canvas.draw() # Ensure transforms are computed
1079
-
1080
- dpi = fig.dpi
1081
- fig_width_px = int(fig.get_figwidth() * dpi)
1082
- fig_height_px = int(fig.get_figheight() * dpi)
1083
-
1084
- renderer = fig.canvas.get_renderer()
1085
-
1086
- def get_bbox_px(artist) -> Optional[List[float]]:
1087
- """Get bounding box in pixels (y-flipped for image coordinates)."""
1088
- try:
1089
- bbox = artist.get_window_extent(renderer)
1090
- if bbox.width > 0 and bbox.height > 0:
1091
- return [
1092
- float(bbox.x0),
1093
- float(fig_height_px - bbox.y1), # Flip Y
1094
- float(bbox.x1),
1095
- float(fig_height_px - bbox.y0),
1096
- ]
1097
- except Exception:
1098
- pass
1099
- return None
1100
-
1101
- def get_text_info(text_artist) -> Optional[Dict[str, Any]]:
1102
- """Extract text element info with bounding box."""
1103
- if text_artist is None:
1104
- return None
1105
- text = text_artist.get_text()
1106
- if not text or not text.strip():
1107
- return None
1108
- bbox = get_bbox_px(text_artist)
1109
- if bbox is None:
1110
- return None
1111
- return {
1112
- "bbox_px": bbox,
1113
- "text": text,
1114
- "fontsize": text_artist.get_fontsize(),
1115
- "color": text_artist.get_color(),
1116
- }
1117
-
1118
- regions = {"axes": []}
1119
-
1120
- for ax_idx, ax in enumerate(fig.axes):
1121
- ax_region = {"index": ax_idx}
1122
-
1123
- # Title
1124
- title_info = get_text_info(ax.title)
1125
- if title_info:
1126
- ax_region["title"] = title_info
1127
-
1128
- # X label
1129
- xlabel_info = get_text_info(ax.xaxis.label)
1130
- if xlabel_info:
1131
- ax_region["xlabel"] = xlabel_info
1132
-
1133
- # Y label
1134
- ylabel_info = get_text_info(ax.yaxis.label)
1135
- if ylabel_info:
1136
- ax_region["ylabel"] = ylabel_info
1137
-
1138
- # X axis elements
1139
- xaxis_info = {"spine": None, "ticks": [], "ticklabels": []}
1140
-
1141
- # X spine (bottom)
1142
- if ax.spines['bottom'].get_visible():
1143
- spine_bbox = get_bbox_px(ax.spines['bottom'])
1144
- if spine_bbox:
1145
- xaxis_info["spine"] = {"bbox_px": spine_bbox}
1146
-
1147
- # X ticks and tick labels
1148
- for tick in ax.xaxis.get_major_ticks():
1149
- # Tick mark
1150
- if tick.tick1line.get_visible():
1151
- tick_bbox = get_bbox_px(tick.tick1line)
1152
- if tick_bbox:
1153
- xaxis_info["ticks"].append({
1154
- "bbox_px": tick_bbox,
1155
- "position": float(tick.get_loc()) if hasattr(tick, 'get_loc') else None,
1156
- })
1157
-
1158
- # Tick label
1159
- if tick.label1.get_visible():
1160
- label_info = get_text_info(tick.label1)
1161
- if label_info:
1162
- xaxis_info["ticklabels"].append(label_info)
1163
-
1164
- if xaxis_info["spine"] or xaxis_info["ticks"] or xaxis_info["ticklabels"]:
1165
- ax_region["xaxis"] = xaxis_info
1166
-
1167
- # Y axis elements
1168
- yaxis_info = {"spine": None, "ticks": [], "ticklabels": []}
1169
-
1170
- # Y spine (left)
1171
- if ax.spines['left'].get_visible():
1172
- spine_bbox = get_bbox_px(ax.spines['left'])
1173
- if spine_bbox:
1174
- yaxis_info["spine"] = {"bbox_px": spine_bbox}
1175
-
1176
- # Y ticks and tick labels
1177
- for tick in ax.yaxis.get_major_ticks():
1178
- # Tick mark
1179
- if tick.tick1line.get_visible():
1180
- tick_bbox = get_bbox_px(tick.tick1line)
1181
- if tick_bbox:
1182
- yaxis_info["ticks"].append({
1183
- "bbox_px": tick_bbox,
1184
- "position": float(tick.get_loc()) if hasattr(tick, 'get_loc') else None,
1185
- })
1186
-
1187
- # Tick label
1188
- if tick.label1.get_visible():
1189
- label_info = get_text_info(tick.label1)
1190
- if label_info:
1191
- yaxis_info["ticklabels"].append(label_info)
1192
-
1193
- if yaxis_info["spine"] or yaxis_info["ticks"] or yaxis_info["ticklabels"]:
1194
- ax_region["yaxis"] = yaxis_info
1195
-
1196
- # Legend
1197
- legend = ax.get_legend()
1198
- if legend and legend.get_visible():
1199
- legend_info = {"bbox_px": None, "entries": []}
1200
-
1201
- legend_bbox = get_bbox_px(legend)
1202
- if legend_bbox:
1203
- legend_info["bbox_px"] = legend_bbox
1204
-
1205
- # Legend entries
1206
- for text in legend.get_texts():
1207
- entry_info = get_text_info(text)
1208
- if entry_info:
1209
- legend_info["entries"].append(entry_info)
1210
-
1211
- # Legend handles (the visual markers)
1212
- try:
1213
- handles = legend.legendHandles
1214
- for i, handle in enumerate(handles):
1215
- handle_bbox = get_bbox_px(handle)
1216
- if handle_bbox and i < len(legend_info["entries"]):
1217
- legend_info["entries"][i]["handle_bbox_px"] = handle_bbox
1218
- except Exception:
1219
- pass
1220
-
1221
- if legend_info["bbox_px"] or legend_info["entries"]:
1222
- ax_region["legend"] = legend_info
1223
-
1224
- regions["axes"].append(ax_region)
1225
-
1226
- # Convert all numpy types to native Python for JSON serialization
1227
- return _to_native(regions)
1228
-
1229
-
1230
- def query_hitmap_neighborhood(
1231
- hitmap: np.ndarray,
1232
- x: int,
1233
- y: int,
1234
- color_map: Dict[int, Dict[str, Any]],
1235
- radius: int = 2,
1236
- ) -> List[Dict[str, Any]]:
1237
- """
1238
- Query hit map with neighborhood sampling for smart selection.
1239
-
1240
- Finds all element IDs in a neighborhood around the click point,
1241
- enabling selection of overlapping elements and thin lines.
1242
-
1243
- Parameters
1244
- ----------
1245
- hitmap : np.ndarray
1246
- Hit map array (uint32, element IDs from RGB encoding).
1247
- x : int
1248
- X coordinate (column) of click point.
1249
- y : int
1250
- Y coordinate (row) of click point.
1251
- color_map : dict
1252
- Mapping from element ID to element info.
1253
- radius : int
1254
- Sampling radius (e.g., 2 = 5×5 neighborhood).
1255
-
1256
- Returns
1257
- -------
1258
- list of dict
1259
- List of element info dicts for all elements found in neighborhood,
1260
- sorted by distance from click point (closest first).
1261
-
1262
- Notes
1263
- -----
1264
- Use cases:
1265
- - Alt+Click to select objects underneath (lower z-order)
1266
- - Click on thin lines that might be missed with exact pixel
1267
- - Show candidate list when multiple elements overlap
1268
- """
1269
- h, w = hitmap.shape
1270
- found_ids = set()
1271
- id_distances = {}
1272
-
1273
- # Sample neighborhood
1274
- for dy in range(-radius, radius + 1):
1275
- for dx in range(-radius, radius + 1):
1276
- ny, nx = y + dy, x + dx
1277
- if 0 <= ny < h and 0 <= nx < w:
1278
- element_id = int(hitmap[ny, nx])
1279
- if element_id > 0 and element_id in color_map:
1280
- found_ids.add(element_id)
1281
- # Track minimum distance for each ID
1282
- dist = abs(dx) + abs(dy) # Manhattan distance
1283
- if element_id not in id_distances or dist < id_distances[element_id]:
1284
- id_distances[element_id] = dist
1285
-
1286
- # Sort by distance (closest first), then by ID for stability
1287
- sorted_ids = sorted(found_ids, key=lambda eid: (id_distances[eid], eid))
1288
-
1289
- return [color_map[eid] for eid in sorted_ids]
1290
-
1291
-
1292
- def save_hitmap_png(hitmap: np.ndarray, path: str, color_map: Dict = None):
1293
- """
1294
- Save hit map as a PNG file (RGB encoding for 24-bit IDs).
1295
-
1296
- Parameters
1297
- ----------
1298
- hitmap : np.ndarray
1299
- Hit map array (uint32, element IDs from 24-bit RGB encoding).
1300
- path : str
1301
- Output path for PNG file.
1302
- color_map : dict, optional
1303
- Color map for visualization.
1304
- """
1305
- import matplotlib.pyplot as plt
1306
- from PIL import Image
1307
-
1308
- # Convert 24-bit IDs back to RGB for PNG storage
1309
- h, w = hitmap.shape
1310
- rgb = np.zeros((h, w, 3), dtype=np.uint8)
1311
- rgb[:, :, 0] = (hitmap >> 16) & 0xFF # R
1312
- rgb[:, :, 1] = (hitmap >> 8) & 0xFF # G
1313
- rgb[:, :, 2] = hitmap & 0xFF # B
1314
-
1315
- # Save as RGB PNG (preserves exact ID values)
1316
- img = Image.fromarray(rgb, mode='RGB')
1317
- img.save(path)
1318
-
1319
-
1320
- def apply_hitmap_colors(
1321
- fig,
1322
- include_text: bool = False,
1323
- ) -> Tuple[List[Dict[str, Any]], Dict[int, Dict[str, Any]], Dict[str, Dict[str, Any]]]:
1324
- """
1325
- Apply unique ID colors to data elements in a figure.
1326
-
1327
- This function modifies data elements (lines, patches, etc.) to have unique
1328
- RGB colors for hit testing, while keeping axes/spines/labels unchanged.
1329
- This preserves the bbox_inches='tight' bounding box calculation.
1330
-
1331
- Also detects logical groups (histogram, bar_series, etc.) and assigns
1332
- group_id to each element for hierarchical selection.
1333
-
1334
- Parameters
1335
- ----------
1336
- fig : matplotlib.figure.Figure
1337
- The figure to modify.
1338
- include_text : bool
1339
- Whether to include text elements.
1340
-
1341
- Returns
1342
- -------
1343
- tuple
1344
- (original_props, color_map, groups) where:
1345
- - original_props: list of dicts with original artist properties for restoration
1346
- - color_map: dict mapping ID to element info (includes group_id, role)
1347
- - groups: dict mapping group_id to logical group info
1348
- """
1349
- # Get artists with group information
1350
- artists_with_groups, groups = get_all_artists_with_groups(fig, include_text)
1351
-
1352
- original_props = []
1353
- color_map = {}
1354
-
1355
- for i, (artist, ax_idx, artist_type, group_id) in enumerate(artists_with_groups):
1356
- element_id = i + 1
1357
- r, g, b = _id_to_rgb(element_id)
1358
- hex_color = f"#{r:02x}{g:02x}{b:02x}"
1359
-
1360
- # Store original properties
1361
- props = {'artist': artist, 'type': artist_type}
1362
- try:
1363
- if hasattr(artist, 'get_color'):
1364
- props['color'] = artist.get_color()
1365
- if hasattr(artist, 'get_facecolor'):
1366
- props['facecolor'] = artist.get_facecolor()
1367
- if hasattr(artist, 'get_edgecolor'):
1368
- props['edgecolor'] = artist.get_edgecolor()
1369
- if hasattr(artist, 'get_alpha'):
1370
- props['alpha'] = artist.get_alpha()
1371
- if hasattr(artist, 'get_antialiased'):
1372
- props['antialiased'] = artist.get_antialiased()
1373
- if hasattr(artist, 'get_linewidth'):
1374
- props['linewidth'] = artist.get_linewidth()
1375
- except Exception:
1376
- pass
1377
- original_props.append(props)
1378
-
1379
- # Build color map entry with group information
1380
- label = ''
1381
- if hasattr(artist, 'get_label'):
1382
- label = artist.get_label()
1383
- if label.startswith('_'):
1384
- label = f'{artist_type}_{i}'
1385
-
1386
- # Determine role based on group membership
1387
- role = 'physical' if group_id else 'standalone'
1388
-
1389
- color_map[element_id] = {
1390
- 'id': element_id,
1391
- 'type': artist_type,
1392
- 'label': label,
1393
- 'axes_index': ax_idx,
1394
- 'rgb': [r, g, b],
1395
- 'group_id': group_id, # NEW: logical group this element belongs to
1396
- 'role': role, # NEW: 'physical' (part of group), 'standalone' (no group), or 'logical' (is a group)
1397
- }
1398
-
1399
- # Apply ID color
1400
- try:
1401
- _apply_id_color(artist, hex_color)
1402
- except Exception:
1403
- pass
1404
-
1405
- # Add RGB color to groups for logical selection
1406
- # Groups get IDs starting after all physical elements
1407
- group_id_start = len(artists_with_groups) + 1
1408
- groups_with_colors = {}
1409
- for i, (gid, ginfo) in enumerate(groups.items()):
1410
- logical_id = group_id_start + i
1411
- r, g, b = _id_to_rgb(logical_id)
1412
-
1413
- # Find member element IDs
1414
- member_ids = []
1415
- for elem_id, elem_info in color_map.items():
1416
- if elem_info.get('group_id') == gid:
1417
- member_ids.append(elem_id)
1418
-
1419
- groups_with_colors[gid] = {
1420
- 'id': logical_id,
1421
- 'type': ginfo['type'],
1422
- 'label': ginfo['label'],
1423
- 'axes_index': ginfo['axes_index'],
1424
- 'rgb': [r, g, b],
1425
- 'role': 'logical',
1426
- 'member_ids': member_ids,
1427
- 'member_count': ginfo['member_count'],
1428
- }
1429
-
1430
- return original_props, color_map, groups_with_colors
1431
-
1432
-
1433
- def restore_original_colors(original_props: List[Dict[str, Any]]):
1434
- """
1435
- Restore original colors to artists after hitmap generation.
1436
-
1437
- Parameters
1438
- ----------
1439
- original_props : list
1440
- List of dicts with original artist properties (from apply_hitmap_colors).
1441
- """
1442
- for props in original_props:
1443
- artist = props['artist']
1444
- try:
1445
- if 'color' in props and hasattr(artist, 'set_color'):
1446
- artist.set_color(props['color'])
1447
- if 'facecolor' in props and hasattr(artist, 'set_facecolor'):
1448
- artist.set_facecolor(props['facecolor'])
1449
- if 'edgecolor' in props and hasattr(artist, 'set_edgecolor'):
1450
- artist.set_edgecolor(props['edgecolor'])
1451
- if 'alpha' in props and hasattr(artist, 'set_alpha'):
1452
- artist.set_alpha(props['alpha'])
1453
- if 'antialiased' in props and hasattr(artist, 'set_antialiased'):
1454
- artist.set_antialiased(props['antialiased'])
1455
- if 'linewidth' in props and hasattr(artist, 'set_linewidth'):
1456
- artist.set_linewidth(props['linewidth'])
1457
- except Exception:
1458
- pass
1459
-
1460
-
1461
- def generate_hitmap_with_bbox_tight(
1462
- fig,
1463
- dpi: int = 150,
1464
- include_text: bool = False,
1465
- ) -> Tuple['Image.Image', Dict[int, Dict[str, Any]]]:
1466
- """
1467
- Generate a hitmap image with bbox_inches='tight' to match PNG output.
1468
-
1469
- This function generates a hitmap that exactly matches the PNG saved with
1470
- bbox_inches='tight'. The key insight is that both PNG and hitmap must use
1471
- the same savefig parameters to have identical cropping.
1472
-
1473
- Parameters
1474
- ----------
1475
- fig : matplotlib.figure.Figure
1476
- The figure to generate hit map for.
1477
- dpi : int
1478
- Resolution for hit map rendering.
1479
- include_text : bool
1480
- Whether to include text elements in hit map.
1481
-
1482
- Returns
1483
- -------
1484
- tuple
1485
- (hitmap_image, color_map) where:
1486
- - hitmap_image: PIL.Image.Image with RGB-encoded element IDs
1487
- - color_map: dict mapping ID to element info
1488
- """
1489
- import matplotlib.pyplot as plt
1490
- from PIL import Image
1491
- import io
1492
- import tempfile
1493
-
1494
- # Get all artists
1495
- artists = get_all_artists(fig, include_text)
1496
-
1497
- if not artists:
1498
- # Return empty black image with same size as PNG would have
1499
- buf = io.BytesIO()
1500
- fig.savefig(buf, format='png', dpi=dpi, bbox_inches='tight')
1501
- buf.seek(0)
1502
- img = Image.open(buf).convert('RGB')
1503
- # Create black image of same size
1504
- black_img = Image.new('RGB', img.size, (0, 0, 0))
1505
- return black_img, {}
1506
-
1507
- # Store original properties for restoration
1508
- original_props = []
1509
- original_ax_props = []
1510
-
1511
- # Store original axes properties
1512
- for ax in fig.axes:
1513
- ax_props = {
1514
- 'ax': ax,
1515
- 'facecolor': ax.get_facecolor(),
1516
- 'grid_visible': ax.xaxis.get_gridlines()[0].get_visible() if ax.xaxis.get_gridlines() else False,
1517
- 'spines': {name: spine.get_visible() for name, spine in ax.spines.items()},
1518
- 'xlabel': ax.get_xlabel(),
1519
- 'ylabel': ax.get_ylabel(),
1520
- 'title': ax.get_title(),
1521
- 'tick_params': {
1522
- 'left': ax.yaxis.get_tick_params()['left'] if hasattr(ax.yaxis.get_tick_params(), '__getitem__') else True,
1523
- 'bottom': ax.xaxis.get_tick_params()['bottom'] if hasattr(ax.xaxis.get_tick_params(), '__getitem__') else True,
1524
- },
1525
- }
1526
- if ax.get_legend():
1527
- ax_props['legend_visible'] = ax.get_legend().get_visible()
1528
- original_ax_props.append(ax_props)
1529
-
1530
- original_fig_facecolor = fig.patch.get_facecolor()
1531
-
1532
- # Build color map
1533
- color_map = {}
1534
-
1535
- for i, (artist, ax_idx, artist_type) in enumerate(artists):
1536
- element_id = i + 1
1537
- r, g, b = _id_to_rgb(element_id)
1538
- hex_color = f"#{r:02x}{g:02x}{b:02x}"
1539
-
1540
- # Store original properties
1541
- props = {'artist': artist, 'type': artist_type}
1542
- try:
1543
- if hasattr(artist, 'get_color'):
1544
- props['color'] = artist.get_color()
1545
- if hasattr(artist, 'get_facecolor'):
1546
- props['facecolor'] = artist.get_facecolor()
1547
- if hasattr(artist, 'get_edgecolor'):
1548
- props['edgecolor'] = artist.get_edgecolor()
1549
- if hasattr(artist, 'get_alpha'):
1550
- props['alpha'] = artist.get_alpha()
1551
- if hasattr(artist, 'get_antialiased'):
1552
- props['antialiased'] = artist.get_antialiased()
1553
- except Exception:
1554
- pass
1555
- original_props.append(props)
1556
-
1557
- # Build color map entry
1558
- label = ''
1559
- if hasattr(artist, 'get_label'):
1560
- label = artist.get_label()
1561
- if label.startswith('_'):
1562
- label = f'{artist_type}_{i}'
1563
-
1564
- color_map[element_id] = {
1565
- 'id': element_id,
1566
- 'type': artist_type,
1567
- 'label': label,
1568
- 'axes_index': ax_idx,
1569
- 'rgb': [r, g, b],
1570
- }
1571
-
1572
- # Apply ID color
1573
- try:
1574
- _apply_id_color(artist, hex_color)
1575
- except Exception:
1576
- pass
1577
-
1578
- # Make non-artist elements a reserved "axes" color (NOT black/invisible)
1579
- # This preserves bbox_inches='tight' bounds while distinguishing from background
1580
- # Use HITMAP_AXES_COLOR (#010101) which maps to ID 65793 (non-selectable)
1581
- axes_color = HITMAP_AXES_COLOR
1582
- for ax in fig.axes:
1583
- ax.grid(False)
1584
- # Make spines the reserved axes color instead of black
1585
- for spine in ax.spines.values():
1586
- spine.set_color(axes_color)
1587
- ax.set_facecolor(HITMAP_BACKGROUND_COLOR) # Keep facecolor as background
1588
- # Make tick labels the reserved axes color
1589
- ax.tick_params(colors=axes_color, labelcolor=axes_color)
1590
- # Make axis labels the reserved axes color
1591
- ax.xaxis.label.set_color(axes_color)
1592
- ax.yaxis.label.set_color(axes_color)
1593
- # Make title the reserved axes color
1594
- ax.title.set_color(axes_color)
1595
- if ax.get_legend():
1596
- ax.get_legend().set_visible(False)
1597
-
1598
- fig.patch.set_facecolor(HITMAP_BACKGROUND_COLOR)
1599
-
1600
- # Save hitmap with bbox_inches='tight' - SAME as PNG
1601
- buf = io.BytesIO()
1602
- fig.savefig(buf, format='png', dpi=dpi, bbox_inches='tight', facecolor=HITMAP_BACKGROUND_COLOR)
1603
- buf.seek(0)
1604
- hitmap_img = Image.open(buf).convert('RGB')
1605
-
1606
- # Restore original properties
1607
- for props in original_props:
1608
- artist = props['artist']
1609
- try:
1610
- if 'color' in props and hasattr(artist, 'set_color'):
1611
- artist.set_color(props['color'])
1612
- if 'facecolor' in props and hasattr(artist, 'set_facecolor'):
1613
- artist.set_facecolor(props['facecolor'])
1614
- if 'edgecolor' in props and hasattr(artist, 'set_edgecolor'):
1615
- artist.set_edgecolor(props['edgecolor'])
1616
- if 'alpha' in props and hasattr(artist, 'set_alpha'):
1617
- artist.set_alpha(props['alpha'])
1618
- if 'antialiased' in props and hasattr(artist, 'set_antialiased'):
1619
- artist.set_antialiased(props['antialiased'])
1620
- except Exception:
1621
- pass
1622
-
1623
- # Restore axes properties
1624
- for ax_props in original_ax_props:
1625
- ax = ax_props['ax']
1626
- try:
1627
- ax.set_facecolor(ax_props['facecolor'])
1628
- for name, visible in ax_props['spines'].items():
1629
- ax.spines[name].set_visible(visible)
1630
- ax.set_xlabel(ax_props['xlabel'])
1631
- ax.set_ylabel(ax_props['ylabel'])
1632
- ax.set_title(ax_props['title'])
1633
- if 'legend_visible' in ax_props and ax.get_legend():
1634
- ax.get_legend().set_visible(ax_props['legend_visible'])
1635
- except Exception:
1636
- pass
1637
-
1638
- fig.patch.set_facecolor(original_fig_facecolor)
1639
-
1640
- return hitmap_img, color_map
1641
-
1642
-
1643
73
  # EOF