scitex 2.10.3__py3-none-any.whl → 2.13.0__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 (504) hide show
  1. scitex/__init__.py +1 -4
  2. scitex/__main__.py +24 -5
  3. scitex/__version__.py +1 -1
  4. scitex/_install_guide.py +14 -2
  5. scitex/_optional_deps.py +33 -0
  6. scitex/ai/classification/reporters/_ClassificationReporter.py +1 -1
  7. scitex/ai/classification/timeseries/_TimeSeriesBlockingSplit.py +2 -2
  8. scitex/ai/classification/timeseries/_TimeSeriesCalendarSplit.py +2 -2
  9. scitex/ai/classification/timeseries/_TimeSeriesSlidingWindowSplit.py +2 -2
  10. scitex/ai/classification/timeseries/_TimeSeriesSlidingWindowSplit_v01-not-using-n_splits.py +2 -2
  11. scitex/ai/classification/timeseries/_TimeSeriesStratifiedSplit.py +2 -2
  12. scitex/ai/classification/timeseries/_normalize_timestamp.py +1 -1
  13. scitex/ai/metrics/_calc_seizure_prediction_metrics.py +1 -1
  14. scitex/ai/plt/_plot_feature_importance.py +1 -1
  15. scitex/ai/plt/_plot_learning_curve.py +1 -1
  16. scitex/ai/plt/_plot_optuna_study.py +1 -1
  17. scitex/ai/plt/_plot_pre_rec_curve.py +1 -1
  18. scitex/ai/plt/_plot_roc_curve.py +1 -1
  19. scitex/ai/plt/_stx_conf_mat.py +1 -1
  20. scitex/ai/training/_LearningCurveLogger.py +1 -1
  21. scitex/audio/mcp_server.py +38 -8
  22. scitex/bridge/_figrecipe.py +1 -1
  23. scitex/bridge/_helpers.py +1 -1
  24. scitex/bridge/_plt_vis.py +1 -1
  25. scitex/bridge/_stats_plt.py +1 -1
  26. scitex/bridge/_stats_vis.py +2 -2
  27. scitex/browser/automation/CookieHandler.py +1 -1
  28. scitex/browser/core/BrowserMixin.py +1 -1
  29. scitex/browser/core/ChromeProfileManager.py +1 -1
  30. scitex/browser/debugging/_browser_logger.py +1 -1
  31. scitex/browser/debugging/_highlight_element.py +1 -1
  32. scitex/browser/debugging/_show_grid.py +1 -1
  33. scitex/browser/interaction/click_center.py +1 -1
  34. scitex/browser/interaction/click_with_fallbacks.py +1 -1
  35. scitex/browser/interaction/close_popups.py +1 -1
  36. scitex/browser/interaction/fill_with_fallbacks.py +1 -1
  37. scitex/browser/pdf/click_download_for_chrome_pdf_viewer.py +1 -1
  38. scitex/browser/pdf/detect_chrome_pdf_viewer.py +1 -1
  39. scitex/browser/stealth/HumanBehavior.py +1 -1
  40. scitex/browser/stealth/StealthManager.py +1 -1
  41. scitex/{fig → canvas}/__init__.py +84 -96
  42. scitex/canvas/_mcp_handlers.py +372 -0
  43. scitex/canvas/_mcp_tool_schemas.py +219 -0
  44. scitex/{fig → canvas}/backend/_parser.py +1 -1
  45. scitex/{fig → canvas}/canvas.py +13 -14
  46. scitex/{fts/_fig/_editor → canvas/editor}/_defaults.py +2 -2
  47. scitex/{fig → canvas}/editor/edit/__init__.py +11 -14
  48. scitex/{fig → canvas}/editor/edit/bundle_resolver.py +56 -48
  49. scitex/{fig → canvas}/editor/edit/editor_launcher.py +79 -26
  50. scitex/{fts/_fig/_editor/_cui/_panel_loader.py → canvas/editor/edit/panel_loader.py} +8 -8
  51. scitex/{fts/_fig/_editor/_gui/_flask_editor → canvas/editor/flask_editor}/_bbox.py +2 -1
  52. scitex/{fts/_fig/_editor/_gui/_flask_editor → canvas/editor/flask_editor}/_core.py +84 -84
  53. scitex/{fts/_fig/_editor/_gui/_flask_editor → canvas/editor/flask_editor}/_renderer.py +7 -6
  54. scitex/{fts/_fig/_editor/_gui/_flask_editor → canvas/editor/flask_editor}/static/css/features/canvas.css +2 -2
  55. scitex/{fig → canvas}/editor/flask_editor/static/css/features/panel-grid.css +1 -1
  56. scitex/{fig → canvas}/editor/flask_editor/static/js/core/api.js +3 -4
  57. scitex/{fig → canvas}/editor/flask_editor/static/js/editor/preview.js +5 -5
  58. scitex/{fig → canvas}/editor/flask_editor/templates/_html.py +3 -3
  59. scitex/{fig → canvas}/editor/flask_editor/templates/_scripts.py +10 -10
  60. scitex/{fig → canvas}/editor/flask_editor/templates/_styles.py +3 -3
  61. scitex/{fig → canvas}/io/__init__.py +32 -38
  62. scitex/{fig → canvas}/io/_bundle.py +217 -154
  63. scitex/{fig → canvas}/io/_canvas.py +1 -1
  64. scitex/{fig → canvas}/io/_data.py +1 -1
  65. scitex/{fig → canvas}/io/_export.py +1 -1
  66. scitex/{fig → canvas}/io/_load.py +1 -1
  67. scitex/{fig → canvas}/io/_panel.py +1 -1
  68. scitex/{fig → canvas}/io/_save.py +1 -1
  69. scitex/canvas/mcp_server.py +151 -0
  70. scitex/{fig → canvas}/model/__init__.py +1 -1
  71. scitex/{fig → canvas}/model/_annotations.py +1 -1
  72. scitex/{fig → canvas}/model/_axes.py +1 -1
  73. scitex/{fig → canvas}/model/_figure.py +1 -1
  74. scitex/{fig → canvas}/model/_guides.py +1 -1
  75. scitex/{fig → canvas}/model/_plot.py +1 -1
  76. scitex/{fig → canvas}/model/_styles.py +1 -1
  77. scitex/{fig → canvas}/utils/__init__.py +1 -1
  78. scitex/capture/mcp_server.py +41 -12
  79. scitex/cli/audio.py +233 -0
  80. scitex/cli/capture.py +307 -0
  81. scitex/cli/convert.py +10 -6
  82. scitex/cli/main.py +27 -4
  83. scitex/cli/repro.py +233 -0
  84. scitex/cli/resource.py +240 -0
  85. scitex/cli/stats.py +325 -0
  86. scitex/cli/template.py +236 -0
  87. scitex/cli/tex.py +286 -0
  88. scitex/cli/web.py +11 -12
  89. scitex/dev/__init__.py +3 -0
  90. scitex/dev/_pyproject.py +405 -0
  91. scitex/dev/plt/__init__.py +2 -2
  92. scitex/dev/plt/mpl/get_dir_ax.py +1 -1
  93. scitex/dev/plt/mpl/get_signatures.py +1 -1
  94. scitex/dev/plt/mpl/get_signatures_details.py +1 -1
  95. scitex/diagram/README.md +7 -7
  96. scitex/diagram/_mcp_handlers.py +400 -0
  97. scitex/diagram/_mcp_tool_schemas.py +157 -0
  98. scitex/diagram/mcp_server.py +151 -0
  99. scitex/dsp/_demo_sig.py +51 -5
  100. scitex/dsp/_mne.py +13 -2
  101. scitex/dsp/_modulation_index.py +15 -3
  102. scitex/dsp/_pac.py +23 -5
  103. scitex/dsp/_psd.py +16 -4
  104. scitex/dsp/_resample.py +24 -4
  105. scitex/dsp/_transform.py +16 -3
  106. scitex/dsp/add_noise.py +15 -1
  107. scitex/dsp/norm.py +17 -2
  108. scitex/dsp/reference.py +17 -1
  109. scitex/dsp/utils/_differential_bandpass_filters.py +20 -2
  110. scitex/dsp/utils/_zero_pad.py +18 -4
  111. scitex/dt/_normalize_timestamp.py +1 -1
  112. scitex/git/_session.py +1 -1
  113. scitex/io/__init__.py +7 -19
  114. scitex/io/_load.py +15 -19
  115. scitex/io/_load_modules/_canvas.py +2 -2
  116. scitex/io/_load_modules/_con.py +17 -6
  117. scitex/io/_load_modules/_eeg.py +28 -13
  118. scitex/io/_load_modules/_optuna.py +21 -63
  119. scitex/io/_load_modules/_torch.py +11 -3
  120. scitex/io/_save.py +11 -16
  121. scitex/io/_save_modules/__init__.py +6 -10
  122. scitex/io/_save_modules/_canvas.py +3 -3
  123. scitex/io/_save_modules/_optuna_study_as_csv_and_pngs.py +13 -2
  124. scitex/io/_save_modules/_plot_bundle.py +112 -0
  125. scitex/io/_save_modules/{_pltz_stx.py → _plot_scitex.py} +7 -7
  126. scitex/io/_save_modules/_stx_bundle.py +16 -16
  127. scitex/io/_save_modules/_torch.py +11 -3
  128. scitex/io/bundle/README.md +89 -80
  129. scitex/{fts/_bundle/_FTS.py → io/bundle/_Bundle.py} +197 -95
  130. scitex/io/bundle/__init__.py +67 -35
  131. scitex/{fts/_bundle → io/bundle}/_children.py +32 -40
  132. scitex/io/bundle/_core.py +184 -97
  133. scitex/{fts/_bundle/_dataclasses/_Node.py → io/bundle/_dataclasses/_Spec.py} +29 -23
  134. scitex/{fts/_bundle/_dataclasses/_NodeRefs.py → io/bundle/_dataclasses/_SpecRefs.py} +6 -6
  135. scitex/{fts/_bundle → io/bundle}/_dataclasses/__init__.py +4 -4
  136. scitex/{fts/_bundle → io/bundle}/_loader.py +19 -19
  137. scitex/io/bundle/_manifest.py +99 -0
  138. scitex/{fts/_bundle → io/bundle}/_mpl_helpers.py +119 -28
  139. scitex/io/bundle/_nested.py +113 -100
  140. scitex/{fts/_bundle → io/bundle}/_saver.py +13 -14
  141. scitex/{fts/_bundle → io/bundle}/_storage.py +3 -3
  142. scitex/io/bundle/_types.py +41 -16
  143. scitex/{fts/_bundle → io/bundle}/_validation.py +20 -18
  144. scitex/io/bundle/_zip.py +21 -31
  145. scitex/{fts/_kinds → io/bundle/kinds}/_plot/_backend/_parser.py +1 -1
  146. scitex/{fts/_kinds → io/bundle/kinds}/_plot/_models/_Annotations.py +1 -1
  147. scitex/{fts/_kinds → io/bundle/kinds}/_plot/_models/_Axes.py +1 -1
  148. scitex/{fts/_kinds → io/bundle/kinds}/_plot/_models/_Figure.py +1 -1
  149. scitex/{fts/_fig → io/bundle/kinds/_plot}/_models/_Guides.py +1 -1
  150. scitex/{fts/_kinds → io/bundle/kinds}/_plot/_models/_Plot.py +1 -1
  151. scitex/{fts/_fig → io/bundle/kinds/_plot}/_models/_Styles.py +1 -1
  152. scitex/{fts/_kinds → io/bundle/kinds}/_plot/_utils/_plot_layout.py +1 -1
  153. scitex/{fts/_kinds → io/bundle/kinds}/_table/_latex/__init__.py +1 -1
  154. scitex/{fts/_kinds → io/bundle/kinds}/_table/_latex/_editor/_app.py +1 -1
  155. scitex/{fts/_tables → io/bundle/kinds/_table}/_latex/_export.py +1 -1
  156. scitex/{fts/_kinds → io/bundle/kinds}/_table/_latex/_figure_exporter.py +1 -1
  157. scitex/{fts/_kinds → io/bundle/kinds}/_table/_latex/_table_exporter.py +1 -1
  158. scitex/io/bundle/schemas/__init__.py +30 -0
  159. scitex/mcp_server.py +159 -0
  160. scitex/parallel/_run.py +5 -4
  161. scitex/path/_find.py +60 -83
  162. scitex/path/_get_module_path.py +23 -21
  163. scitex/path/_get_spath.py +6 -27
  164. scitex/path/_getsize.py +23 -9
  165. scitex/path/_increment_version.py +31 -38
  166. scitex/path/_mk_spath.py +26 -29
  167. scitex/path/_path.py +5 -12
  168. scitex/path/_split.py +27 -15
  169. scitex/path/_this_path.py +23 -9
  170. scitex/plt/_mcp_handlers.py +361 -0
  171. scitex/plt/_mcp_tool_schemas.py +169 -0
  172. scitex/plt/_subplots/_AxisWrapperMixins/_MatplotlibPlotMixin/__init__.py +2 -1
  173. scitex/plt/_subplots/_AxisWrapperMixins/__init__.py +2 -2
  174. scitex/plt/gallery/_generate.py +76 -50
  175. scitex/plt/io/__init__.py +17 -19
  176. scitex/plt/io/_bundle.py +99 -52
  177. scitex/plt/io/_layered_bundle.py +303 -168
  178. scitex/plt/mcp_server.py +205 -0
  179. scitex/plt/utils/_csv_column_naming.py +250 -118
  180. scitex/repro/README_RandomStateManager.md +3 -3
  181. scitex/repro/_RandomStateManager.py +14 -14
  182. scitex/repro/_gen_ID.py +1 -1
  183. scitex/repro/_gen_timestamp.py +1 -1
  184. scitex/repro/_hash_array.py +4 -4
  185. scitex/schema/__init__.py +69 -73
  186. scitex/schema/_canvas.py +1 -1
  187. scitex/schema/_stats.py +2 -2
  188. scitex/scholar/__main__.py +24 -2
  189. scitex/scholar/_mcp_handlers.py +685 -0
  190. scitex/scholar/_mcp_tool_schemas.py +339 -0
  191. scitex/scholar/docs/template.py +1 -1
  192. scitex/scholar/examples/07_storage_integration.py +1 -1
  193. scitex/scholar/impact_factor/jcr/ImpactFactorJCREngine.py +1 -1
  194. scitex/scholar/impact_factor/jcr/build_database.py +1 -1
  195. scitex/scholar/mcp_server.py +315 -0
  196. scitex/scholar/pdf_download/ScholarPDFDownloader.py +1 -1
  197. scitex/scholar/pipelines/ScholarPipelineBibTeX.py +1 -1
  198. scitex/scholar/pipelines/ScholarPipelineParallel.py +1 -1
  199. scitex/scholar/pipelines/ScholarPipelineSingle.py +1 -1
  200. scitex/scholar/storage/PaperIO.py +1 -1
  201. scitex/session/README.md +4 -4
  202. scitex/session/__init__.py +1 -1
  203. scitex/session/_decorator.py +9 -9
  204. scitex/session/_lifecycle.py +5 -5
  205. scitex/session/template.py +1 -1
  206. scitex/stats/__init__.py +30 -33
  207. scitex/stats/__main__.py +281 -0
  208. scitex/stats/_mcp_handlers.py +1191 -0
  209. scitex/stats/_mcp_tool_schemas.py +384 -0
  210. scitex/stats/_schema.py +1 -1
  211. scitex/stats/correct/_correct_bonferroni.py +1 -1
  212. scitex/stats/correct/_correct_fdr.py +1 -1
  213. scitex/stats/correct/_correct_fdr_.py +1 -1
  214. scitex/stats/correct/_correct_holm.py +1 -1
  215. scitex/stats/correct/_correct_sidak.py +1 -1
  216. scitex/stats/effect_sizes/_cliffs_delta.py +1 -1
  217. scitex/stats/effect_sizes/_cohens_d.py +1 -1
  218. scitex/stats/effect_sizes/_epsilon_squared.py +1 -1
  219. scitex/stats/effect_sizes/_eta_squared.py +1 -1
  220. scitex/stats/effect_sizes/_prob_superiority.py +1 -1
  221. scitex/stats/io/__init__.py +10 -11
  222. scitex/stats/io/_bundle.py +16 -16
  223. scitex/stats/mcp_server.py +405 -0
  224. scitex/stats/posthoc/_dunnett.py +1 -1
  225. scitex/stats/posthoc/_games_howell.py +1 -1
  226. scitex/stats/posthoc/_tukey_hsd.py +1 -1
  227. scitex/stats/power/_power.py +1 -1
  228. scitex/stats/utils/_effect_size.py +1 -1
  229. scitex/stats/utils/_formatters.py +1 -1
  230. scitex/stats/utils/_power.py +1 -1
  231. scitex/template/_mcp_handlers.py +259 -0
  232. scitex/template/_mcp_tool_schemas.py +112 -0
  233. scitex/template/mcp_server.py +186 -0
  234. scitex/utils/_verify_scitex_format.py +2 -2
  235. scitex/utils/template.py +1 -1
  236. scitex/web/__init__.py +12 -11
  237. scitex/web/_scraping.py +26 -265
  238. scitex/web/download_images.py +316 -0
  239. scitex/writer/Writer.py +1 -1
  240. scitex/writer/_clone_writer_project.py +1 -1
  241. scitex/writer/_validate_tree_structures.py +1 -1
  242. scitex/writer/dataclasses/config/_WriterConfig.py +1 -1
  243. scitex/writer/dataclasses/contents/_ManuscriptContents.py +1 -1
  244. scitex/writer/dataclasses/core/_Document.py +1 -1
  245. scitex/writer/dataclasses/core/_DocumentSection.py +1 -1
  246. scitex/writer/dataclasses/results/_CompilationResult.py +1 -1
  247. scitex/writer/dataclasses/results/_LaTeXIssue.py +1 -1
  248. scitex/writer/utils/.legacy_git_retry.py +7 -5
  249. scitex/writer/utils/_parse_latex_logs.py +1 -1
  250. scitex-2.13.0.dist-info/METADATA +1231 -0
  251. {scitex-2.10.3.dist-info → scitex-2.13.0.dist-info}/RECORD +376 -470
  252. scitex-2.13.0.dist-info/entry_points.txt +11 -0
  253. scitex/fig/editor/_defaults.py +0 -300
  254. scitex/fig/editor/edit/panel_loader.py +0 -232
  255. scitex/fig/editor/flask_editor/_bbox.py +0 -1299
  256. scitex/fig/editor/flask_editor/_core.py +0 -1429
  257. scitex/fig/editor/flask_editor/_renderer.py +0 -813
  258. scitex/fig/editor/flask_editor/static/css/features/canvas.css +0 -176
  259. scitex/fts/README.md +0 -262
  260. scitex/fts/TODO.md +0 -66
  261. scitex/fts/__init__.py +0 -90
  262. scitex/fts/_bundle/README_IN_BUNDLE.md +0 -102
  263. scitex/fts/_bundle/__init__.py +0 -38
  264. scitex/fts/_bundle/_utils/__init__.py +0 -55
  265. scitex/fts/_bundle/_utils/_const.py +0 -26
  266. scitex/fts/_bundle/_utils/_errors.py +0 -73
  267. scitex/fts/_bundle/_utils/_generate.py +0 -21
  268. scitex/fts/_bundle/_utils/_types.py +0 -76
  269. scitex/fts/_bundle/_zipbundle.py +0 -165
  270. scitex/fts/_fig/__init__.py +0 -22
  271. scitex/fts/_fig/_backend/_parser.py +0 -188
  272. scitex/fts/_fig/_editor/__init__.py +0 -14
  273. scitex/fts/_fig/_editor/_cui/__init__.py +0 -33
  274. scitex/fts/_fig/_editor/_cui/_backend_detector.py +0 -39
  275. scitex/fts/_fig/_editor/_cui/_bundle_resolver.py +0 -366
  276. scitex/fts/_fig/_editor/_cui/_editor_launcher.py +0 -175
  277. scitex/fts/_fig/_editor/_cui/_manual_handler.py +0 -52
  278. scitex/fts/_fig/_editor/_cui/_path_resolver.py +0 -66
  279. scitex/fts/_fig/_editor/_gui/__init__.py +0 -11
  280. scitex/fts/_fig/_editor/_gui/_flask_editor/__init__.py +0 -20
  281. scitex/fts/_fig/_editor/_gui/_flask_editor/_plotter.py +0 -664
  282. scitex/fts/_fig/_editor/_gui/_flask_editor/_utils.py +0 -79
  283. scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/base/reset.css +0 -41
  284. scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/base/typography.css +0 -16
  285. scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/base/variables.css +0 -85
  286. scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/components/buttons.css +0 -217
  287. scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/components/context-menu.css +0 -93
  288. scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/components/dropdown.css +0 -57
  289. scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/components/forms.css +0 -112
  290. scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/components/modal.css +0 -59
  291. scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/components/sections.css +0 -212
  292. scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/features/element-inspector.css +0 -190
  293. scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/features/loading.css +0 -59
  294. scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/features/overlay.css +0 -45
  295. scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/features/panel-grid.css +0 -95
  296. scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/features/selection.css +0 -101
  297. scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/features/statistics.css +0 -138
  298. scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/index.css +0 -31
  299. scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/layout/container.css +0 -7
  300. scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/layout/controls.css +0 -56
  301. scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/layout/preview.css +0 -78
  302. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/alignment/axis.js +0 -314
  303. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/alignment/basic.js +0 -107
  304. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/alignment/distribute.js +0 -54
  305. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/canvas/canvas.js +0 -172
  306. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/canvas/dragging.js +0 -258
  307. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/canvas/resize.js +0 -48
  308. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/canvas/selection.js +0 -71
  309. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/core/api.js +0 -288
  310. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/core/state.js +0 -143
  311. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/core/utils.js +0 -245
  312. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/dev/element-inspector.js +0 -992
  313. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/editor/bbox.js +0 -339
  314. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/editor/element-drag.js +0 -286
  315. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/editor/overlay.js +0 -371
  316. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/editor/preview.js +0 -293
  317. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/main.js +0 -426
  318. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/shortcuts/context-menu.js +0 -152
  319. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/shortcuts/keyboard.js +0 -265
  320. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/ui/controls.js +0 -184
  321. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/ui/download.js +0 -57
  322. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/ui/help.js +0 -100
  323. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/ui/theme.js +0 -34
  324. scitex/fts/_fig/_editor/_gui/_flask_editor/templates/__init__.py +0 -124
  325. scitex/fts/_fig/_editor/_gui/_flask_editor/templates/_html.py +0 -851
  326. scitex/fts/_fig/_editor/_gui/_flask_editor/templates/_scripts.py +0 -4932
  327. scitex/fts/_fig/_editor/_gui/_flask_editor/templates/_styles.py +0 -1657
  328. scitex/fts/_fig/_editor/_gui/_flask_editor.py +0 -36
  329. scitex/fts/_fig/_models/_Annotations.py +0 -115
  330. scitex/fts/_fig/_models/_Axes.py +0 -152
  331. scitex/fts/_fig/_models/_Figure.py +0 -138
  332. scitex/fts/_fig/_models/_Plot.py +0 -123
  333. scitex/fts/_fig/_utils/_plot_layout.py +0 -397
  334. scitex/fts/_kinds/_figure/_composite.py +0 -345
  335. scitex/fts/_kinds/_plot/_backend/__init__.py +0 -53
  336. scitex/fts/_kinds/_plot/_backend/_export.py +0 -165
  337. scitex/fts/_kinds/_plot/_backend/_render.py +0 -538
  338. scitex/fts/_kinds/_plot/_dataclasses/_ChannelEncoding.py +0 -46
  339. scitex/fts/_kinds/_plot/_dataclasses/_Encoding.py +0 -82
  340. scitex/fts/_kinds/_plot/_dataclasses/_Theme.py +0 -441
  341. scitex/fts/_kinds/_plot/_dataclasses/_TraceEncoding.py +0 -52
  342. scitex/fts/_kinds/_plot/_dataclasses/__init__.py +0 -47
  343. scitex/fts/_kinds/_plot/_models/_Guides.py +0 -104
  344. scitex/fts/_kinds/_plot/_models/_Styles.py +0 -245
  345. scitex/fts/_kinds/_plot/_models/__init__.py +0 -80
  346. scitex/fts/_kinds/_plot/_models/_plot_types/__init__.py +0 -156
  347. scitex/fts/_kinds/_plot/_models/_plot_types/_bar.py +0 -43
  348. scitex/fts/_kinds/_plot/_models/_plot_types/_box.py +0 -38
  349. scitex/fts/_kinds/_plot/_models/_plot_types/_distribution.py +0 -36
  350. scitex/fts/_kinds/_plot/_models/_plot_types/_errorbar.py +0 -60
  351. scitex/fts/_kinds/_plot/_models/_plot_types/_histogram.py +0 -30
  352. scitex/fts/_kinds/_plot/_models/_plot_types/_image.py +0 -61
  353. scitex/fts/_kinds/_plot/_models/_plot_types/_line.py +0 -57
  354. scitex/fts/_kinds/_plot/_models/_plot_types/_scatter.py +0 -30
  355. scitex/fts/_kinds/_plot/_models/_plot_types/_seaborn.py +0 -121
  356. scitex/fts/_kinds/_plot/_models/_plot_types/_violin.py +0 -36
  357. scitex/fts/_kinds/_plot/_utils/__init__.py +0 -129
  358. scitex/fts/_kinds/_plot/_utils/_auto_layout.py +0 -127
  359. scitex/fts/_kinds/_plot/_utils/_calc_bounds.py +0 -111
  360. scitex/fts/_kinds/_plot/_utils/_const_sizes.py +0 -48
  361. scitex/fts/_kinds/_plot/_utils/_convert_coords.py +0 -77
  362. scitex/fts/_kinds/_plot/_utils/_get_template.py +0 -178
  363. scitex/fts/_kinds/_plot/_utils/_normalize.py +0 -73
  364. scitex/fts/_kinds/_plot/_utils/_validate.py +0 -197
  365. scitex/fts/_kinds/_table/_latex/_export.py +0 -279
  366. scitex/fts/_stats/__init__.py +0 -48
  367. scitex/fts/_stats/_dataclasses/_Stats.py +0 -423
  368. scitex/fts/_stats/_dataclasses/__init__.py +0 -48
  369. scitex/fts/_tables/__init__.py +0 -65
  370. scitex/fts/_tables/_latex/__init__.py +0 -93
  371. scitex/fts/_tables/_latex/_editor/__init__.py +0 -11
  372. scitex/fts/_tables/_latex/_editor/_app.py +0 -725
  373. scitex/fts/_tables/_latex/_figure_exporter.py +0 -153
  374. scitex/fts/_tables/_latex/_stats_formatter.py +0 -274
  375. scitex/fts/_tables/_latex/_table_exporter.py +0 -362
  376. scitex/fts/_tables/_latex/_utils.py +0 -369
  377. scitex/fts/_tables/_latex/_validator.py +0 -445
  378. scitex/io/_save_modules/_pltz_bundle.py +0 -356
  379. scitex-2.10.3.dist-info/METADATA +0 -952
  380. scitex-2.10.3.dist-info/entry_points.txt +0 -2
  381. /scitex/{fig → canvas}/README.md +0 -0
  382. /scitex/{fig → canvas}/backend/__init__.py +0 -0
  383. /scitex/{fig → canvas}/backend/_export.py +0 -0
  384. /scitex/{fig → canvas}/backend/_render.py +0 -0
  385. /scitex/{fig → canvas}/docs/CANVAS_ARCHITECTURE.md +0 -0
  386. /scitex/{fig → canvas}/editor/__init__.py +0 -0
  387. /scitex/{fig → canvas}/editor/_dearpygui_editor.py +0 -0
  388. /scitex/{fig → canvas}/editor/_flask_editor.py +0 -0
  389. /scitex/{fig → canvas}/editor/_mpl_editor.py +0 -0
  390. /scitex/{fig → canvas}/editor/_qt_editor.py +0 -0
  391. /scitex/{fig → canvas}/editor/_tkinter_editor.py +0 -0
  392. /scitex/{fig → canvas}/editor/edit/backend_detector.py +0 -0
  393. /scitex/{fig → canvas}/editor/edit/manual_handler.py +0 -0
  394. /scitex/{fig → canvas}/editor/edit/path_resolver.py +0 -0
  395. /scitex/{fig → canvas}/editor/flask_editor/__init__.py +0 -0
  396. /scitex/{fig → canvas}/editor/flask_editor/_plotter.py +0 -0
  397. /scitex/{fig → canvas}/editor/flask_editor/_utils.py +0 -0
  398. /scitex/{fig → canvas}/editor/flask_editor/static/css/base/reset.css +0 -0
  399. /scitex/{fig → canvas}/editor/flask_editor/static/css/base/typography.css +0 -0
  400. /scitex/{fig → canvas}/editor/flask_editor/static/css/base/variables.css +0 -0
  401. /scitex/{fig → canvas}/editor/flask_editor/static/css/components/buttons.css +0 -0
  402. /scitex/{fig → canvas}/editor/flask_editor/static/css/components/context-menu.css +0 -0
  403. /scitex/{fig → canvas}/editor/flask_editor/static/css/components/dropdown.css +0 -0
  404. /scitex/{fig → canvas}/editor/flask_editor/static/css/components/forms.css +0 -0
  405. /scitex/{fig → canvas}/editor/flask_editor/static/css/components/modal.css +0 -0
  406. /scitex/{fig → canvas}/editor/flask_editor/static/css/components/sections.css +0 -0
  407. /scitex/{fig → canvas}/editor/flask_editor/static/css/features/element-inspector.css +0 -0
  408. /scitex/{fig → canvas}/editor/flask_editor/static/css/features/loading.css +0 -0
  409. /scitex/{fig → canvas}/editor/flask_editor/static/css/features/overlay.css +0 -0
  410. /scitex/{fig → canvas}/editor/flask_editor/static/css/features/selection.css +0 -0
  411. /scitex/{fig → canvas}/editor/flask_editor/static/css/features/statistics.css +0 -0
  412. /scitex/{fig → canvas}/editor/flask_editor/static/css/index.css +0 -0
  413. /scitex/{fig → canvas}/editor/flask_editor/static/css/layout/container.css +0 -0
  414. /scitex/{fig → canvas}/editor/flask_editor/static/css/layout/controls.css +0 -0
  415. /scitex/{fig → canvas}/editor/flask_editor/static/css/layout/preview.css +0 -0
  416. /scitex/{fig → canvas}/editor/flask_editor/static/js/alignment/axis.js +0 -0
  417. /scitex/{fig → canvas}/editor/flask_editor/static/js/alignment/basic.js +0 -0
  418. /scitex/{fig → canvas}/editor/flask_editor/static/js/alignment/distribute.js +0 -0
  419. /scitex/{fig → canvas}/editor/flask_editor/static/js/canvas/canvas.js +0 -0
  420. /scitex/{fig → canvas}/editor/flask_editor/static/js/canvas/dragging.js +0 -0
  421. /scitex/{fig → canvas}/editor/flask_editor/static/js/canvas/resize.js +0 -0
  422. /scitex/{fig → canvas}/editor/flask_editor/static/js/canvas/selection.js +0 -0
  423. /scitex/{fig → canvas}/editor/flask_editor/static/js/core/state.js +0 -0
  424. /scitex/{fig → canvas}/editor/flask_editor/static/js/core/utils.js +0 -0
  425. /scitex/{fig → canvas}/editor/flask_editor/static/js/dev/element-inspector.js +0 -0
  426. /scitex/{fig → canvas}/editor/flask_editor/static/js/editor/bbox.js +0 -0
  427. /scitex/{fig → canvas}/editor/flask_editor/static/js/editor/element-drag.js +0 -0
  428. /scitex/{fig → canvas}/editor/flask_editor/static/js/editor/overlay.js +0 -0
  429. /scitex/{fig → canvas}/editor/flask_editor/static/js/main.js +0 -0
  430. /scitex/{fig → canvas}/editor/flask_editor/static/js/shortcuts/context-menu.js +0 -0
  431. /scitex/{fig → canvas}/editor/flask_editor/static/js/shortcuts/keyboard.js +0 -0
  432. /scitex/{fig → canvas}/editor/flask_editor/static/js/ui/controls.js +0 -0
  433. /scitex/{fig → canvas}/editor/flask_editor/static/js/ui/download.js +0 -0
  434. /scitex/{fig → canvas}/editor/flask_editor/static/js/ui/help.js +0 -0
  435. /scitex/{fig → canvas}/editor/flask_editor/static/js/ui/theme.js +0 -0
  436. /scitex/{fig → canvas}/editor/flask_editor/templates/__init__.py +0 -0
  437. /scitex/{fig → canvas}/io/_directory.py +0 -0
  438. /scitex/{fig → canvas}/model/_plot_types.py +0 -0
  439. /scitex/{fig → canvas}/utils/_defaults.py +0 -0
  440. /scitex/{fig → canvas}/utils/_validate.py +0 -0
  441. /scitex/{fts/_bundle → io/bundle}/_conversion/__init__.py +0 -0
  442. /scitex/{fts/_bundle → io/bundle}/_conversion/_bundle2dict.py +0 -0
  443. /scitex/{fts/_bundle → io/bundle}/_conversion/_dict2bundle.py +0 -0
  444. /scitex/{fts/_bundle → io/bundle}/_dataclasses/_Axes.py +0 -0
  445. /scitex/{fts/_bundle → io/bundle}/_dataclasses/_BBox.py +0 -0
  446. /scitex/{fts/_bundle → io/bundle}/_dataclasses/_ColumnDef.py +0 -0
  447. /scitex/{fts/_bundle → io/bundle}/_dataclasses/_DataFormat.py +0 -0
  448. /scitex/{fts/_bundle → io/bundle}/_dataclasses/_DataInfo.py +0 -0
  449. /scitex/{fts/_bundle → io/bundle}/_dataclasses/_DataSource.py +0 -0
  450. /scitex/{fts/_bundle → io/bundle}/_dataclasses/_SizeMM.py +0 -0
  451. /scitex/{fts/_bundle → io/bundle}/_extractors/__init__.py +0 -0
  452. /scitex/{fts/_bundle → io/bundle}/_extractors/_extract_bar.py +0 -0
  453. /scitex/{fts/_bundle → io/bundle}/_extractors/_extract_line.py +0 -0
  454. /scitex/{fts/_bundle → io/bundle}/_extractors/_extract_scatter.py +0 -0
  455. /scitex/{fts/_kinds → io/bundle/kinds}/__init__.py +0 -0
  456. /scitex/{fts/_kinds → io/bundle/kinds}/_figure/__init__.py +0 -0
  457. /scitex/{fts/_fig → io/bundle/kinds/_figure}/_composite.py +0 -0
  458. /scitex/{fts/_kinds → io/bundle/kinds}/_plot/__init__.py +0 -0
  459. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_backend/__init__.py +0 -0
  460. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_backend/_export.py +0 -0
  461. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_backend/_render.py +0 -0
  462. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_dataclasses/_ChannelEncoding.py +0 -0
  463. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_dataclasses/_Encoding.py +0 -0
  464. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_dataclasses/_Theme.py +0 -0
  465. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_dataclasses/_TraceEncoding.py +0 -0
  466. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_dataclasses/__init__.py +0 -0
  467. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_models/__init__.py +0 -0
  468. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_models/_plot_types/__init__.py +0 -0
  469. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_models/_plot_types/_bar.py +0 -0
  470. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_models/_plot_types/_box.py +0 -0
  471. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_models/_plot_types/_distribution.py +0 -0
  472. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_models/_plot_types/_errorbar.py +0 -0
  473. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_models/_plot_types/_histogram.py +0 -0
  474. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_models/_plot_types/_image.py +0 -0
  475. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_models/_plot_types/_line.py +0 -0
  476. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_models/_plot_types/_scatter.py +0 -0
  477. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_models/_plot_types/_seaborn.py +0 -0
  478. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_models/_plot_types/_violin.py +0 -0
  479. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_utils/__init__.py +0 -0
  480. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_utils/_auto_layout.py +0 -0
  481. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_utils/_calc_bounds.py +0 -0
  482. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_utils/_const_sizes.py +0 -0
  483. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_utils/_convert_coords.py +0 -0
  484. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_utils/_get_template.py +0 -0
  485. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_utils/_normalize.py +0 -0
  486. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_utils/_validate.py +0 -0
  487. /scitex/{fts/_kinds → io/bundle/kinds}/_shape/__init__.py +0 -0
  488. /scitex/{fts/_kinds → io/bundle/kinds}/_stats/__init__.py +0 -0
  489. /scitex/{fts/_kinds → io/bundle/kinds}/_stats/_dataclasses/_Stats.py +0 -0
  490. /scitex/{fts/_kinds → io/bundle/kinds}/_stats/_dataclasses/__init__.py +0 -0
  491. /scitex/{fts/_kinds → io/bundle/kinds}/_table/__init__.py +0 -0
  492. /scitex/{fts/_kinds → io/bundle/kinds}/_table/_latex/_editor/__init__.py +0 -0
  493. /scitex/{fts/_kinds → io/bundle/kinds}/_table/_latex/_stats_formatter.py +0 -0
  494. /scitex/{fts/_kinds → io/bundle/kinds}/_table/_latex/_utils.py +0 -0
  495. /scitex/{fts/_kinds → io/bundle/kinds}/_table/_latex/_validator.py +0 -0
  496. /scitex/{fts/_kinds → io/bundle/kinds}/_text/__init__.py +0 -0
  497. /scitex/{fts/_schemas → io/bundle/schemas}/data_info.schema.json +0 -0
  498. /scitex/{fts/_schemas → io/bundle/schemas}/encoding.schema.json +0 -0
  499. /scitex/{fts/_schemas → io/bundle/schemas}/node.schema.json +0 -0
  500. /scitex/{fts/_schemas → io/bundle/schemas}/render_manifest.schema.json +0 -0
  501. /scitex/{fts/_schemas → io/bundle/schemas}/stats.schema.json +0 -0
  502. /scitex/{fts/_schemas → io/bundle/schemas}/theme.schema.json +0 -0
  503. {scitex-2.10.3.dist-info → scitex-2.13.0.dist-info}/WHEEL +0 -0
  504. {scitex-2.10.3.dist-info → scitex-2.13.0.dist-info}/licenses/LICENSE +0 -0
