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,371 +0,0 @@
1
- /**
2
- * Overlay Rendering
3
- * Handles SVG overlay for element highlighting and debug visualization
4
- */
5
-
6
- // ============================================================================
7
- // Main Overlay Update
8
- // ============================================================================
9
- function updateOverlay() {
10
- const overlay = document.getElementById('hover-overlay');
11
- // Find the visible preview element (SVG wrapper or img)
12
- const svgWrapper = document.getElementById('preview-svg-wrapper');
13
- const imgEl = document.getElementById('preview');
14
-
15
- let targetEl = null;
16
- if (svgWrapper) {
17
- targetEl = svgWrapper.querySelector('svg') || svgWrapper;
18
- } else if (imgEl && imgEl.offsetWidth > 0) {
19
- targetEl = imgEl;
20
- }
21
-
22
- if (!targetEl) return;
23
-
24
- const rect = targetEl.getBoundingClientRect();
25
- if (rect.width === 0 || rect.height === 0) return;
26
-
27
- // Guard against zero imgSize (can cause Infinity scale)
28
- if (!imgSize || !imgSize.width || !imgSize.height || imgSize.width === 0 || imgSize.height === 0) {
29
- return;
30
- }
31
-
32
- overlay.setAttribute('width', rect.width);
33
- overlay.setAttribute('height', rect.height);
34
- overlay.style.width = rect.width + 'px';
35
- overlay.style.height = rect.height + 'px';
36
-
37
- // Position overlay over the target element
38
- const containerRect = document.getElementById('preview-container').getBoundingClientRect();
39
- overlay.style.left = (rect.left - containerRect.left) + 'px';
40
- overlay.style.top = (rect.top - containerRect.top) + 'px';
41
-
42
- const scaleX = rect.width / imgSize.width;
43
- const scaleY = rect.height / imgSize.height;
44
-
45
- let svg = '';
46
-
47
- // Debug mode: draw ALL bboxes
48
- if (debugMode) {
49
- svg += drawDebugBboxes(scaleX, scaleY);
50
- }
51
-
52
- function drawElement(elementName, type) {
53
- const bbox = elementBboxes[elementName];
54
- if (!bbox) return '';
55
-
56
- const elementType = bbox.element_type || '';
57
- const hasPoints = bbox.points && bbox.points.length > 0;
58
-
59
- // Lines - draw as path
60
- if ((elementType === 'line' || elementName.includes('trace_')) && hasPoints) {
61
- return drawTracePath(bbox, scaleX, scaleY, type);
62
- }
63
- // Scatter - draw as circles
64
- else if (elementType === 'scatter' && hasPoints) {
65
- return drawScatterPoints(bbox, scaleX, scaleY, type);
66
- }
67
- // Default - draw bbox rectangle
68
- else {
69
- const rectClass = type === 'hover' ? 'hover-rect' : 'selected-rect';
70
- const labelClass = type === 'hover' ? 'hover-label' : 'selected-label';
71
- const x = bbox.x0 * scaleX - 2;
72
- const y = bbox.y0 * scaleY - 2;
73
- const w = (bbox.x1 - bbox.x0) * scaleX + 4;
74
- const h = (bbox.y1 - bbox.y0) * scaleY + 4;
75
- return `<rect class="${rectClass}" x="${x}" y="${y}" width="${w}" height="${h}" rx="2"/>` +
76
- `<text class="${labelClass}" x="${x}" y="${y - 4}">${bbox.label || elementName}</text>`;
77
- }
78
- }
79
-
80
- if (hoveredElement && hoveredElement !== selectedElement) {
81
- svg += drawElement(hoveredElement, 'hover');
82
- }
83
-
84
- if (selectedElement) {
85
- svg += drawElement(selectedElement, 'selected');
86
- }
87
-
88
- overlay.innerHTML = svg;
89
- }
90
-
91
- // ============================================================================
92
- // Draw Path/Line Elements
93
- // ============================================================================
94
- function drawTracePath(bbox, scaleX, scaleY, type) {
95
- if (!Array.isArray(bbox.points) || bbox.points.length < 2) return '';
96
-
97
- const points = bbox.points.filter(pt => Array.isArray(pt) && pt.length >= 2);
98
- if (points.length < 2) return '';
99
-
100
- let pathD = `M ${points[0][0] * scaleX} ${points[0][1] * scaleY}`;
101
- for (let i = 1; i < points.length; i++) {
102
- pathD += ` L ${points[i][0] * scaleX} ${points[i][1] * scaleY}`;
103
- }
104
-
105
- const className = type === 'hover' ? 'hover-path' : 'selected-path';
106
- const labelX = points[0][0] * scaleX;
107
- const labelY = points[0][1] * scaleY - 8;
108
- const labelClass = type === 'hover' ? 'hover-label' : 'selected-label';
109
-
110
- return `<path class="${className}" d="${pathD}"/>` +
111
- `<text class="${labelClass}" x="${labelX}" y="${labelY}">${bbox.label || ''}</text>`;
112
- }
113
-
114
- // ============================================================================
115
- // Draw Scatter Points
116
- // ============================================================================
117
- function drawScatterPoints(bbox, scaleX, scaleY, type) {
118
- // Draw scatter points as circles
119
- if (!Array.isArray(bbox.points) || bbox.points.length === 0) return '';
120
-
121
- const className = type === 'hover' ? 'hover-scatter' : 'selected-scatter';
122
- const labelClass = type === 'hover' ? 'hover-label' : 'selected-label';
123
- const radius = 4;
124
-
125
- let svg = '';
126
- for (const pt of bbox.points) {
127
- if (!Array.isArray(pt) || pt.length < 2) continue;
128
- const [x, y] = pt;
129
- svg += `<circle class="${className}" cx="${x * scaleX}" cy="${y * scaleY}" r="${radius}"/>`;
130
- }
131
-
132
- // Add label near first point
133
- const validPoints = bbox.points.filter(pt => Array.isArray(pt) && pt.length >= 2);
134
- if (validPoints.length > 0) {
135
- const labelX = validPoints[0][0] * scaleX;
136
- const labelY = validPoints[0][1] * scaleY - 10;
137
- svg += `<text class="${labelClass}" x="${labelX}" y="${labelY}">${bbox.label || ''}</text>`;
138
- }
139
-
140
- return svg;
141
- }
142
-
143
- // ============================================================================
144
- // Debug Visualization
145
- // ============================================================================
146
- function drawDebugBboxes(scaleX, scaleY) {
147
- let svg = '';
148
- let count = 0;
149
-
150
- for (const [name, bbox] of Object.entries(elementBboxes)) {
151
- if (name === '_meta') continue;
152
-
153
- count++;
154
- const hasPoints = bbox.points && bbox.points.length > 0;
155
- const elementType = bbox.element_type || '';
156
-
157
- // Choose color based on element type
158
- let rectClass = 'debug-rect';
159
- if (name.includes('trace_') || elementType === 'line') {
160
- rectClass = 'debug-rect-trace';
161
- } else if (name.includes('legend')) {
162
- rectClass = 'debug-rect-legend';
163
- }
164
-
165
- // Draw bbox rectangle
166
- const x = bbox.x0 * scaleX;
167
- const y = bbox.y0 * scaleY;
168
- const w = (bbox.x1 - bbox.x0) * scaleX;
169
- const h = (bbox.y1 - bbox.y0) * scaleY;
170
-
171
- svg += `<rect class="${rectClass}" x="${x}" y="${y}" width="${w}" height="${h}"/>`;
172
- svg += `<text class="debug-label" x="${x + 2}" y="${y + 10}">${name}</text>`;
173
-
174
- // Draw path points if available
175
- if (hasPoints && bbox.points.length > 1) {
176
- let pathD = `M ${bbox.points[0][0] * scaleX} ${bbox.points[0][1] * scaleY}`;
177
- for (let i = 1; i < bbox.points.length; i++) {
178
- const pt = bbox.points[i];
179
- if (pt && pt.length >= 2) {
180
- pathD += ` L ${pt[0] * scaleX} ${pt[1] * scaleY}`;
181
- }
182
- }
183
- svg += `<path class="debug-path" d="${pathD}"/>`;
184
- }
185
- }
186
-
187
- return svg;
188
- }
189
-
190
- function toggleDebugMode() {
191
- debugMode = !debugMode;
192
- const btn = document.getElementById('debug-toggle-btn');
193
- if (btn) {
194
- btn.classList.toggle('active', debugMode);
195
- btn.textContent = debugMode ? 'Hide Hit Areas' : 'Show Hit Areas';
196
- }
197
- updateOverlay();
198
- }
199
-
200
- // ============================================================================
201
- // Panel Overlay Update (for multi-panel canvas)
202
- // ============================================================================
203
- function updatePanelOverlay(overlay, bboxes, imgSizePanel, displayWidth, displayHeight, hovered, selected, img) {
204
- if (!overlay) return;
205
-
206
- overlay.innerHTML = '';
207
-
208
- // Calculate actual rendered dimensions accounting for object-fit: contain
209
- let scaleX, scaleY, offsetX = 0, offsetY = 0;
210
-
211
- if (img && img.naturalWidth && img.naturalHeight) {
212
- const dims = getObjectFitContainDimensions(img);
213
- scaleX = dims.displayWidth / imgSizePanel.width;
214
- scaleY = dims.displayHeight / imgSizePanel.height;
215
- offsetX = dims.offsetX;
216
- offsetY = dims.offsetY;
217
-
218
- // Use container dimensions for the overlay size
219
- overlay.setAttribute('width', img.clientWidth);
220
- overlay.setAttribute('height', img.clientHeight);
221
- } else {
222
- // Fallback for backward compatibility
223
- scaleX = displayWidth / imgSizePanel.width;
224
- scaleY = displayHeight / imgSizePanel.height;
225
- overlay.setAttribute('width', displayWidth);
226
- overlay.setAttribute('height', displayHeight);
227
- }
228
-
229
- let svg = '';
230
-
231
- // Debug mode: draw all bboxes (with offset for object-fit:contain letterboxing)
232
- if (panelDebugMode) {
233
- svg += drawPanelDebugBboxes(bboxes, scaleX, scaleY, offsetX, offsetY);
234
- }
235
-
236
- function drawPanelElement(elementName, type) {
237
- const bbox = bboxes[elementName];
238
- if (!bbox) return '';
239
-
240
- const elementType = bbox.element_type || '';
241
- const hasPoints = bbox.points && bbox.points.length > 0;
242
-
243
- // Lines - draw as path (with offset)
244
- if ((elementType === 'line' || elementName.includes('trace_')) && hasPoints) {
245
- const points = bbox.points.filter(pt => Array.isArray(pt) && pt.length >= 2);
246
- if (points.length < 2) return '';
247
-
248
- let pathD = `M ${points[0][0] * scaleX + offsetX} ${points[0][1] * scaleY + offsetY}`;
249
- for (let i = 1; i < points.length; i++) {
250
- pathD += ` L ${points[i][0] * scaleX + offsetX} ${points[i][1] * scaleY + offsetY}`;
251
- }
252
-
253
- const className = type === 'hover' ? 'hover-path' : 'selected-path';
254
- return `<path class="${className}" d="${pathD}"/>`;
255
- }
256
- // Scatter - draw as circles (with offset)
257
- else if (elementType === 'scatter' && hasPoints) {
258
- const className = type === 'hover' ? 'hover-scatter' : 'selected-scatter';
259
- let circles = '';
260
- for (const pt of bbox.points) {
261
- if (!Array.isArray(pt) || pt.length < 2) continue;
262
- const [x, y] = pt;
263
- circles += `<circle class="${className}" cx="${x * scaleX + offsetX}" cy="${y * scaleY + offsetY}" r="3"/>`;
264
- }
265
- return circles;
266
- }
267
- // Default - draw bbox rectangle (with offset)
268
- else {
269
- const rectClass = type === 'hover' ? 'hover-rect' : 'selected-rect';
270
- const x = bbox.x0 * scaleX + offsetX;
271
- const y = bbox.y0 * scaleY + offsetY;
272
- const w = (bbox.x1 - bbox.x0) * scaleX;
273
- const h = (bbox.y1 - bbox.y0) * scaleY;
274
- return `<rect class="${rectClass}" x="${x}" y="${y}" width="${w}" height="${h}" rx="1"/>`;
275
- }
276
- }
277
-
278
- if (hovered && hovered !== selected) {
279
- svg += drawPanelElement(hovered, 'hover');
280
- }
281
-
282
- if (selected) {
283
- svg += drawPanelElement(selected, 'selected');
284
- }
285
-
286
- overlay.innerHTML = svg;
287
- }
288
-
289
- function drawPanelDebugBboxes(bboxes, scaleX, scaleY, offsetX, offsetY) {
290
- let svg = '';
291
-
292
- // Default offset to 0 if not provided
293
- offsetX = offsetX || 0;
294
- offsetY = offsetY || 0;
295
-
296
- for (const [name, bbox] of Object.entries(bboxes)) {
297
- if (name === '_meta') continue;
298
-
299
- const hasPoints = bbox.points && bbox.points.length > 0;
300
- const elementType = bbox.element_type || '';
301
-
302
- // Choose color based on element type
303
- let rectClass = 'debug-rect';
304
- if (name.includes('trace_') || elementType === 'line') {
305
- rectClass = 'debug-rect-trace';
306
- } else if (name.includes('legend')) {
307
- rectClass = 'debug-rect-legend';
308
- }
309
-
310
- // Draw bbox rectangle (with offset for object-fit:contain letterboxing)
311
- const x = bbox.x0 * scaleX + offsetX;
312
- const y = bbox.y0 * scaleY + offsetY;
313
- const w = (bbox.x1 - bbox.x0) * scaleX;
314
- const h = (bbox.y1 - bbox.y0) * scaleY;
315
-
316
- svg += `<rect class="${rectClass}" x="${x}" y="${y}" width="${w}" height="${h}"/>`;
317
-
318
- // Draw short label (truncated for small panels)
319
- const shortName = name.length > 15 ? name.substring(0, 12) + '...' : name;
320
- svg += `<text class="debug-label" x="${x + 2}" y="${y + 8}" font-size="8">${shortName}</text>`;
321
-
322
- // Draw path points if available (with offset)
323
- if (hasPoints && bbox.points.length > 1) {
324
- let pathD = `M ${bbox.points[0][0] * scaleX + offsetX} ${bbox.points[0][1] * scaleY + offsetY}`;
325
- for (let i = 1; i < bbox.points.length; i++) {
326
- const pt = bbox.points[i];
327
- if (pt && pt.length >= 2) {
328
- pathD += ` L ${pt[0] * scaleX + offsetX} ${pt[1] * scaleY + offsetY}`;
329
- }
330
- }
331
- svg += `<path class="debug-path" d="${pathD}" stroke-width="0.5"/>`;
332
- }
333
- }
334
-
335
- return svg;
336
- }
337
-
338
- function togglePanelDebugMode() {
339
- panelDebugMode = !panelDebugMode;
340
- const btn = document.getElementById('panel-debug-toggle-btn');
341
- if (btn) {
342
- btn.classList.toggle('active', panelDebugMode);
343
- btn.textContent = panelDebugMode ? 'Hide Panel Hit Areas' : 'Show Panel Hit Areas';
344
- }
345
-
346
- // Redraw all panel overlays
347
- redrawAllPanelOverlays();
348
- }
349
-
350
- function redrawAllPanelOverlays() {
351
- document.querySelectorAll('.panel-canvas-item').forEach((item, idx) => {
352
- const panelName = item.dataset.panelName;
353
- const overlay = item.querySelector('.panel-card-overlay');
354
- const img = item.querySelector('img');
355
- const panelCache = panelBboxesCache[panelName];
356
-
357
- if (overlay && img && panelCache) {
358
- const rect = img.getBoundingClientRect();
359
- updatePanelOverlay(
360
- overlay,
361
- panelCache.bboxes,
362
- panelCache.imgSize,
363
- rect.width,
364
- rect.height,
365
- panelHoveredElement,
366
- selectedElement,
367
- img
368
- );
369
- }
370
- });
371
- }
@@ -1,293 +0,0 @@
1
- /**
2
- * Preview Management
3
- * Handles preview loading, panel navigation, and grid view
4
- */
5
-
6
- // ============================================================================
7
- // Initial Preview Loading
8
- // ============================================================================
9
- async function loadInitialPreview() {
10
- setStatus('Loading preview...', false);
11
- try {
12
- const resp = await fetch('/preview');
13
- const data = await resp.json();
14
-
15
- console.log('=== PREVIEW DATA RECEIVED ===');
16
- console.log('format:', data.format);
17
- console.log('img_size:', data.img_size);
18
- console.log('bboxes keys:', Object.keys(data.bboxes || {}));
19
-
20
- const previewContainer = document.getElementById('preview-container');
21
- const img = document.getElementById('preview');
22
-
23
- if (data.format === 'svg' && data.svg) {
24
- // Handle SVG: replace img with inline SVG
25
- const svgWrapper = document.createElement('div');
26
- svgWrapper.id = 'preview-svg-wrapper';
27
- svgWrapper.innerHTML = data.svg;
28
- svgWrapper.style.width = '100%';
29
- svgWrapper.style.maxHeight = '70vh';
30
-
31
- // Find the SVG element and set styles
32
- const svgEl = svgWrapper.querySelector('svg');
33
- if (svgEl) {
34
- svgEl.style.width = '100%';
35
- svgEl.style.height = 'auto';
36
- svgEl.style.maxHeight = '70vh';
37
- svgEl.id = 'preview'; // Keep same ID for event handlers
38
- }
39
-
40
- img.style.display = 'none';
41
- const existingWrapper = document.getElementById('preview-svg-wrapper');
42
- if (existingWrapper) existingWrapper.remove();
43
- previewContainer.appendChild(svgWrapper);
44
- } else if (data.image) {
45
- // Handle PNG: show as base64 image
46
- img.src = 'data:image/png;base64,' + data.image;
47
- img.style.display = 'block';
48
- const existingWrapper = document.getElementById('preview-svg-wrapper');
49
- if (existingWrapper) existingWrapper.remove();
50
- }
51
-
52
- if (data.bboxes) {
53
- elementBboxes = data.bboxes;
54
- originalBboxes = JSON.parse(JSON.stringify(data.bboxes)); // Deep copy
55
- if (data.bboxes._meta) {
56
- schemaMeta = data.bboxes._meta;
57
- }
58
- }
59
- if (data.img_size) {
60
- imgSize = data.img_size;
61
- originalImgSize = {...data.img_size}; // Copy
62
- }
63
-
64
- isShowingOriginalPreview = true;
65
- updateOverlay();
66
- setStatus('Preview loaded', false);
67
-
68
- // Initialize hover system for the SVG if needed
69
- if (data.format === 'svg') {
70
- const svgWrapper = document.getElementById('preview-svg-wrapper');
71
- if (svgWrapper) {
72
- initHoverSystemForElement(svgWrapper.querySelector('svg'));
73
- }
74
- }
75
-
76
- // Draw debug bboxes if debug mode is on
77
- if (debugMode) {
78
- updateOverlay();
79
- }
80
-
81
- // Handle multi-panel figz bundles
82
- if (data.panel_info && data.panel_info.panels) {
83
- panelData = data.panel_info;
84
- currentPanelIndex = data.panel_info.current_index || 0;
85
- console.log('Multi-panel figz detected:', panelData.panels.length, 'panels');
86
- loadPanelGrid();
87
- }
88
-
89
- // Start auto-update AFTER initial preview is loaded
90
- setAutoUpdateInterval();
91
- } catch (e) {
92
- setStatus('Error loading preview: ' + e.message, true);
93
- console.error('Preview load error:', e);
94
- // Start auto-update even on error so the editor works
95
- setAutoUpdateInterval();
96
- }
97
- }
98
-
99
- // ============================================================================
100
- // Multi-Panel Grid Loading
101
- // ============================================================================
102
- async function loadPanelGrid() {
103
- if (!panelData || panelData.panels.length <= 1) {
104
- // Not a multi-panel bundle or only one panel
105
- document.getElementById('panel-grid-section').style.display = 'none';
106
- document.getElementById('preview-header').style.display = 'none';
107
- return;
108
- }
109
-
110
- console.log('Loading panel canvas for', panelData.panels.length, 'panels');
111
-
112
- // Hide single-panel preview completely for multi-panel bundles (unified canvas only)
113
- document.getElementById('preview-header').style.display = 'none';
114
- const previewWrapper = document.querySelector('.preview-wrapper');
115
- if (previewWrapper) {
116
- previewWrapper.style.display = 'none';
117
- }
118
-
119
- // Fetch all panel images with bboxes
120
- try {
121
- const resp = await fetch('/panels');
122
- const data = await resp.json();
123
-
124
- if (data.error) {
125
- console.error('Panel canvas error:', data.error);
126
- return;
127
- }
128
-
129
- const canvasEl = document.getElementById('panel-canvas');
130
- canvasEl.innerHTML = '';
131
-
132
- // Use figz layout to position panels as unified canvas (matching export)
133
- const hasLayout = data.layout && Object.keys(data.layout).length > 0;
134
-
135
- // Calculate scale factor: convert mm to pixels
136
- // Find total figure dimensions from layout
137
- let maxX = 0, maxY = 0;
138
- if (hasLayout) {
139
- Object.values(data.layout).forEach(l => {
140
- const right = (l.position?.x_mm || 0) + (l.size?.width_mm || 80);
141
- const bottom = (l.position?.y_mm || 0) + (l.size?.height_mm || 50);
142
- maxX = Math.max(maxX, right);
143
- maxY = Math.max(maxY, bottom);
144
- });
145
- }
146
-
147
- // Scale to fit canvas (max width ~700px for good display)
148
- const canvasMaxWidth = 700;
149
- const scale = hasLayout && maxX > 0 ? canvasMaxWidth / maxX : 3; // ~3px per mm fallback
150
- canvasScale = scale; // Store globally for drag conversions
151
-
152
- // Reset layout tracking
153
- panelLayoutMm = {};
154
- layoutModified = false;
155
-
156
- data.panels.forEach((panel, idx) => {
157
- // Store bboxes and imgSize in cache for interactive hover/click
158
- if (panel.bboxes && panel.img_size) {
159
- panelBboxesCache[panel.name] = {
160
- bboxes: panel.bboxes,
161
- imgSize: panel.img_size
162
- };
163
- }
164
-
165
- // Use figz layout for positioning (unified canvas like export)
166
- let pos, posMm;
167
- if (panel.layout && panel.layout.position && panel.layout.size) {
168
- const x_mm = panel.layout.position.x_mm || 0;
169
- const y_mm = panel.layout.position.y_mm || 0;
170
- const width_mm = panel.layout.size.width_mm || 80;
171
- const height_mm = panel.layout.size.height_mm || 50;
172
- pos = {
173
- x: x_mm * scale,
174
- y: y_mm * scale,
175
- width: width_mm * scale,
176
- height: height_mm * scale,
177
- };
178
- posMm = { x_mm, y_mm, width_mm, height_mm };
179
- } else {
180
- // Fallback grid layout if no figz layout
181
- const cols = Math.ceil(Math.sqrt(data.panels.length));
182
- const baseWidth = 220, baseHeight = 180, padding = 15;
183
- const col = idx % cols;
184
- const row = Math.floor(idx / cols);
185
- pos = {
186
- x: padding + col * (baseWidth + padding),
187
- y: padding + row * (baseHeight + padding),
188
- width: baseWidth,
189
- height: baseHeight,
190
- };
191
- // Convert to mm for fallback
192
- posMm = {
193
- x_mm: pos.x / scale,
194
- y_mm: pos.y / scale,
195
- width_mm: pos.width / scale,
196
- height_mm: pos.height / scale,
197
- };
198
- }
199
- panelPositions[panel.name] = pos;
200
- panelLayoutMm[panel.name] = posMm;
201
-
202
- const item = document.createElement('div');
203
- item.className = 'panel-canvas-item' + (idx === currentPanelIndex ? ' active' : '');
204
- item.dataset.panelIndex = idx;
205
- item.dataset.panelName = panel.name;
206
- item.style.left = pos.x + 'px';
207
- item.style.top = pos.y + 'px';
208
- item.style.width = pos.width + 'px';
209
- item.style.height = pos.height + 'px';
210
-
211
- if (panel.image) {
212
- item.innerHTML = `
213
- <span class="panel-canvas-label">${panel.name}</span>
214
- <span class="panel-position-indicator" id="pos-${panel.name}"></span>
215
- <div class="panel-drag-handle" title="Drag to move panel">⋮⋮</div>
216
- <div class="panel-card-container">
217
- <img src="data:image/png;base64,${panel.image}" alt="Panel ${panel.name}">
218
- <svg class="panel-card-overlay" id="panel-overlay-${idx}"></svg>
219
- </div>
220
- `;
221
- } else {
222
- item.innerHTML = `
223
- <span class="panel-canvas-label">${panel.name}</span>
224
- <span class="panel-position-indicator" id="pos-${panel.name}"></span>
225
- <div class="panel-drag-handle" title="Drag to move panel">⋮⋮</div>
226
- <div style="padding: 20px; color: var(--text-muted);">No preview</div>
227
- `;
228
- }
229
-
230
- // Add interactive event handlers (hover, click for element selection)
231
- // Note: initCanvasItemInteraction already calls initPanelDrag internally
232
- initCanvasItemInteraction(item, idx, panel.name);
233
-
234
- canvasEl.appendChild(item);
235
- });
236
-
237
- // Update canvas size to fit all panels (unified canvas)
238
- const canvasHeight = Math.max(...Object.values(panelPositions).map(p => p.y + p.height)) + 10;
239
- const canvasWidth = Math.max(...Object.values(panelPositions).map(p => p.x + p.width)) + 10;
240
- canvasEl.style.minHeight = Math.max(400, canvasHeight) + 'px';
241
- canvasEl.style.minWidth = canvasWidth + 'px';
242
-
243
- // Update panel indicator
244
- updatePanelIndicator();
245
-
246
- // Show unified canvas for multi-panel figures
247
- showingPanelGrid = true;
248
- document.getElementById('panel-grid-section').style.display = 'block';
249
- } catch (e) {
250
- console.error('Error loading panels:', e);
251
- }
252
- }
253
-
254
- // ============================================================================
255
- // Panel Navigation
256
- // ============================================================================
257
- function togglePanelGrid() {
258
- showingPanelGrid = !showingPanelGrid;
259
- if (showingPanelGrid) {
260
- loadPanelGrid();
261
- } else {
262
- document.getElementById('panel-grid-section').style.display = 'none';
263
- }
264
- }
265
-
266
- function prevPanel() {
267
- if (currentPanelIndex > 0) {
268
- loadPanelForEditing(panelData.panels[currentPanelIndex - 1].name);
269
- }
270
- }
271
-
272
- function nextPanel() {
273
- if (currentPanelIndex < panelData.panels.length - 1) {
274
- loadPanelForEditing(panelData.panels[currentPanelIndex + 1].name);
275
- }
276
- }
277
-
278
- function updatePanelIndicator() {
279
- if (!panelData) return;
280
-
281
- const indicator = document.getElementById('panel-indicator');
282
- const prevBtn = document.getElementById('btn-prev-panel');
283
- const nextBtn = document.getElementById('btn-next-panel');
284
-
285
- // Update indicator text (if elements exist)
286
- if (indicator) {
287
- indicator.textContent = `${currentPanelIndex + 1} / ${panelData.panels.length}`;
288
- }
289
-
290
- // Update button states
291
- if (prevBtn) prevBtn.disabled = currentPanelIndex === 0;
292
- if (nextBtn) nextBtn.disabled = currentPanelIndex === panelData.panels.length - 1;
293
- }