scitex 2.10.3__py3-none-any.whl → 2.11.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 (363) hide show
  1. scitex/__init__.py +1 -4
  2. scitex/__version__.py +1 -1
  3. scitex/_install_guide.py +14 -2
  4. scitex/bridge/_figrecipe.py +1 -1
  5. scitex/bridge/_helpers.py +1 -1
  6. scitex/bridge/_plt_vis.py +1 -1
  7. scitex/bridge/_stats_plt.py +1 -1
  8. scitex/bridge/_stats_vis.py +2 -2
  9. scitex/{fig → canvas}/__init__.py +84 -96
  10. scitex/{fig → canvas}/backend/_parser.py +1 -1
  11. scitex/{fig → canvas}/canvas.py +13 -14
  12. scitex/{fts/_fig/_editor → canvas/editor}/_defaults.py +2 -2
  13. scitex/{fig → canvas}/editor/edit/__init__.py +11 -14
  14. scitex/{fig → canvas}/editor/edit/bundle_resolver.py +56 -48
  15. scitex/{fig → canvas}/editor/edit/editor_launcher.py +79 -26
  16. scitex/{fts/_fig/_editor/_cui/_panel_loader.py → canvas/editor/edit/panel_loader.py} +8 -8
  17. scitex/{fts/_fig/_editor/_gui/_flask_editor → canvas/editor/flask_editor}/_bbox.py +2 -1
  18. scitex/{fts/_fig/_editor/_gui/_flask_editor → canvas/editor/flask_editor}/_core.py +84 -84
  19. scitex/{fts/_fig/_editor/_gui/_flask_editor → canvas/editor/flask_editor}/_renderer.py +7 -6
  20. scitex/{fts/_fig/_editor/_gui/_flask_editor → canvas/editor/flask_editor}/static/css/features/canvas.css +2 -2
  21. scitex/{fig → canvas}/editor/flask_editor/static/css/features/panel-grid.css +1 -1
  22. scitex/{fig → canvas}/editor/flask_editor/static/js/core/api.js +3 -4
  23. scitex/{fig → canvas}/editor/flask_editor/static/js/editor/preview.js +5 -5
  24. scitex/{fig → canvas}/editor/flask_editor/templates/_html.py +3 -3
  25. scitex/{fig → canvas}/editor/flask_editor/templates/_scripts.py +10 -10
  26. scitex/{fig → canvas}/editor/flask_editor/templates/_styles.py +3 -3
  27. scitex/{fig → canvas}/io/__init__.py +32 -38
  28. scitex/{fig → canvas}/io/_bundle.py +217 -154
  29. scitex/{fig → canvas}/io/_canvas.py +1 -1
  30. scitex/{fig → canvas}/io/_data.py +1 -1
  31. scitex/{fig → canvas}/io/_export.py +1 -1
  32. scitex/{fig → canvas}/io/_load.py +1 -1
  33. scitex/{fig → canvas}/io/_panel.py +1 -1
  34. scitex/{fig → canvas}/io/_save.py +1 -1
  35. scitex/{fig → canvas}/model/__init__.py +1 -1
  36. scitex/{fig → canvas}/model/_annotations.py +1 -1
  37. scitex/{fig → canvas}/model/_axes.py +1 -1
  38. scitex/{fig → canvas}/model/_figure.py +1 -1
  39. scitex/{fig → canvas}/model/_guides.py +1 -1
  40. scitex/{fig → canvas}/model/_plot.py +1 -1
  41. scitex/{fig → canvas}/model/_styles.py +1 -1
  42. scitex/{fig → canvas}/utils/__init__.py +1 -1
  43. scitex/cli/convert.py +10 -6
  44. scitex/diagram/README.md +7 -7
  45. scitex/io/__init__.py +7 -19
  46. scitex/io/_load.py +15 -19
  47. scitex/io/_load_modules/_canvas.py +2 -2
  48. scitex/io/_load_modules/_con.py +5 -5
  49. scitex/io/_load_modules/_eeg.py +16 -12
  50. scitex/io/_save.py +11 -16
  51. scitex/io/_save_modules/__init__.py +6 -10
  52. scitex/io/_save_modules/_canvas.py +3 -3
  53. scitex/io/_save_modules/_plot_bundle.py +112 -0
  54. scitex/io/_save_modules/{_pltz_stx.py → _plot_scitex.py} +7 -7
  55. scitex/io/_save_modules/_stx_bundle.py +16 -16
  56. scitex/io/bundle/README.md +89 -80
  57. scitex/{fts/_bundle/_FTS.py → io/bundle/_Bundle.py} +197 -95
  58. scitex/io/bundle/__init__.py +67 -35
  59. scitex/{fts/_bundle → io/bundle}/_children.py +32 -40
  60. scitex/io/bundle/_core.py +184 -97
  61. scitex/{fts/_bundle/_dataclasses/_Node.py → io/bundle/_dataclasses/_Spec.py} +29 -23
  62. scitex/{fts/_bundle/_dataclasses/_NodeRefs.py → io/bundle/_dataclasses/_SpecRefs.py} +6 -6
  63. scitex/{fts/_bundle → io/bundle}/_dataclasses/__init__.py +4 -4
  64. scitex/{fts/_bundle → io/bundle}/_loader.py +19 -19
  65. scitex/io/bundle/_manifest.py +99 -0
  66. scitex/{fts/_bundle → io/bundle}/_mpl_helpers.py +119 -28
  67. scitex/io/bundle/_nested.py +113 -100
  68. scitex/{fts/_bundle → io/bundle}/_saver.py +13 -14
  69. scitex/{fts/_bundle → io/bundle}/_storage.py +3 -3
  70. scitex/io/bundle/_types.py +41 -16
  71. scitex/{fts/_bundle → io/bundle}/_validation.py +20 -18
  72. scitex/io/bundle/_zip.py +21 -31
  73. scitex/{fts/_kinds → io/bundle/kinds}/_plot/_backend/_parser.py +1 -1
  74. scitex/{fts/_kinds → io/bundle/kinds}/_plot/_models/_Annotations.py +1 -1
  75. scitex/{fts/_kinds → io/bundle/kinds}/_plot/_models/_Axes.py +1 -1
  76. scitex/{fts/_kinds → io/bundle/kinds}/_plot/_models/_Figure.py +1 -1
  77. scitex/{fts/_fig → io/bundle/kinds/_plot}/_models/_Guides.py +1 -1
  78. scitex/{fts/_kinds → io/bundle/kinds}/_plot/_models/_Plot.py +1 -1
  79. scitex/{fts/_fig → io/bundle/kinds/_plot}/_models/_Styles.py +1 -1
  80. scitex/{fts/_kinds → io/bundle/kinds}/_plot/_utils/_plot_layout.py +1 -1
  81. scitex/{fts/_kinds → io/bundle/kinds}/_table/_latex/__init__.py +1 -1
  82. scitex/{fts/_kinds → io/bundle/kinds}/_table/_latex/_editor/_app.py +1 -1
  83. scitex/{fts/_tables → io/bundle/kinds/_table}/_latex/_export.py +1 -1
  84. scitex/{fts/_kinds → io/bundle/kinds}/_table/_latex/_figure_exporter.py +1 -1
  85. scitex/{fts/_kinds → io/bundle/kinds}/_table/_latex/_table_exporter.py +1 -1
  86. scitex/io/bundle/schemas/__init__.py +30 -0
  87. scitex/parallel/_run.py +5 -4
  88. scitex/path/_find.py +60 -83
  89. scitex/path/_get_module_path.py +23 -21
  90. scitex/path/_get_spath.py +6 -27
  91. scitex/path/_getsize.py +23 -9
  92. scitex/path/_increment_version.py +31 -38
  93. scitex/path/_mk_spath.py +26 -29
  94. scitex/path/_path.py +5 -12
  95. scitex/path/_split.py +27 -15
  96. scitex/path/_this_path.py +23 -9
  97. scitex/plt/_subplots/_AxisWrapperMixins/_MatplotlibPlotMixin/__init__.py +2 -1
  98. scitex/plt/_subplots/_AxisWrapperMixins/__init__.py +2 -2
  99. scitex/plt/gallery/_generate.py +76 -50
  100. scitex/plt/io/__init__.py +17 -19
  101. scitex/plt/io/_bundle.py +99 -52
  102. scitex/plt/io/_layered_bundle.py +303 -168
  103. scitex/plt/utils/_csv_column_naming.py +250 -118
  104. scitex/schema/__init__.py +69 -73
  105. scitex/schema/_canvas.py +1 -1
  106. scitex/schema/_stats.py +2 -2
  107. scitex/stats/__init__.py +30 -33
  108. scitex/stats/_schema.py +1 -1
  109. scitex/stats/io/__init__.py +10 -11
  110. scitex/stats/io/_bundle.py +16 -16
  111. {scitex-2.10.3.dist-info → scitex-2.11.0.dist-info}/METADATA +190 -73
  112. {scitex-2.10.3.dist-info → scitex-2.11.0.dist-info}/RECORD +237 -360
  113. scitex/fig/editor/_defaults.py +0 -300
  114. scitex/fig/editor/edit/panel_loader.py +0 -232
  115. scitex/fig/editor/flask_editor/_bbox.py +0 -1299
  116. scitex/fig/editor/flask_editor/_core.py +0 -1429
  117. scitex/fig/editor/flask_editor/_renderer.py +0 -813
  118. scitex/fig/editor/flask_editor/static/css/features/canvas.css +0 -176
  119. scitex/fts/README.md +0 -262
  120. scitex/fts/TODO.md +0 -66
  121. scitex/fts/__init__.py +0 -90
  122. scitex/fts/_bundle/README_IN_BUNDLE.md +0 -102
  123. scitex/fts/_bundle/__init__.py +0 -38
  124. scitex/fts/_bundle/_utils/__init__.py +0 -55
  125. scitex/fts/_bundle/_utils/_const.py +0 -26
  126. scitex/fts/_bundle/_utils/_errors.py +0 -73
  127. scitex/fts/_bundle/_utils/_generate.py +0 -21
  128. scitex/fts/_bundle/_utils/_types.py +0 -76
  129. scitex/fts/_bundle/_zipbundle.py +0 -165
  130. scitex/fts/_fig/__init__.py +0 -22
  131. scitex/fts/_fig/_backend/_parser.py +0 -188
  132. scitex/fts/_fig/_editor/__init__.py +0 -14
  133. scitex/fts/_fig/_editor/_cui/__init__.py +0 -33
  134. scitex/fts/_fig/_editor/_cui/_backend_detector.py +0 -39
  135. scitex/fts/_fig/_editor/_cui/_bundle_resolver.py +0 -366
  136. scitex/fts/_fig/_editor/_cui/_editor_launcher.py +0 -175
  137. scitex/fts/_fig/_editor/_cui/_manual_handler.py +0 -52
  138. scitex/fts/_fig/_editor/_cui/_path_resolver.py +0 -66
  139. scitex/fts/_fig/_editor/_gui/__init__.py +0 -11
  140. scitex/fts/_fig/_editor/_gui/_flask_editor/__init__.py +0 -20
  141. scitex/fts/_fig/_editor/_gui/_flask_editor/_plotter.py +0 -664
  142. scitex/fts/_fig/_editor/_gui/_flask_editor/_utils.py +0 -79
  143. scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/base/reset.css +0 -41
  144. scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/base/typography.css +0 -16
  145. scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/base/variables.css +0 -85
  146. scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/components/buttons.css +0 -217
  147. scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/components/context-menu.css +0 -93
  148. scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/components/dropdown.css +0 -57
  149. scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/components/forms.css +0 -112
  150. scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/components/modal.css +0 -59
  151. scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/components/sections.css +0 -212
  152. scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/features/element-inspector.css +0 -190
  153. scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/features/loading.css +0 -59
  154. scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/features/overlay.css +0 -45
  155. scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/features/panel-grid.css +0 -95
  156. scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/features/selection.css +0 -101
  157. scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/features/statistics.css +0 -138
  158. scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/index.css +0 -31
  159. scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/layout/container.css +0 -7
  160. scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/layout/controls.css +0 -56
  161. scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/layout/preview.css +0 -78
  162. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/alignment/axis.js +0 -314
  163. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/alignment/basic.js +0 -107
  164. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/alignment/distribute.js +0 -54
  165. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/canvas/canvas.js +0 -172
  166. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/canvas/dragging.js +0 -258
  167. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/canvas/resize.js +0 -48
  168. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/canvas/selection.js +0 -71
  169. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/core/api.js +0 -288
  170. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/core/state.js +0 -143
  171. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/core/utils.js +0 -245
  172. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/dev/element-inspector.js +0 -992
  173. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/editor/bbox.js +0 -339
  174. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/editor/element-drag.js +0 -286
  175. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/editor/overlay.js +0 -371
  176. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/editor/preview.js +0 -293
  177. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/main.js +0 -426
  178. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/shortcuts/context-menu.js +0 -152
  179. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/shortcuts/keyboard.js +0 -265
  180. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/ui/controls.js +0 -184
  181. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/ui/download.js +0 -57
  182. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/ui/help.js +0 -100
  183. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/ui/theme.js +0 -34
  184. scitex/fts/_fig/_editor/_gui/_flask_editor/templates/__init__.py +0 -124
  185. scitex/fts/_fig/_editor/_gui/_flask_editor/templates/_html.py +0 -851
  186. scitex/fts/_fig/_editor/_gui/_flask_editor/templates/_scripts.py +0 -4932
  187. scitex/fts/_fig/_editor/_gui/_flask_editor/templates/_styles.py +0 -1657
  188. scitex/fts/_fig/_editor/_gui/_flask_editor.py +0 -36
  189. scitex/fts/_fig/_models/_Annotations.py +0 -115
  190. scitex/fts/_fig/_models/_Axes.py +0 -152
  191. scitex/fts/_fig/_models/_Figure.py +0 -138
  192. scitex/fts/_fig/_models/_Plot.py +0 -123
  193. scitex/fts/_fig/_utils/_plot_layout.py +0 -397
  194. scitex/fts/_kinds/_figure/_composite.py +0 -345
  195. scitex/fts/_kinds/_plot/_backend/__init__.py +0 -53
  196. scitex/fts/_kinds/_plot/_backend/_export.py +0 -165
  197. scitex/fts/_kinds/_plot/_backend/_render.py +0 -538
  198. scitex/fts/_kinds/_plot/_dataclasses/_ChannelEncoding.py +0 -46
  199. scitex/fts/_kinds/_plot/_dataclasses/_Encoding.py +0 -82
  200. scitex/fts/_kinds/_plot/_dataclasses/_Theme.py +0 -441
  201. scitex/fts/_kinds/_plot/_dataclasses/_TraceEncoding.py +0 -52
  202. scitex/fts/_kinds/_plot/_dataclasses/__init__.py +0 -47
  203. scitex/fts/_kinds/_plot/_models/_Guides.py +0 -104
  204. scitex/fts/_kinds/_plot/_models/_Styles.py +0 -245
  205. scitex/fts/_kinds/_plot/_models/__init__.py +0 -80
  206. scitex/fts/_kinds/_plot/_models/_plot_types/__init__.py +0 -156
  207. scitex/fts/_kinds/_plot/_models/_plot_types/_bar.py +0 -43
  208. scitex/fts/_kinds/_plot/_models/_plot_types/_box.py +0 -38
  209. scitex/fts/_kinds/_plot/_models/_plot_types/_distribution.py +0 -36
  210. scitex/fts/_kinds/_plot/_models/_plot_types/_errorbar.py +0 -60
  211. scitex/fts/_kinds/_plot/_models/_plot_types/_histogram.py +0 -30
  212. scitex/fts/_kinds/_plot/_models/_plot_types/_image.py +0 -61
  213. scitex/fts/_kinds/_plot/_models/_plot_types/_line.py +0 -57
  214. scitex/fts/_kinds/_plot/_models/_plot_types/_scatter.py +0 -30
  215. scitex/fts/_kinds/_plot/_models/_plot_types/_seaborn.py +0 -121
  216. scitex/fts/_kinds/_plot/_models/_plot_types/_violin.py +0 -36
  217. scitex/fts/_kinds/_plot/_utils/__init__.py +0 -129
  218. scitex/fts/_kinds/_plot/_utils/_auto_layout.py +0 -127
  219. scitex/fts/_kinds/_plot/_utils/_calc_bounds.py +0 -111
  220. scitex/fts/_kinds/_plot/_utils/_const_sizes.py +0 -48
  221. scitex/fts/_kinds/_plot/_utils/_convert_coords.py +0 -77
  222. scitex/fts/_kinds/_plot/_utils/_get_template.py +0 -178
  223. scitex/fts/_kinds/_plot/_utils/_normalize.py +0 -73
  224. scitex/fts/_kinds/_plot/_utils/_validate.py +0 -197
  225. scitex/fts/_kinds/_table/_latex/_export.py +0 -279
  226. scitex/fts/_stats/__init__.py +0 -48
  227. scitex/fts/_stats/_dataclasses/_Stats.py +0 -423
  228. scitex/fts/_stats/_dataclasses/__init__.py +0 -48
  229. scitex/fts/_tables/__init__.py +0 -65
  230. scitex/fts/_tables/_latex/__init__.py +0 -93
  231. scitex/fts/_tables/_latex/_editor/__init__.py +0 -11
  232. scitex/fts/_tables/_latex/_editor/_app.py +0 -725
  233. scitex/fts/_tables/_latex/_figure_exporter.py +0 -153
  234. scitex/fts/_tables/_latex/_stats_formatter.py +0 -274
  235. scitex/fts/_tables/_latex/_table_exporter.py +0 -362
  236. scitex/fts/_tables/_latex/_utils.py +0 -369
  237. scitex/fts/_tables/_latex/_validator.py +0 -445
  238. scitex/io/_save_modules/_pltz_bundle.py +0 -356
  239. /scitex/{fig → canvas}/README.md +0 -0
  240. /scitex/{fig → canvas}/backend/__init__.py +0 -0
  241. /scitex/{fig → canvas}/backend/_export.py +0 -0
  242. /scitex/{fig → canvas}/backend/_render.py +0 -0
  243. /scitex/{fig → canvas}/docs/CANVAS_ARCHITECTURE.md +0 -0
  244. /scitex/{fig → canvas}/editor/__init__.py +0 -0
  245. /scitex/{fig → canvas}/editor/_dearpygui_editor.py +0 -0
  246. /scitex/{fig → canvas}/editor/_flask_editor.py +0 -0
  247. /scitex/{fig → canvas}/editor/_mpl_editor.py +0 -0
  248. /scitex/{fig → canvas}/editor/_qt_editor.py +0 -0
  249. /scitex/{fig → canvas}/editor/_tkinter_editor.py +0 -0
  250. /scitex/{fig → canvas}/editor/edit/backend_detector.py +0 -0
  251. /scitex/{fig → canvas}/editor/edit/manual_handler.py +0 -0
  252. /scitex/{fig → canvas}/editor/edit/path_resolver.py +0 -0
  253. /scitex/{fig → canvas}/editor/flask_editor/__init__.py +0 -0
  254. /scitex/{fig → canvas}/editor/flask_editor/_plotter.py +0 -0
  255. /scitex/{fig → canvas}/editor/flask_editor/_utils.py +0 -0
  256. /scitex/{fig → canvas}/editor/flask_editor/static/css/base/reset.css +0 -0
  257. /scitex/{fig → canvas}/editor/flask_editor/static/css/base/typography.css +0 -0
  258. /scitex/{fig → canvas}/editor/flask_editor/static/css/base/variables.css +0 -0
  259. /scitex/{fig → canvas}/editor/flask_editor/static/css/components/buttons.css +0 -0
  260. /scitex/{fig → canvas}/editor/flask_editor/static/css/components/context-menu.css +0 -0
  261. /scitex/{fig → canvas}/editor/flask_editor/static/css/components/dropdown.css +0 -0
  262. /scitex/{fig → canvas}/editor/flask_editor/static/css/components/forms.css +0 -0
  263. /scitex/{fig → canvas}/editor/flask_editor/static/css/components/modal.css +0 -0
  264. /scitex/{fig → canvas}/editor/flask_editor/static/css/components/sections.css +0 -0
  265. /scitex/{fig → canvas}/editor/flask_editor/static/css/features/element-inspector.css +0 -0
  266. /scitex/{fig → canvas}/editor/flask_editor/static/css/features/loading.css +0 -0
  267. /scitex/{fig → canvas}/editor/flask_editor/static/css/features/overlay.css +0 -0
  268. /scitex/{fig → canvas}/editor/flask_editor/static/css/features/selection.css +0 -0
  269. /scitex/{fig → canvas}/editor/flask_editor/static/css/features/statistics.css +0 -0
  270. /scitex/{fig → canvas}/editor/flask_editor/static/css/index.css +0 -0
  271. /scitex/{fig → canvas}/editor/flask_editor/static/css/layout/container.css +0 -0
  272. /scitex/{fig → canvas}/editor/flask_editor/static/css/layout/controls.css +0 -0
  273. /scitex/{fig → canvas}/editor/flask_editor/static/css/layout/preview.css +0 -0
  274. /scitex/{fig → canvas}/editor/flask_editor/static/js/alignment/axis.js +0 -0
  275. /scitex/{fig → canvas}/editor/flask_editor/static/js/alignment/basic.js +0 -0
  276. /scitex/{fig → canvas}/editor/flask_editor/static/js/alignment/distribute.js +0 -0
  277. /scitex/{fig → canvas}/editor/flask_editor/static/js/canvas/canvas.js +0 -0
  278. /scitex/{fig → canvas}/editor/flask_editor/static/js/canvas/dragging.js +0 -0
  279. /scitex/{fig → canvas}/editor/flask_editor/static/js/canvas/resize.js +0 -0
  280. /scitex/{fig → canvas}/editor/flask_editor/static/js/canvas/selection.js +0 -0
  281. /scitex/{fig → canvas}/editor/flask_editor/static/js/core/state.js +0 -0
  282. /scitex/{fig → canvas}/editor/flask_editor/static/js/core/utils.js +0 -0
  283. /scitex/{fig → canvas}/editor/flask_editor/static/js/dev/element-inspector.js +0 -0
  284. /scitex/{fig → canvas}/editor/flask_editor/static/js/editor/bbox.js +0 -0
  285. /scitex/{fig → canvas}/editor/flask_editor/static/js/editor/element-drag.js +0 -0
  286. /scitex/{fig → canvas}/editor/flask_editor/static/js/editor/overlay.js +0 -0
  287. /scitex/{fig → canvas}/editor/flask_editor/static/js/main.js +0 -0
  288. /scitex/{fig → canvas}/editor/flask_editor/static/js/shortcuts/context-menu.js +0 -0
  289. /scitex/{fig → canvas}/editor/flask_editor/static/js/shortcuts/keyboard.js +0 -0
  290. /scitex/{fig → canvas}/editor/flask_editor/static/js/ui/controls.js +0 -0
  291. /scitex/{fig → canvas}/editor/flask_editor/static/js/ui/download.js +0 -0
  292. /scitex/{fig → canvas}/editor/flask_editor/static/js/ui/help.js +0 -0
  293. /scitex/{fig → canvas}/editor/flask_editor/static/js/ui/theme.js +0 -0
  294. /scitex/{fig → canvas}/editor/flask_editor/templates/__init__.py +0 -0
  295. /scitex/{fig → canvas}/io/_directory.py +0 -0
  296. /scitex/{fig → canvas}/model/_plot_types.py +0 -0
  297. /scitex/{fig → canvas}/utils/_defaults.py +0 -0
  298. /scitex/{fig → canvas}/utils/_validate.py +0 -0
  299. /scitex/{fts/_bundle → io/bundle}/_conversion/__init__.py +0 -0
  300. /scitex/{fts/_bundle → io/bundle}/_conversion/_bundle2dict.py +0 -0
  301. /scitex/{fts/_bundle → io/bundle}/_conversion/_dict2bundle.py +0 -0
  302. /scitex/{fts/_bundle → io/bundle}/_dataclasses/_Axes.py +0 -0
  303. /scitex/{fts/_bundle → io/bundle}/_dataclasses/_BBox.py +0 -0
  304. /scitex/{fts/_bundle → io/bundle}/_dataclasses/_ColumnDef.py +0 -0
  305. /scitex/{fts/_bundle → io/bundle}/_dataclasses/_DataFormat.py +0 -0
  306. /scitex/{fts/_bundle → io/bundle}/_dataclasses/_DataInfo.py +0 -0
  307. /scitex/{fts/_bundle → io/bundle}/_dataclasses/_DataSource.py +0 -0
  308. /scitex/{fts/_bundle → io/bundle}/_dataclasses/_SizeMM.py +0 -0
  309. /scitex/{fts/_bundle → io/bundle}/_extractors/__init__.py +0 -0
  310. /scitex/{fts/_bundle → io/bundle}/_extractors/_extract_bar.py +0 -0
  311. /scitex/{fts/_bundle → io/bundle}/_extractors/_extract_line.py +0 -0
  312. /scitex/{fts/_bundle → io/bundle}/_extractors/_extract_scatter.py +0 -0
  313. /scitex/{fts/_kinds → io/bundle/kinds}/__init__.py +0 -0
  314. /scitex/{fts/_kinds → io/bundle/kinds}/_figure/__init__.py +0 -0
  315. /scitex/{fts/_fig → io/bundle/kinds/_figure}/_composite.py +0 -0
  316. /scitex/{fts/_kinds → io/bundle/kinds}/_plot/__init__.py +0 -0
  317. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_backend/__init__.py +0 -0
  318. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_backend/_export.py +0 -0
  319. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_backend/_render.py +0 -0
  320. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_dataclasses/_ChannelEncoding.py +0 -0
  321. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_dataclasses/_Encoding.py +0 -0
  322. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_dataclasses/_Theme.py +0 -0
  323. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_dataclasses/_TraceEncoding.py +0 -0
  324. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_dataclasses/__init__.py +0 -0
  325. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_models/__init__.py +0 -0
  326. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_models/_plot_types/__init__.py +0 -0
  327. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_models/_plot_types/_bar.py +0 -0
  328. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_models/_plot_types/_box.py +0 -0
  329. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_models/_plot_types/_distribution.py +0 -0
  330. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_models/_plot_types/_errorbar.py +0 -0
  331. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_models/_plot_types/_histogram.py +0 -0
  332. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_models/_plot_types/_image.py +0 -0
  333. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_models/_plot_types/_line.py +0 -0
  334. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_models/_plot_types/_scatter.py +0 -0
  335. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_models/_plot_types/_seaborn.py +0 -0
  336. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_models/_plot_types/_violin.py +0 -0
  337. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_utils/__init__.py +0 -0
  338. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_utils/_auto_layout.py +0 -0
  339. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_utils/_calc_bounds.py +0 -0
  340. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_utils/_const_sizes.py +0 -0
  341. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_utils/_convert_coords.py +0 -0
  342. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_utils/_get_template.py +0 -0
  343. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_utils/_normalize.py +0 -0
  344. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_utils/_validate.py +0 -0
  345. /scitex/{fts/_kinds → io/bundle/kinds}/_shape/__init__.py +0 -0
  346. /scitex/{fts/_kinds → io/bundle/kinds}/_stats/__init__.py +0 -0
  347. /scitex/{fts/_kinds → io/bundle/kinds}/_stats/_dataclasses/_Stats.py +0 -0
  348. /scitex/{fts/_kinds → io/bundle/kinds}/_stats/_dataclasses/__init__.py +0 -0
  349. /scitex/{fts/_kinds → io/bundle/kinds}/_table/__init__.py +0 -0
  350. /scitex/{fts/_kinds → io/bundle/kinds}/_table/_latex/_editor/__init__.py +0 -0
  351. /scitex/{fts/_kinds → io/bundle/kinds}/_table/_latex/_stats_formatter.py +0 -0
  352. /scitex/{fts/_kinds → io/bundle/kinds}/_table/_latex/_utils.py +0 -0
  353. /scitex/{fts/_kinds → io/bundle/kinds}/_table/_latex/_validator.py +0 -0
  354. /scitex/{fts/_kinds → io/bundle/kinds}/_text/__init__.py +0 -0
  355. /scitex/{fts/_schemas → io/bundle/schemas}/data_info.schema.json +0 -0
  356. /scitex/{fts/_schemas → io/bundle/schemas}/encoding.schema.json +0 -0
  357. /scitex/{fts/_schemas → io/bundle/schemas}/node.schema.json +0 -0
  358. /scitex/{fts/_schemas → io/bundle/schemas}/render_manifest.schema.json +0 -0
  359. /scitex/{fts/_schemas → io/bundle/schemas}/stats.schema.json +0 -0
  360. /scitex/{fts/_schemas → io/bundle/schemas}/theme.schema.json +0 -0
  361. {scitex-2.10.3.dist-info → scitex-2.11.0.dist-info}/WHEEL +0 -0
  362. {scitex-2.10.3.dist-info → scitex-2.11.0.dist-info}/entry_points.txt +0 -0
  363. {scitex-2.10.3.dist-info → scitex-2.11.0.dist-info}/licenses/LICENSE +0 -0