@@ -1,9 +1,8 @@
1
1
  #!/usr/bin/env python3
2
- # -*- coding: utf-8 -*-
3
2
  # Timestamp: 2025-12-08
4
3
  # File: ./src/scitex/vis/__init__.py
5
4
  """
6
- SciTeX Visualization Module (scitex.fig)
5
+ SciTeX Visualization Module (scitex.canvas)
7
6
 
8
7
  Canvas-based composition of publication-quality figures.
9
8
 
@@ -19,7 +18,7 @@ Quick Start:
19
18
  >>> # Create canvas and add panels
20
19
  >>> stx.vis.create_canvas("/output", "fig1")
21
20
  >>> stx.vis.add_panel("/output", "fig1", "panel_a", source="plot.png",
22
- ... position=(10, 10), size=(80, 60), label="A")
21
+ ... xy_mm=(10, 10), size_mm=(80, 60), label="A")
23
22
  >>>
24
23
  >>> # Save with stx.io (auto-exports PNG/PDF/SVG)
25
24
  >>> canvas = stx.io.load("/output/fig1.canvas")
@@ -34,46 +33,31 @@ Directory Structure:
34
33
  """
35
34
 
36
35
  # Submodules for advanced use
37
- from . import io
38
- from . import model
39
- from . import backend
40
- from . import utils
41
- from . import editor
36
+ from . import backend, editor, io, model, utils
42
37
 
43
38
  # Canvas class
44
39
  from .canvas import Canvas
45
40
 
41
+ # Editor
42
+ from .editor import edit
43
+
44
+ # Data integrity
45
+ # Export (usually handled by stx.io.save, but available for explicit use)
46
46
  # =============================================================================
47
47
  # Primary API (minimal, reusable, flexible)
48
48
  # =============================================================================
49
-
50
49
  # Canvas operations
51
- from .io import (
52
- ensure_canvas_directory as create_canvas,
53
- get_canvas_directory_path as get_canvas_path,
54
- canvas_directory_exists as canvas_exists,
55
- list_canvas_directories as list_canvases,
56
- delete_canvas_directory as delete_canvas,
57
- )
58
-
59
50
  # Panel operations
60
- from .io import (
61
- add_panel_from_scitex,
62
- add_panel_from_image,
63
- update_panel,
64
- remove_panel,
65
- list_panels,
66
- )
67
-
68
- # Export (usually handled by stx.io.save, but available for explicit use)
51
+ from .io import add_panel_from_image, add_panel_from_scitex
52
+ from .io import canvas_directory_exists as canvas_exists
53
+ from .io import delete_canvas_directory as delete_canvas
54
+ from .io import ensure_canvas_directory as create_canvas
69
55
  from .io import export_canvas_to_file as export_canvas