@@ -1,33 +0,0 @@
1
- #!/usr/bin/env python3
2
- # Timestamp: 2025-12-20
3
- # File: /home/ywatanabe/proj/scitex-code/src/scitex/fsb/_fig/editor/cui/__init__.py
4
-
5
- """CUI module for launching visual figure editors."""
6
-
7
- from ._backend_detector import detect_best_backend, print_available_backends
8
- from ._bundle_resolver import (
9
- resolve_figz_bundle,
10
- resolve_layered_pltz_bundle,
11
- resolve_pltz_bundle,
12
- resolve_stx_bundle,
13
- )
14
- from ._editor_launcher import edit
15
- from ._manual_handler import compute_file_hash, save_manual_overrides
16
- from ._panel_loader import load_panel_data
17
- from ._path_resolver import resolve_figure_paths
18
-
19
- __all__ = [
20
- "edit",
21
- "detect_best_backend",
22
- "print_available_backends",
23
- "resolve_figure_paths",
24
- "resolve_pltz_bundle",
25
- "resolve_figz_bundle",
26
- "resolve_layered_pltz_bundle",
27
- "resolve_stx_bundle",
28
- "load_panel_data",
29
- "compute_file_hash",
30
- "save_manual_overrides",
31
- ]
32
-
33
- # EOF
@@ -1,39 +0,0 @@
1
- #!/usr/bin/env python3
2
- # Timestamp: 2025-12-20
3
- # File: /home/ywatanabe/proj/scitex-code/src/scitex/fsb/_fig/_editor/_cui/_backend_detector.py
4
-
5
- """Backend detection for figure editor (Flask only)."""
6
-
7
- __all__ = ["print_available_backends", "detect_best_backend"]
8
-
9
-
10
- def print_available_backends() -> None:
11
- """Print Flask backend availability."""
12
- print("\n" + "=" * 50)
13
- print("SciTeX Visual Editor")
14
- print("=" * 50)
15
-
16
- try:
17
- import flask
18
-
19
- print(f" Flask: [OK] {flask.__version__}")
20
- except ImportError:
21
- print(" Flask: [NOT INSTALLED]")
22
- print("\nInstall: pip install flask")
23
-
24
- print("=" * 50 + "\n")
25
-
26
-
27
- def detect_best_backend() -> str:
28
- """Return Flask as the only supported backend."""
29
- try:
30
- import flask
31
-
32
- return "flask"
33
- except ImportError:
34
- raise ImportError(
35
- "Flask is required for the editor. Install with: pip install flask"
36
- )
37
-
38
-
39
- # EOF
@@ -1,366 +0,0 @@
1
- #!/usr/bin/env python3
2
- # Timestamp: 2025-12-20
3
- # File: /home/ywatanabe/proj/scitex-code/src/scitex/fsb/editor/edit/bundle_resolver.py
4
-
5
- """Bundle path resolution for FTS bundles (unified format)."""
6
-
7
- import json as json_module
8
- import tempfile
9
- import zipfile
10
- from pathlib import Path
11
- from typing import Tuple
12
-
13
- __all__ = [
14
- "resolve_pltz_bundle",
15
- "resolve_figz_bundle",
16
- "resolve_layered_pltz_bundle",
17
- "resolve_stx_bundle",
18
- ]
19
-
20
-
21
- def resolve_figz_bundle(path: Path, panel_index: int = 0) -> Tuple:
22
- """
23
- Resolve paths from a .figz bundle (multi-panel figure).
24
-
25
- Uses in-memory zip reading for .pltz panels - no disk extraction.
26
-
27
- Parameters
28
- ----------
29
- path : Path
30
- Path to .figz bundle (.figz or .figz.d)
31
- panel_index : int, optional
32
- Index of panel to open (default: 0 for first panel)
33
-
34
- Returns
35
- -------
36
- tuple
37
- (json_path, csv_path, png_path, hitmap_path, bundle_spec, panel_info)
38
- """
39
- spath = str(path)
40
- figz_is_zip = False
41
-
42
- # Handle ZIP vs directory for figz
43
- if spath.endswith(".figz") and not spath.endswith(".figz.d"):
44
- figz_is_zip = True
45
- if not path.exists():
46
- raise FileNotFoundError(f"Figz bundle not found: {path}")
47
- # For figz zip, extract to access nested pltz
48
- temp_dir = tempfile.mkdtemp(prefix="scitex_edit_figz_")
49
- with zipfile.ZipFile(path, "r") as zf:
50
- zf.extractall(temp_dir)
51
- bundle_dir = Path(temp_dir)
52
- for item in bundle_dir.iterdir():
53
- if item.is_dir() and str(item).endswith(".figz.d"):
54
- bundle_dir = item
55
- break
56
- else:
57
- bundle_dir = Path(path)
58
- if not bundle_dir.exists():
59
- raise FileNotFoundError(f"Figz bundle directory not found: {bundle_dir}")
60
-
61
- # Find nested pltz bundles
62
- panel_paths = []
63
- panel_is_zip = []
64
-
65
- for item in sorted(bundle_dir.iterdir(), key=lambda x: x.name):
66
- if item.is_dir() and str(item).endswith(".pltz.d"):
67
- panel_paths.append(str(item))
68
- panel_is_zip.append(False)
69
- elif item.is_file() and str(item).endswith(".pltz"):
70
- panel_paths.append(str(item))
71
- panel_is_zip.append(True)
72
-
73
- if not panel_paths:
74
- raise FileNotFoundError(f"No .pltz panels found in figz bundle: {bundle_dir}")
75
-
76
- # Validate panel index
77
- if panel_index < 0 or panel_index >= len(panel_paths):
78
- panel_index = 0
79
-
80
- selected_panel_path = panel_paths[panel_index]
81
- panel_name = Path(selected_panel_path).name
82
- print(f"Opening panel: {panel_name}")
83
- if len(panel_paths) > 1:
84
- print(f" (Figz contains {len(panel_paths)} panels)")
85
-
86
- # Build panel info
87
- panel_names = [Path(p).name for p in panel_paths]
88
- panel_info = {
89
- "panels": panel_names,
90
- "panel_paths": panel_paths,
91
- "panel_is_zip": panel_is_zip,
92
- "current_index": panel_index,
93
- "figz_dir": str(bundle_dir),
94
- "figz_is_zip": figz_is_zip,
95
- "bundle_path": (
96
- str(path) if figz_is_zip else None
97
- ), # Original figz zip path for export/download
98
- }
99
-
100
- # Resolve the selected panel
101
- result = resolve_pltz_bundle(Path(selected_panel_path))
102
- return result + (panel_info,)
103
-
104
-
105
- def resolve_pltz_bundle(path: Path) -> Tuple:
106
- """
107
- Resolve paths from a .pltz bundle (directory or ZIP).
108
-
109
- Supports both:
110
- - Legacy format (single {basename}.json)
111
- - Layered format v2.0 (spec.json + style.json + cache/)
112
-
113
- Parameters
114
- ----------
115
- path : Path
116
- Path to .pltz bundle (.pltz or .pltz.d)
117
-
118
- Returns
119
- -------
120
- tuple
121
- (json_path, csv_path, png_path, hitmap_path, bundle_spec)
122
- """
123
- spath = str(path)
124
-
125
- # Handle ZIP vs directory
126
- if spath.endswith(".pltz") and not spath.endswith(".pltz.d"):
127
- if not path.exists():
128
- raise FileNotFoundError(f"Bundle not found: {path}")
129
- temp_dir = tempfile.mkdtemp(prefix="scitex_edit_")
130
- with zipfile.ZipFile(path, "r") as zf:
131
- zf.extractall(temp_dir)
132
- bundle_dir = Path(temp_dir)
133
- for item in bundle_dir.iterdir():
134
- if item.is_dir() and str(item).endswith(".pltz.d"):
135
- bundle_dir = item
136
- break
137
- else:
138
- bundle_dir = Path(path)
139
- if not bundle_dir.exists():
140
- raise FileNotFoundError(f"Bundle directory not found: {bundle_dir}")
141
-
142
- # Check if this is a layered bundle (v2.0)
143
- spec_path = bundle_dir / "spec.json"
144
- if spec_path.exists():
145
- return resolve_layered_pltz_bundle(bundle_dir)
146
-
147
- # === Legacy format ===
148
- json_path = None
149
- csv_path = None
150
- png_path = None
151
- svg_path = None
152
- hitmap_path = None
153
- bundle_spec = None
154
-
155
- for f in bundle_dir.iterdir():
156
- name = f.name
157
- if name.endswith(".json") and not name.endswith(".manual.json"):
158
- json_path = f
159
- elif name.endswith(".csv"):
160
- csv_path = f
161
- elif name.endswith("_hitmap.png"):
162
- hitmap_path = f
163
- elif name.endswith(".svg") and "_hitmap" not in name:
164
- svg_path = f
165
- elif (
166
- name.endswith(".png") and "_hitmap" not in name and "_overview" not in name
167
- ):
168
- png_path = f
169
-
170
- # Prefer SVG for display
171
- if svg_path:
172
- png_path = svg_path
173
-
174
- if json_path and json_path.exists():
175
- with open(json_path) as f:
176
- bundle_spec = json_module.load(f)
177
-
178
- return (
179
- json_path,
180
- csv_path if csv_path and csv_path.exists() else None,
181
- png_path if png_path and png_path.exists() else None,
182
- hitmap_path if hitmap_path and hitmap_path.exists() else None,
183
- bundle_spec,
184
- )
185
-
186
-
187
- def resolve_layered_pltz_bundle(bundle_dir: Path) -> Tuple:
188
- """
189
- Resolve paths from a layered FTS bundle.
190
-
191
- FTS format structure:
192
- bundle.zip (or bundle.d/)
193
- canonical/
194
- spec.json # Main specification
195
- data.csv # Source data
196
- encoding.json # Data-to-visual mappings
197
- theme.json # Visual aesthetics
198
- artifacts/
199
- exports/ # PNG, SVG, PDF
200
- cache/ # geometry_px.json
201
-
202
- Parameters
203
- ----------
204
- bundle_dir : Path
205
- Path to bundle directory.
206
-
207
- Returns
208
- -------
209
- tuple
210
- (json_path, csv_path, png_path, hitmap_path, bundle_spec)
211
- """
212
- # Load FTS bundle directly
213
- bundle_data = {}
214
- spec_path = bundle_dir / "canonical" / "spec.json"
215
- if not spec_path.exists():
216
- spec_path = bundle_dir / "spec.json" # Legacy location
217
-
218
- if spec_path.exists():
219
- with open(spec_path) as f:
220
- bundle_data["spec"] = json_module.load(f)
221
-
222
- # Try to load encoding and theme
223
- for fname in ["encoding.json", "theme.json"]:
224
- fpath = bundle_dir / "canonical" / fname
225
- if not fpath.exists():
226
- fpath = bundle_dir / fname
227
- if fpath.exists():
228
- with open(fpath) as f:
229
- bundle_data[fname.replace(".json", "")] = json_module.load(f)
230
-
231
- csv_path = None
232
- png_path = None
233
- hitmap_path = None
234
-
235
- # Find CSV (check canonical/ first, then root)
236
- for search_dir in [bundle_dir / "canonical", bundle_dir]:
237
- for f in search_dir.glob("*.csv"):
238
- csv_path = f
239
- break
240
- if csv_path:
241
- break
242
-
243
- # Find exports (check artifacts/exports first, then exports/)
244
- for exports_dir in [bundle_dir / "artifacts" / "exports", bundle_dir / "exports"]:
245
- if exports_dir.exists():
246
- for f in exports_dir.iterdir():
247
- name = f.name
248
- if name.endswith("_hitmap.png"):
249
- hitmap_path = f
250
- elif name.endswith(".svg") and "_hitmap" not in name:
251
- png_path = f
252
- elif (
253
- name.endswith(".png") and "_hitmap" not in name and png_path is None
254
- ):
255
- png_path = f
256
-
257
- # Merge spec with encoding and theme
258
- bundle_spec = bundle_data.get("spec", {})
259
- if "encoding" in bundle_data:
260
- bundle_spec["encoding"] = bundle_data["encoding"]
261
- if "theme" in bundle_data:
262
- bundle_spec["theme"] = bundle_data["theme"]
263
-
264
- if hitmap_path and "hit_regions" in bundle_spec:
265
- bundle_spec["hit_regions"]["hit_map"] = str(hitmap_path.name)
266
-
267
- return (
268
- spec_path,
269
- csv_path if csv_path and csv_path.exists() else None,
270
- png_path if png_path and png_path.exists() else None,
271
- hitmap_path if hitmap_path and hitmap_path.exists() else None,
272
- bundle_spec,
273
- )
274
-
275
-
276
- def resolve_stx_bundle(path: Path) -> Tuple:
277
- """
278
- Resolve paths from a .stx bundle (unified FTS format).
279
-
280
- Parameters
281
- ----------
282
- path : Path
283
- Path to .stx bundle (.stx, .stx.d, .zip, or directory)
284
-
285
- Returns
286
- -------
287
- tuple
288
- (json_path, csv_path, png_path, hitmap_path, bundle_spec, element_info)
289
- """
290
- from scitex.fts import FTS
291
-
292
- spath = str(path)
293
-
294
- # Handle ZIP vs directory
295
- if spath.endswith((".stx", ".zip")) and not spath.endswith(".stx.d"):
296
- if not path.exists():
297
- raise FileNotFoundError(f"Bundle not found: {path}")
298
- temp_dir = tempfile.mkdtemp(prefix="scitex_edit_stx_")
299
- with zipfile.ZipFile(path, "r") as zf:
300
- zf.extractall(temp_dir)
301
- bundle_dir = Path(temp_dir)
302
- for item in bundle_dir.iterdir():
303
- if item.is_dir() and str(item).endswith((".stx.d", ".d")):
304
- bundle_dir = item
305
- break
306
- else:
307
- bundle_dir = Path(path)
308
- if not bundle_dir.exists():
309
- raise FileNotFoundError(f"Bundle directory not found: {bundle_dir}")
310
-
311
- # Load using FTS class
312
- fts_bundle = FTS(bundle_dir)
313
-
314
- # Find spec path (canonical/spec.json or spec.json)
315
- spec_path = bundle_dir / "canonical" / "spec.json"
316
- if not spec_path.exists():
317
- spec_path = bundle_dir / "spec.json"
318
-
319
- # Find exports (artifacts/exports or exports/)
320
- png_path = None
321
- hitmap_path = None
322
- csv_path = None
323
- for exports_dir in [bundle_dir / "artifacts" / "exports", bundle_dir / "exports"]:
324
- if exports_dir.exists():
325
- for f in exports_dir.iterdir():
326
- name = f.name
327
- if name.endswith("_hitmap.png"):
328
- hitmap_path = f
329
- elif name.endswith(".svg") and "_hitmap" not in name:
330
- png_path = f
331
- elif (
332
- name.endswith(".png") and "_hitmap" not in name and png_path is None
333
- ):
334
- png_path = f
335
-
336
- # Find CSV (canonical/data.csv or root)
337
- for search_dir in [bundle_dir / "canonical", bundle_dir]:
338
- for f in search_dir.glob("*.csv"):
339
- csv_path = f
340
- break
341
- if csv_path:
342
- break
343
-
344
- # Build bundle spec from FTS
345
- bundle_spec = fts_bundle.to_dict() if hasattr(fts_bundle, "to_dict") else {}
346
-
347
- # Build element info for editor
348
- element_info = {
349
- "elements": getattr(fts_bundle, "elements", []),
350
- "size_mm": fts_bundle.node.size_mm if fts_bundle.node else None,
351
- "bundle_dir": str(bundle_dir),
352
- "bundle_path": str(path),
353
- "is_directory": bundle_dir.is_dir(),
354
- }
355
-
356
- return (
357
- spec_path,
358
- csv_path if csv_path and csv_path.exists() else None,
359
- png_path if png_path and png_path.exists() else None,
360
- hitmap_path if hitmap_path and hitmap_path.exists() else None,
361
- bundle_spec,
362
- element_info,
363
- )
364
-
365
-
366
- # EOF
@@ -1,175 +0,0 @@
1
- #!/usr/bin/env python3
2
- # Timestamp: 2025-12-20
3
- # File: /home/ywatanabe/proj/scitex-code/src/scitex/fsb/_fig/_editor/_cui/_editor_launcher.py
4
-
5
- """Main edit function for launching Flask visual editor."""
6
-
7
- from pathlib import Path
8
- from typing import Union
9
-
10
- from ._backend_detector import detect_best_backend, print_available_backends
11
- from ._bundle_resolver import (
12
- resolve_figz_bundle,
13
- resolve_pltz_bundle,
14
- )
15
- from ._path_resolver import resolve_figure_paths
16
-
17
- __all__ = ["edit"]
18
-
19
-
20
- def edit(
21
- path: Union[str, Path],
22
- apply_manual: bool = True,
23
- port: int = 5050,
24
- ) -> None:
25
- """
26
- Launch interactive Flask editor for figure style/annotation editing.
27
-
28
- Parameters
29
- ----------
30
- path : str or Path
31
- Path to figure file. Can be:
32
- - .stx or .stx.d unified element bundle
33
- - .pltz.d directory bundle (recommended for hitmap selection)
34
- - .pltz ZIP bundle
35
- - .figz or .figz.d multi-panel bundle
36
- - JSON file (figure.json or figure.manual.json)
37
- - CSV file (figure.csv) - for data-only start
38
- - PNG file (figure.png)
39
- apply_manual : bool, optional
40
- If True, load .manual.json overrides if exists (default: True)
41
- port : int, optional
42
- Port number for Flask editor. Default: 5050.
43
-
44
- Returns
45
- -------
46
- None
47
- Editor runs in Flask event loop. Changes saved to .manual.json.
48
- """
49
- path = Path(path)
50
- spath = str(path)
51
- parent_str = str(path.parent) if path.is_file() else ""
52
-
53
- # Panel info for multi-panel figures
54
- panel_info = None
55
-
56
- # Resolve paths based on input type
57
- json_path, csv_path, png_path, hitmap_path, bundle_spec, panel_info = (
58
- _resolve_paths(path, spath, parent_str)
59
- )
60
-
61
- if not json_path.exists():
62
- raise FileNotFoundError(f"JSON file not found: {json_path}")
63
-
64
- # Load data
65
- import scitex as stx
66
-
67
- metadata = bundle_spec if bundle_spec else stx.io.load(json_path)
68
- csv_data = None
69
- if csv_path and csv_path.exists():
70
- csv_data = stx.io.load(csv_path)
71
-
72
- # Load manual overrides if exists
73
- manual_path = json_path.with_suffix(".manual.json")
74
- manual_overrides = None
75
- if apply_manual and manual_path.exists():
76
- manual_data = stx.io.load(manual_path)
77
- manual_overrides = manual_data.get("overrides", {})
78
-
79
- # Verify Flask is available
80
- detect_best_backend()
81
-
82
- # Print status
83
- print_available_backends()
84
- print(f"Launching Flask editor for: {json_path}")
85
-
86
- # Launch Flask editor
87
- _launch_flask(
88
- json_path=json_path,
89
- metadata=metadata,
90
- csv_data=csv_data,
91
- png_path=png_path,
92
- hitmap_path=hitmap_path,
93
- manual_overrides=manual_overrides,
94
- port=port,
95
- panel_info=panel_info,
96
- )
97
-
98
-
99
- def _resolve_paths(path: Path, spath: str, parent_str: str) -> tuple:
100
- """Resolve paths based on input type."""
101
- panel_info = None
102
- hitmap_path = None
103
- bundle_spec = None
104
-
105
- # Check if this is a .stx bundle (unified element format)
106
- if spath.endswith(".stx.d") or spath.endswith(".stx"):
107
- from ._bundle_resolver import resolve_stx_bundle
108
-
109
- json_path, csv_path, png_path, hitmap_path, bundle_spec, panel_info = (
110
- resolve_stx_bundle(path)
111
- )
112
- # Check if this is a .figz bundle (multi-panel figure)
113
- elif spath.endswith(".figz.d") or spath.endswith(".figz"):
114
- json_path, csv_path, png_path, hitmap_path, bundle_spec, panel_info = (
115
- resolve_figz_bundle(path)
116
- )
117
- # Check if this is a .pltz bundle
118
- elif (
119
- spath.endswith(".pltz.d")
120
- or spath.endswith(".pltz")
121
- or parent_str.endswith(".pltz.d")
122
- ):
123
- bundle_path = path.parent if parent_str.endswith(".pltz.d") else path
124
- json_path, csv_path, png_path, hitmap_path, bundle_spec = resolve_pltz_bundle(
125
- bundle_path
126
- )
127
- # Check if file is inside a .figz.d
128
- elif parent_str.endswith(".figz.d") or (
129
- path.parent.parent and str(path.parent.parent).endswith(".figz.d")
130
- ):
131
- figz_path = (
132
- path.parent if parent_str.endswith(".figz.d") else path.parent.parent
133
- )
134
- json_path, csv_path, png_path, hitmap_path, bundle_spec, panel_info = (
135
- resolve_figz_bundle(figz_path)
136
- )
137
- else:
138
- # Standard file paths
139
- json_path, csv_path, png_path = resolve_figure_paths(path)
140
-
141
- return json_path, csv_path, png_path, hitmap_path, bundle_spec, panel_info
142
-
143
-
144
- def _launch_flask(
145
- json_path,
146
- metadata,
147
- csv_data,
148
- png_path,
149
- hitmap_path,
150
- manual_overrides,
151
- port,
152
- panel_info,
153
- ):
154
- """Launch Flask web editor."""
155
- try:
156
- from .._gui._flask_editor import WebEditor
157
-
158
- editor = WebEditor(
159
- json_path=json_path,
160
- metadata=metadata,
161
- csv_data=csv_data,
162
- png_path=png_path,
163
- hitmap_path=hitmap_path,
164
- manual_overrides=manual_overrides,
165
- port=port,
166
- panel_info=panel_info,
167
- )
168
- editor.run()
169
- except ImportError as e:
170
- raise ImportError(
171
- "Flask backend requires Flask. Install with: pip install flask"
172
- ) from e
173
-
174
-
175
- # EOF
@@ -1,52 +0,0 @@
1
- #!/usr/bin/env python3
2
- # Timestamp: "2025-12-14 (ywatanabe)"
3
- # File: /home/ywatanabe/proj/scitex-code/src/scitex/fig/editor/edit/manual_handler.py
4
-
5
- """Manual override handling for figure editor."""
6
-
7
- import hashlib
8
- from pathlib import Path
9
-
10
- __all__ = ["compute_file_hash", "save_manual_overrides"]
11
-
12
-
13
- def compute_file_hash(path: Path) -> str:
14
- """Compute SHA256 hash of file contents."""
15
- with open(path, "rb") as f:
16
- return hashlib.sha256(f.read()).hexdigest()
17
-
18
-
19
- def save_manual_overrides(json_path: Path, overrides: dict) -> Path:
20
- """
21
- Save manual overrides to .manual.json file.
22
-
23
- Parameters
24
- ----------
25
- json_path : Path
26
- Path to base JSON file
27
- overrides : dict
28
- Override settings (styles, annotations, etc.)
29
-
30
- Returns
31
- -------
32
- Path
33
- Path to saved manual.json file
34
- """
35
- import scitex as stx
36
-
37
- manual_path = json_path.with_suffix(".manual.json")
38
-
39
- # Compute hash of base JSON for staleness detection
40
- base_hash = compute_file_hash(json_path)
41
-
42
- manual_data = {
43
- "base_file": json_path.name,
44
- "base_hash": base_hash,
45
- "overrides": overrides,
46
- }
47
-
48
- stx.io.save(manual_data, manual_path)
49
- return manual_path
50
-
51
-
52
- # EOF