70
-
71
- # Data integrity
56
+ from .io import get_canvas_directory_path as get_canvas_path
57
+ from .io import list_canvas_directories as list_canvases
58
+ from .io import list_panels, remove_panel, update_panel
72
59
  from .io import verify_all_data_hashes as verify_data
73
60
 
74
- # Editor
75
- from .editor import edit
76
-
77
61
 
78
62
  # =============================================================================
79
63
  # Convenience wrapper for add_panel
@@ -83,8 +67,8 @@ def add_panel(
83
67
  canvas_name,
84
68
  panel_name,
85
69
  source,
86
- position=(0, 0),
87
- size=(50, 50),
70
+ xy_mm=(0, 0),
71
+ size_mm=(50, 50),
88
72
  label="",
89
73
  bundle=False,
90
74
  **kwargs,
@@ -102,10 +86,10 @@ def add_panel(
102
86
  Name for the panel
103
87
  source : str or Path
104
88
  Source file (PNG, JPG, SVG)
105
- position : tuple
106
- (x_mm, y_mm) position on canvas
107
- size : tuple
108
- (width_mm, height_mm) panel size
89
+ xy_mm : tuple
90
+ (x_mm, y_mm) position on canvas in millimeters
91
+ size_mm : tuple
92
+ (width_mm, height_mm) panel size in millimeters
109
93
  label : str
110
94
  Panel label (A, B, C...)
111
95
  bundle : bool
@@ -117,8 +101,8 @@ def add_panel(
117
101
 
118
102
  source = Path(source)
119
103
  panel_properties = {
120
- "position": {"x_mm": position[0], "y_mm": position[1]},
121
- "size": {"width_mm": size[0], "height_mm": size[1]},
104
+ "position": {"x_mm": xy_mm[0], "y_mm": xy_mm[1]},
105
+ "size": {"width_mm": size_mm[0], "height_mm": size_mm[1]},
122
106
  **kwargs,
123
107
  }
124
108
  if label:
@@ -147,32 +131,33 @@ def add_panel(
147
131
 
148
132
 
149
133
  # =============================================================================
150
- # .figz Bundle Support
134
+ # .figure Bundle Support
151
135
  # =============================================================================
152
136
 
153
- def save_figz(
137
+
138
+ def save_figure(
154
139
  panels,
155
140
  path,
156
141
  spec=None,
157
142
  as_zip=None,
158
143
  ):
159
144
  """
160
- Save panels as a .figz publication figure bundle.
145
+ Save panels as a .figure publication figure bundle.
161
146
 
162
147
  Parameters
163
148
  ----------
164
149
  panels : dict
165
- Dictionary mapping panel IDs to .pltz bundle paths or data.
166
- Example: {"A": "timecourse.pltz.d", "B": "barplot.pltz.d"}
150
+ Dictionary mapping panel IDs to .plot bundle paths or data.
151
+ Example: {"A": "timecourse.plot", "B": "barplot.plot"}
167
152
  path : str or Path
168
- Output path (e.g., "Figure1.figz" or "Figure1.figz.d").
169
- - Path ending with ".figz" creates ZIP archive (default behavior)
170
- - Path ending with ".figz.d" creates directory bundle
153
+ Output path (e.g., "Figure1.figure.zip" or "Figure1.figure").
154
+ - Path ending with ".zip" creates ZIP archive
155
+ - Path ending with ".figure" creates directory bundle
171
156
  spec : dict, optional
172
157
  Figure specification. Auto-generated if None.
173
158
  as_zip : bool, optional
174
159
  If True, save as ZIP archive. If False, save as directory.
175
- Default: auto-detect from path (ZIP for .figz, directory for .figz.d).
160
+ Default: auto-detect from path.
176
161
 
177
162
  Returns
178
163
  -------
@@ -181,24 +166,25 @@ def save_figz(
181
166
 
182
167
  Examples
183
168
  --------
184
- >>> import scitex.fig as sfig
169
+ >>> import scitex.canvas as sfig
185
170
  >>> panels = {
186
- ... "A": "timecourse.pltz.d",
187
- ... "B": "barplot.pltz.d"
171
+ ... "A": "timecourse.plot",
172
+ ... "B": "barplot.plot"
188
173
  ... }
189
- >>> sfig.save_figz(panels, "Figure1.figz") # Creates ZIP
190
- >>> sfig.save_figz(panels, "Figure1.figz.d") # Creates directory
174
+ >>> sfig.save_figure(panels, "Figure1.figure.zip") # Creates ZIP
175
+ >>> sfig.save_figure(panels, "Figure1.figure") # Creates directory
191
176
  """
192
- from pathlib import Path
193
177
  import shutil
194
- from scitex.io.bundle import save, BundleType
178
+ from pathlib import Path
179
+
180
+ from scitex.io.bundle import BundleType, save
195
181
 
196
182
  p = Path(path)
197
183
  spath = str(path)
198
184
 
199
185
  # Auto-detect as_zip from path suffix if not specified
200
186
  if as_zip is None:
201
- as_zip = not spath.endswith(".d")
187
+ as_zip = spath.endswith(".zip")
202
188
 
203
189
  # Auto-generate spec if not provided
204
190
  if spec is None:
@@ -206,28 +192,28 @@ def save_figz(
206
192
 
207
193
  # Build bundle data - pass source paths directly for file copying
208
194
  bundle_data = {
209
- 'spec': spec,
210
- 'plots': {},
195
+ "spec": spec,
196
+ "plots": {},
211
197
  }
212
198
 
213
199
  # Pass source paths directly (not loaded data) to preserve all files
214
- for panel_id, pltz_source in panels.items():
215
- pltz_path = Path(pltz_source)
216
- if pltz_path.exists():
200
+ for panel_id, plot_source in panels.items():
201
+ plot_path = Path(plot_source)
202
+ if plot_path.exists():
217
203
  # Store source path for direct copying
218
- bundle_data['plots'][panel_id] = str(pltz_path)
204
+ bundle_data["plots"][panel_id] = str(plot_path)
219
205
 
220
- return save(bundle_data, p, bundle_type=BundleType.FIGZ, as_zip=as_zip)
206
+ return save(bundle_data, p, bundle_type=BundleType.FIGURE, as_zip=as_zip)
221
207
 
222
208
 
223
- def load_figz(path):
209
+ def load_figure(path):
224
210
  """
225
- Load a .figz bundle.
211
+ Load a .figure bundle.
226
212
 
227
213
  Parameters
228
214
  ----------
229
215
  path : str or Path
230
- Path to .figz bundle (directory or ZIP).
216
+ Path to .figure bundle (directory or ZIP).
231
217
 
232
218
  Returns
233
219
  -------
@@ -238,7 +224,7 @@ def load_figz(path):
238
224
 
239
225
  Examples
240
226
  --------
241
- >>> figure = scitex.fig.load_figz("Figure1.figz.d")
227
+ >>> figure = scitex.canvas.load_figure("Figure1.figure")
242
228
  >>> print(figure['spec']['figure']['title'])
243
229
  >>> panel_a = figure['panels']['A']
244
230
  >>> print(panel_a['spec'], panel_a['data'])
@@ -247,19 +233,19 @@ def load_figz(path):
247
233
 
248
234
  bundle = load(path)
249
235
 
250
- if bundle['type'] != 'figz':
251
- raise ValueError(f"Not a .figz bundle: {path}")
236
+ if bundle["type"] != "figure":
237
+ raise ValueError(f"Not a .figure bundle: {path}")
252
238
 
253
239
  result = {
254
- 'spec': bundle.get('spec', {}),
255
- 'panels': {},
240
+ "spec": bundle.get("spec", {}),
241
+ "panels": {},
256
242
  }
257
243
 
258
244
  # Return spec and data for each panel (reconstruction is optional)
259
- for panel_id, plot_bundle in bundle.get('plots', {}).items():
260
- result['panels'][panel_id] = {
261
- 'spec': plot_bundle.get('spec', {}),
262
- 'data': plot_bundle.get('data'),
245
+ for panel_id, plot_bundle in bundle.get("plots", {}).items():
246
+ result["panels"][panel_id] = {
247
+ "spec": plot_bundle.get("spec", {}),
248
+ "data": plot_bundle.get("data"),
263
249
  }
264
250
 
265
251
  return result
@@ -270,17 +256,17 @@ def _generate_figure_spec(panels):
270
256
  from pathlib import Path
271
257
 
272
258
  spec = {
273
- 'schema': {'name': 'scitex.fig.figure', 'version': '1.0.0'},
274
- 'figure': {
275
- 'id': 'figure',
276
- 'title': '',
277
- 'caption': '',
278
- 'styles': {
279
- 'size': {'width_mm': 180, 'height_mm': 120},
280
- 'background': '#ffffff',
259
+ "schema": {"name": "scitex.canvas.figure", "version": "1.0.0"},
260
+ "figure": {
261
+ "id": "figure",
262
+ "title": "",
263
+ "caption": "",
264
+ "styles": {
265
+ "size": {"width_mm": 180, "height_mm": 120},
266
+ "background": "#ffffff",
281
267
  },
282
268
  },
283
- 'panels': [],
269
+ "panels": [],
284
270
  }
285
271
 
286
272
  # Auto-layout panels
@@ -305,15 +291,17 @@ def _generate_figure_spec(panels):
305
291
  x = margin + col * (panel_w + margin)
306
292
  y = margin + row * (panel_h + margin)
307
293
 
308
- # Note: save_bundle uses panel_id for the directory name (e.g., A.pltz.d)
309
- spec['panels'].append({
310
- 'id': panel_id,
311
- 'label': panel_id,
312
- 'caption': '',
313
- 'plot': f"{panel_id}.pltz.d",
314
- 'position': {'x_mm': x, 'y_mm': y},
315
- 'size': {'width_mm': panel_w, 'height_mm': panel_h},
316
- })
294
+ # Note: save_bundle uses panel_id for the directory name (e.g., A.plot)
295
+ spec["panels"].append(
296
+ {
297
+ "id": panel_id,
298
+ "label": panel_id,
299
+ "caption": "",
300
+ "plot": f"{panel_id}.plot",
301
+ "position": {"x_mm": x, "y_mm": y},
302
+ "size": {"width_mm": panel_w, "height_mm": panel_h},
303
+ }
304
+ )
317
305
 
318
306
  return spec
319
307
 
@@ -344,9 +332,9 @@ __all__ = [
344
332
  "verify_data",
345
333
  # Editor
346
334
  "edit",
347
- # .figz bundle
348
- "save_figz",
349
- "load_figz",
335
+ # .figure bundle
336
+ "save_figure",
337
+ "load_figure",
350
338
  ]
351
339
 
352
340
  # EOF
@@ -0,0 +1,372 @@
1
+ #!/usr/bin/env python3
2
+ # Timestamp: 2026-01-08
3
+ # File: src/scitex/canvas/_mcp_handlers.py
4
+ # ----------------------------------------
5
+
6
+ """
7
+ MCP Handler implementations for SciTeX canvas module.
8
+
9
+ Provides async handlers for multi-panel figure composition.
10
+ """
11
+
12
+ from __future__ import annotations
13
+
14
+ import asyncio
15
+ from typing import Optional
16
+
17
+
18
+ async def create_canvas_handler(
19
+ parent_dir: str,
20
+ canvas_name: str,
21
+ width_mm: float = 180,
22
+ height_mm: float = 120,
23
+ ) -> dict:
24
+ """
25
+ Create a new canvas workspace.
26
+
27
+ Parameters
28
+ ----------
29
+ parent_dir : str
30
+ Parent directory for canvas
31
+ canvas_name : str
32
+ Name for the canvas
33
+ width_mm : float
34
+ Canvas width in mm
35
+ height_mm : float
36
+ Canvas height in mm
37
+
38
+ Returns
39
+ -------
40
+ dict
41
+ Success status and canvas info
42
+ """
43
+ try:
44
+ import scitex.canvas as canvas_module
45
+
46
+ loop = asyncio.get_event_loop()
47
+ await loop.run_in_executor(
48
+ None,
49
+ lambda: canvas_module.create_canvas(
50
+ parent_dir,
51
+ canvas_name,
52
+ ),
53
+ )
54
+
55
+ canvas_path = canvas_module.get_canvas_path(parent_dir, canvas_name)
56
+
57
+ return {
58
+ "success": True,
59
+ "canvas_name": canvas_name,
60
+ "canvas_path": str(canvas_path),
61
+ "size_mm": {"width": width_mm, "height": height_mm},
62
+ "message": f"Created canvas '{canvas_name}' at {canvas_path}",
63
+ }
64
+ except Exception as e:
65
+ return {
66
+ "success": False,
67
+ "error": str(e),
68
+ }
69
+
70
+
71
+ async def add_panel_handler(
72
+ parent_dir: str,
73
+ canvas_name: str,
74
+ panel_name: str,
75
+ source: str,
76
+ x_mm: float = 0,
77
+ y_mm: float = 0,
78
+ width_mm: float = 50,
79
+ height_mm: float = 50,
80
+ label: Optional[str] = None,
81
+ ) -> dict:
82
+ """
83
+ Add a panel to a canvas.
84
+
85
+ Parameters
86
+ ----------
87
+ parent_dir : str
88
+ Parent directory containing canvas
89
+ canvas_name : str
90
+ Canvas name
91
+ panel_name : str
92
+ Name for this panel
93
+ source : str
94
+ Path to source file
95
+ x_mm, y_mm : float
96
+ Position in mm
97
+ width_mm, height_mm : float
98
+ Size in mm
99
+ label : str, optional
100
+ Panel label (A, B, C...)
101
+
102
+ Returns
103
+ -------
104
+ dict
105
+ Success status and panel info
106
+ """
107
+ try:
108
+ import scitex.canvas as canvas_module
109
+
110
+ loop = asyncio.get_event_loop()
111
+ await loop.run_in_executor(
112
+ None,
113
+ lambda: canvas_module.add_panel(
114
+ parent_dir=parent_dir,
115
+ canvas_name=canvas_name,
116
+ panel_name=panel_name,
117
+ source=source,
118
+ xy_mm=(x_mm, y_mm),
119
+ size_mm=(width_mm, height_mm),
120
+ label=label or "",
121
+ ),
122
+ )
123
+
124
+ return {
125
+ "success": True,
126
+ "canvas_name": canvas_name,
127
+ "panel_name": panel_name,
128
+ "source": source,
129
+ "position_mm": {"x": x_mm, "y": y_mm},
130
+ "size_mm": {"width": width_mm, "height": height_mm},
131
+ "label": label,
132
+ "message": f"Added panel '{panel_name}' to canvas '{canvas_name}'",
133
+ }
134
+ except Exception as e:
135
+ return {
136
+ "success": False,
137
+ "error": str(e),
138
+ }
139
+
140
+
141
+ async def list_panels_handler(
142
+ parent_dir: str,
143
+ canvas_name: str,
144
+ ) -> dict:
145
+ """
146
+ List all panels in a canvas.
147
+
148
+ Parameters
149
+ ----------
150
+ parent_dir : str
151
+ Parent directory
152
+ canvas_name : str
153
+ Canvas name
154
+
155
+ Returns
156
+ -------
157
+ dict
158
+ Success status and panel list
159
+ """
160
+ try:
161
+ import scitex.canvas as canvas_module
162
+
163
+ loop = asyncio.get_event_loop()
164
+ panels = await loop.run_in_executor(
165
+ None,
166
+ lambda: canvas_module.list_panels(parent_dir, canvas_name),
167
+ )
168
+
169
+ return {
170
+ "success": True,
171
+ "canvas_name": canvas_name,
172
+ "count": len(panels) if panels else 0,
173
+ "panels": panels or [],
174
+ }
175
+ except Exception as e:
176
+ return {
177
+ "success": False,
178
+ "error": str(e),
179
+ }
180
+
181
+
182
+ async def remove_panel_handler(
183
+ parent_dir: str,
184
+ canvas_name: str,
185
+ panel_name: str,
186
+ ) -> dict:
187
+ """
188
+ Remove a panel from a canvas.
189
+
190
+ Parameters
191
+ ----------
192
+ parent_dir : str
193
+ Parent directory
194
+ canvas_name : str
195
+ Canvas name
196
+ panel_name : str
197
+ Panel to remove
198
+
199
+ Returns
200
+ -------
201
+ dict
202
+ Success status
203
+ """
204
+ try:
205
+ import scitex.canvas as canvas_module
206
+
207
+ loop = asyncio.get_event_loop()
208
+ await loop.run_in_executor(
209
+ None,
210
+ lambda: canvas_module.remove_panel(parent_dir, canvas_name, panel_name),
211
+ )
212
+
213
+ return {
214
+ "success": True,
215
+ "canvas_name": canvas_name,
216
+ "panel_name": panel_name,
217
+ "message": f"Removed panel '{panel_name}' from canvas '{canvas_name}'",
218
+ }
219
+ except Exception as e:
220
+ return {
221
+ "success": False,
222
+ "error": str(e),
223
+ }
224
+
225
+
226
+ async def export_canvas_handler(
227
+ parent_dir: str,
228
+ canvas_name: str,
229
+ output_path: Optional[str] = None,
230
+ format: Optional[str] = None,
231
+ dpi: int = 300,
232
+ ) -> dict:
233
+ """
234
+ Export canvas to file.
235
+
236
+ Parameters
237
+ ----------
238
+ parent_dir : str
239
+ Parent directory
240
+ canvas_name : str
241
+ Canvas name
242
+ output_path : str, optional
243
+ Output file path
244
+ format : str, optional
245
+ Output format (png, pdf, svg)
246
+ dpi : int
247
+ Output DPI
248
+
249
+ Returns
250
+ -------
251
+ dict
252
+ Success status and output path
253
+ """
254
+ try:
255
+ from pathlib import Path
256
+
257
+ import scitex.canvas as canvas_module
258
+
259
+ # Build output path if not provided
260
+ if output_path is None:
261
+ canvas_path = canvas_module.get_canvas_path(parent_dir, canvas_name)
262
+ fmt = format or "png"
263
+ output_path = str(Path(canvas_path) / "exports" / f"{canvas_name}.{fmt}")
264
+
265
+ loop = asyncio.get_event_loop()
266
+ result_path = await loop.run_in_executor(
267
+ None,
268
+ lambda: canvas_module.export_canvas(
269
+ parent_dir,
270
+ canvas_name,
271
+ output_path,
272
+ ),
273
+ )
274
+
275
+ return {
276
+ "success": True,
277
+ "canvas_name": canvas_name,
278
+ "output_path": str(result_path) if result_path else output_path,
279
+ "format": format or Path(output_path).suffix.lstrip("."),
280
+ "dpi": dpi,
281
+ "message": f"Exported canvas to {output_path}",
282
+ }
283
+ except Exception as e:
284
+ return {
285
+ "success": False,
286
+ "error": str(e),
287
+ }
288
+
289
+
290
+ async def list_canvases_handler(parent_dir: str) -> dict:
291
+ """
292
+ List all canvases in a directory.
293
+
294
+ Parameters
295
+ ----------
296
+ parent_dir : str
297
+ Directory to search
298
+
299
+ Returns
300
+ -------
301
+ dict
302
+ Success status and canvas list
303
+ """
304
+ try:
305
+ import scitex.canvas as canvas_module
306
+
307
+ loop = asyncio.get_event_loop()
308
+ canvases = await loop.run_in_executor(
309
+ None,
310
+ lambda: canvas_module.list_canvases(parent_dir),
311
+ )
312
+
313
+ return {
314
+ "success": True,
315
+ "parent_dir": parent_dir,
316
+ "count": len(canvases) if canvases else 0,
317
+ "canvases": canvases or [],
318
+ }
319
+ except Exception as e:
320
+ return {
321
+ "success": False,
322
+ "error": str(e),
323
+ }
324
+
325
+
326
+ async def canvas_exists_handler(
327
+ parent_dir: str,
328
+ canvas_name: str,
329
+ ) -> dict:
330
+ """
331
+ Check if a canvas exists.
332
+
333
+ Parameters
334
+ ----------
335
+ parent_dir : str
336
+ Parent directory
337
+ canvas_name : str
338
+ Canvas name
339
+
340
+ Returns
341
+ -------
342
+ dict
343
+ Success status and existence flag
344
+ """
345
+ try:
346
+ import scitex.canvas as canvas_module
347
+
348
+ exists = canvas_module.canvas_exists(parent_dir, canvas_name)
349
+
350
+ return {
351
+ "success": True,
352
+ "canvas_name": canvas_name,
353
+ "exists": exists,
354
+ }
355
+ except Exception as e:
356
+ return {
357
+ "success": False,
358
+ "error": str(e),
359
+ }
360
+
361
+
362
+ __all__ = [
363
+ "create_canvas_handler",
364
+ "add_panel_handler",
365
+ "list_panels_handler",
366
+ "remove_panel_handler",
367
+ "export_canvas_handler",
368
+ "list_canvases_handler",
369
+ "canvas_exists_handler",
370
+ ]
371
+
372
+ # EOF