scitex 2.7.3__py3-none-any.whl → 2.8.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (160) hide show
  1. scitex/__version__.py +1 -1
  2. scitex/dev/plt/__init__.py +0 -0
  3. scitex/dev/plt/plot_mpl_axhline.py +0 -0
  4. scitex/dev/plt/plot_mpl_axhspan.py +0 -0
  5. scitex/dev/plt/plot_mpl_axvline.py +0 -0
  6. scitex/dev/plt/plot_mpl_axvspan.py +0 -0
  7. scitex/dev/plt/plot_mpl_bar.py +0 -0
  8. scitex/dev/plt/plot_mpl_barh.py +0 -0
  9. scitex/dev/plt/plot_mpl_boxplot.py +0 -0
  10. scitex/dev/plt/plot_mpl_contour.py +0 -0
  11. scitex/dev/plt/plot_mpl_contourf.py +0 -0
  12. scitex/dev/plt/plot_mpl_errorbar.py +0 -0
  13. scitex/dev/plt/plot_mpl_eventplot.py +0 -0
  14. scitex/dev/plt/plot_mpl_fill.py +0 -0
  15. scitex/dev/plt/plot_mpl_fill_between.py +0 -0
  16. scitex/dev/plt/plot_mpl_hexbin.py +0 -0
  17. scitex/dev/plt/plot_mpl_hist.py +0 -0
  18. scitex/dev/plt/plot_mpl_hist2d.py +0 -0
  19. scitex/dev/plt/plot_mpl_imshow.py +0 -0
  20. scitex/dev/plt/plot_mpl_pcolormesh.py +0 -0
  21. scitex/dev/plt/plot_mpl_pie.py +0 -0
  22. scitex/dev/plt/plot_mpl_plot.py +0 -0
  23. scitex/dev/plt/plot_mpl_quiver.py +0 -0
  24. scitex/dev/plt/plot_mpl_scatter.py +0 -0
  25. scitex/dev/plt/plot_mpl_stackplot.py +0 -0
  26. scitex/dev/plt/plot_mpl_stem.py +0 -0
  27. scitex/dev/plt/plot_mpl_step.py +0 -0
  28. scitex/dev/plt/plot_mpl_violinplot.py +0 -0
  29. scitex/dev/plt/plot_sns_barplot.py +0 -0
  30. scitex/dev/plt/plot_sns_boxplot.py +0 -0
  31. scitex/dev/plt/plot_sns_heatmap.py +0 -0
  32. scitex/dev/plt/plot_sns_histplot.py +0 -0
  33. scitex/dev/plt/plot_sns_kdeplot.py +0 -0
  34. scitex/dev/plt/plot_sns_lineplot.py +0 -0
  35. scitex/dev/plt/plot_sns_scatterplot.py +0 -0
  36. scitex/dev/plt/plot_sns_stripplot.py +0 -0
  37. scitex/dev/plt/plot_sns_swarmplot.py +0 -0
  38. scitex/dev/plt/plot_sns_violinplot.py +0 -0
  39. scitex/dev/plt/plot_stx_bar.py +0 -0
  40. scitex/dev/plt/plot_stx_barh.py +0 -0
  41. scitex/dev/plt/plot_stx_box.py +0 -0
  42. scitex/dev/plt/plot_stx_boxplot.py +0 -0
  43. scitex/dev/plt/plot_stx_conf_mat.py +0 -0
  44. scitex/dev/plt/plot_stx_contour.py +0 -0
  45. scitex/dev/plt/plot_stx_ecdf.py +0 -0
  46. scitex/dev/plt/plot_stx_errorbar.py +0 -0
  47. scitex/dev/plt/plot_stx_fill_between.py +0 -0
  48. scitex/dev/plt/plot_stx_fillv.py +0 -0
  49. scitex/dev/plt/plot_stx_heatmap.py +0 -0
  50. scitex/dev/plt/plot_stx_image.py +0 -0
  51. scitex/dev/plt/plot_stx_imshow.py +0 -0
  52. scitex/dev/plt/plot_stx_joyplot.py +0 -0
  53. scitex/dev/plt/plot_stx_kde.py +0 -0
  54. scitex/dev/plt/plot_stx_line.py +0 -0
  55. scitex/dev/plt/plot_stx_mean_ci.py +0 -0
  56. scitex/dev/plt/plot_stx_mean_std.py +0 -0
  57. scitex/dev/plt/plot_stx_median_iqr.py +0 -0
  58. scitex/dev/plt/plot_stx_raster.py +0 -0
  59. scitex/dev/plt/plot_stx_rectangle.py +0 -0
  60. scitex/dev/plt/plot_stx_scatter.py +0 -0
  61. scitex/dev/plt/plot_stx_shaded_line.py +0 -0
  62. scitex/dev/plt/plot_stx_violin.py +0 -0
  63. scitex/dev/plt/plot_stx_violinplot.py +0 -0
  64. scitex/diagram/README.md +197 -0
  65. scitex/diagram/__init__.py +48 -0
  66. scitex/diagram/_compile.py +312 -0
  67. scitex/diagram/_diagram.py +355 -0
  68. scitex/diagram/_presets.py +173 -0
  69. scitex/diagram/_schema.py +182 -0
  70. scitex/diagram/_split.py +278 -0
  71. scitex/fig/editor/__init__.py +5 -2
  72. scitex/fig/editor/_dearpygui_editor.py +1 -1
  73. scitex/fig/editor/_mpl_editor.py +1 -1
  74. scitex/fig/editor/_qt_editor.py +1 -1
  75. scitex/fig/editor/_tkinter_editor.py +1 -1
  76. scitex/fig/editor/edit/__init__.py +50 -0
  77. scitex/fig/editor/edit/backend_detector.py +109 -0
  78. scitex/fig/editor/edit/bundle_resolver.py +240 -0
  79. scitex/fig/editor/edit/editor_launcher.py +239 -0
  80. scitex/fig/editor/edit/manual_handler.py +53 -0
  81. scitex/fig/editor/edit/panel_loader.py +232 -0
  82. scitex/fig/editor/edit/path_resolver.py +67 -0
  83. scitex/fig/editor/flask_editor/_bbox.py +23 -0
  84. scitex/fig/editor/flask_editor/_core.py +908 -103
  85. scitex/fig/editor/flask_editor/_renderer.py +74 -0
  86. scitex/fig/editor/flask_editor/static/css/base/reset.css +41 -0
  87. scitex/fig/editor/flask_editor/static/css/base/typography.css +16 -0
  88. scitex/fig/editor/flask_editor/static/css/base/variables.css +85 -0
  89. scitex/fig/editor/flask_editor/static/css/components/buttons.css +217 -0
  90. scitex/fig/editor/flask_editor/static/css/components/context-menu.css +93 -0
  91. scitex/fig/editor/flask_editor/static/css/components/dropdown.css +57 -0
  92. scitex/fig/editor/flask_editor/static/css/components/forms.css +112 -0
  93. scitex/fig/editor/flask_editor/static/css/components/modal.css +59 -0
  94. scitex/fig/editor/flask_editor/static/css/components/sections.css +212 -0
  95. scitex/fig/editor/flask_editor/static/css/features/canvas.css +176 -0
  96. scitex/fig/editor/flask_editor/static/css/features/element-inspector.css +190 -0
  97. scitex/fig/editor/flask_editor/static/css/features/loading.css +59 -0
  98. scitex/fig/editor/flask_editor/static/css/features/overlay.css +45 -0
  99. scitex/fig/editor/flask_editor/static/css/features/panel-grid.css +95 -0
  100. scitex/fig/editor/flask_editor/static/css/features/selection.css +101 -0
  101. scitex/fig/editor/flask_editor/static/css/features/statistics.css +138 -0
  102. scitex/fig/editor/flask_editor/static/css/index.css +31 -0
  103. scitex/fig/editor/flask_editor/static/css/layout/container.css +7 -0
  104. scitex/fig/editor/flask_editor/static/css/layout/controls.css +56 -0
  105. scitex/fig/editor/flask_editor/static/css/layout/preview.css +78 -0
  106. scitex/fig/editor/flask_editor/static/js/alignment/axis.js +314 -0
  107. scitex/fig/editor/flask_editor/static/js/alignment/basic.js +107 -0
  108. scitex/fig/editor/flask_editor/static/js/alignment/distribute.js +54 -0
  109. scitex/fig/editor/flask_editor/static/js/canvas/canvas.js +172 -0
  110. scitex/fig/editor/flask_editor/static/js/canvas/dragging.js +258 -0
  111. scitex/fig/editor/flask_editor/static/js/canvas/resize.js +48 -0
  112. scitex/fig/editor/flask_editor/static/js/canvas/selection.js +71 -0
  113. scitex/fig/editor/flask_editor/static/js/core/api.js +288 -0
  114. scitex/fig/editor/flask_editor/static/js/core/state.js +143 -0
  115. scitex/fig/editor/flask_editor/static/js/core/utils.js +245 -0
  116. scitex/fig/editor/flask_editor/static/js/dev/element-inspector.js +992 -0
  117. scitex/fig/editor/flask_editor/static/js/editor/bbox.js +339 -0
  118. scitex/fig/editor/flask_editor/static/js/editor/element-drag.js +286 -0
  119. scitex/fig/editor/flask_editor/static/js/editor/overlay.js +371 -0
  120. scitex/fig/editor/flask_editor/static/js/editor/preview.js +293 -0
  121. scitex/fig/editor/flask_editor/static/js/main.js +426 -0
  122. scitex/fig/editor/flask_editor/static/js/shortcuts/context-menu.js +152 -0
  123. scitex/fig/editor/flask_editor/static/js/shortcuts/keyboard.js +265 -0
  124. scitex/fig/editor/flask_editor/static/js/ui/controls.js +184 -0
  125. scitex/fig/editor/flask_editor/static/js/ui/download.js +57 -0
  126. scitex/fig/editor/flask_editor/static/js/ui/help.js +100 -0
  127. scitex/fig/editor/flask_editor/static/js/ui/theme.js +34 -0
  128. scitex/fig/editor/flask_editor/templates/__init__.py +95 -5
  129. scitex/fig/editor/flask_editor/templates/_html.py +27 -9
  130. scitex/fig/editor/flask_editor/templates/_scripts.py +1928 -131
  131. scitex/fig/editor/flask_editor/templates/_styles.py +363 -51
  132. scitex/fig/io/_bundle.py +97 -12
  133. scitex/io/__init__.py +12 -0
  134. scitex/io/_bundle.py +69 -10
  135. scitex/io/_zip_bundle.py +439 -0
  136. scitex/plt/_subplots/_AxisWrapperMixins/_AdjustmentMixin/__init__.py +0 -0
  137. scitex/plt/_subplots/_AxisWrapperMixins/_AdjustmentMixin/_labels.py +0 -0
  138. scitex/plt/_subplots/_AxisWrapperMixins/_AdjustmentMixin/_metadata.py +0 -0
  139. scitex/plt/_subplots/_AxisWrapperMixins/_AdjustmentMixin/_visual.py +0 -0
  140. scitex/plt/_subplots/_AxisWrapperMixins/_MatplotlibPlotMixin/__init__.py +0 -0
  141. scitex/plt/_subplots/_AxisWrapperMixins/_MatplotlibPlotMixin/_base.py +0 -0
  142. scitex/plt/_subplots/_AxisWrapperMixins/_MatplotlibPlotMixin/_scientific.py +0 -0
  143. scitex/plt/_subplots/_AxisWrapperMixins/_MatplotlibPlotMixin/_statistical.py +0 -0
  144. scitex/plt/_subplots/_AxisWrapperMixins/_MatplotlibPlotMixin/_stx_aliases.py +0 -0
  145. scitex/plt/_subplots/_AxisWrapperMixins/_RawMatplotlibMixin.py +0 -0
  146. scitex/plt/_subplots/_AxisWrapperMixins/_SeabornMixin/__init__.py +0 -0
  147. scitex/plt/_subplots/_AxisWrapperMixins/_SeabornMixin/_base.py +0 -0
  148. scitex/plt/_subplots/_AxisWrapperMixins/_SeabornMixin/_wrappers.py +0 -0
  149. scitex/plt/_subplots/_export_as_csv_formatters/_format_stx_bar.py +0 -0
  150. scitex/plt/_subplots/_export_as_csv_formatters/_format_stx_barh.py +0 -0
  151. scitex/plt/_subplots/_export_as_csv_formatters/_format_stx_errorbar.py +0 -0
  152. scitex/plt/_subplots/_export_as_csv_formatters/_format_stx_scatter.py +0 -0
  153. scitex/plt/io/_layered_bundle.py +0 -0
  154. scitex/schema/_plot.py +0 -0
  155. {scitex-2.7.3.dist-info → scitex-2.8.1.dist-info}/METADATA +1 -1
  156. {scitex-2.7.3.dist-info → scitex-2.8.1.dist-info}/RECORD +78 -22
  157. scitex/fig/editor/_edit.py +0 -751
  158. {scitex-2.7.3.dist-info → scitex-2.8.1.dist-info}/WHEEL +0 -0
  159. {scitex-2.7.3.dist-info → scitex-2.8.1.dist-info}/entry_points.txt +0 -0
  160. {scitex-2.7.3.dist-info → scitex-2.8.1.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,439 @@
1
+ #!/usr/bin/env python3
2
+ # -*- coding: utf-8 -*-
3
+ # Timestamp: "2025-12-14 (ywatanabe)"
4
+ # File: /home/ywatanabe/proj/scitex-code/src/scitex/io/_zip_bundle.py
5
+
6
+ """
7
+ SciTeX ZipBundle - In-memory zip archive handler with atomic writes.
8
+
9
+ Provides efficient access to .figz, .pltz, .statsz bundles without extracting
10
+ to disk. Supports:
11
+ - In-memory file reading
12
+ - Atomic writes using temp files
13
+ - Context manager protocol
14
+ - Dict-like access to files
15
+ """
16
+
17
+ import io
18
+ import json
19
+ import os
20
+ import shutil
21
+ import tempfile
22
+ import zipfile
23
+ from pathlib import Path
24
+ from typing import Any, BinaryIO, Dict, Iterator, List, Optional, Union
25
+
26
+ import pandas as pd
27
+
28
+ __all__ = [
29
+ "ZipBundle",
30
+ "open_bundle",
31
+ "create_bundle",
32
+ ]
33
+
34
+
35
+ class ZipBundle:
36
+ """In-memory zip bundle handler.
37
+
38
+ Provides efficient read/write access to zip archives without extracting
39
+ to disk. Files are read into memory on demand and writes are atomic.
40
+
41
+ Usage:
42
+ # Reading
43
+ with ZipBundle("figure.figz") as bundle:
44
+ spec = bundle.read_json("spec.json")
45
+ csv_data = bundle.read_csv("data.csv")
46
+ png_bytes = bundle.read_bytes("exports/figure.png")
47
+
48
+ # Writing
49
+ with ZipBundle("output.pltz", mode="w") as bundle:
50
+ bundle.write_json("spec.json", spec_dict)
51
+ bundle.write_csv("data.csv", dataframe)
52
+ bundle.write_bytes("exports/plot.png", png_bytes)
53
+
54
+ # Modifying (read then write atomically)
55
+ with ZipBundle("figure.figz", mode="a") as bundle:
56
+ spec = bundle.read_json("spec.json")
57
+ spec["title"] = "Updated"
58
+ bundle.write_json("spec.json", spec)
59
+ """
60
+
61
+ def __init__(
62
+ self,
63
+ path: Union[str, Path],
64
+ mode: str = "r",
65
+ compression: int = zipfile.ZIP_DEFLATED,
66
+ ):
67
+ """Initialize ZipBundle.
68
+
69
+ Args:
70
+ path: Path to zip file (.figz, .pltz, .statsz)
71
+ mode: 'r' for read, 'w' for write, 'a' for append/modify
72
+ compression: ZIP compression method (default: ZIP_DEFLATED)
73
+ """
74
+ self.path = Path(path)
75
+ self.mode = mode
76
+ self.compression = compression
77
+ self._zipfile: Optional[zipfile.ZipFile] = None
78
+ self._cache: Dict[str, bytes] = {} # Cache for read files
79
+ self._pending_writes: Dict[str, bytes] = {} # Pending writes for atomic commit
80
+ self._temp_path: Optional[Path] = None
81
+ self._closed = False
82
+
83
+ def __enter__(self) -> "ZipBundle":
84
+ """Enter context manager."""
85
+ self.open()
86
+ return self
87
+
88
+ def __exit__(self, exc_type, exc_val, exc_tb) -> None:
89
+ """Exit context manager with atomic commit on success."""
90
+ if exc_type is None and self.mode in ("w", "a"):
91
+ self._atomic_commit()
92
+ self.close()
93
+
94
+ def open(self) -> None:
95
+ """Open the zip bundle."""
96
+ if self.mode == "r":
97
+ if not self.path.exists():
98
+ raise FileNotFoundError(f"Bundle not found: {self.path}")
99
+ self._zipfile = zipfile.ZipFile(self.path, "r")
100
+ elif self.mode == "w":
101
+ # Create new archive (write to temp, commit on close)
102
+ self._temp_path = Path(tempfile.mktemp(suffix=self.path.suffix))
103
+ self._zipfile = zipfile.ZipFile(
104
+ self._temp_path, "w", self.compression
105
+ )
106
+ elif self.mode == "a":
107
+ # Append mode: read existing, write to temp, commit atomically
108
+ if self.path.exists():
109
+ # Load existing contents into cache
110
+ with zipfile.ZipFile(self.path, "r") as zf:
111
+ for name in zf.namelist():
112
+ self._cache[name] = zf.read(name)
113
+ self._temp_path = Path(tempfile.mktemp(suffix=self.path.suffix))
114
+ self._zipfile = zipfile.ZipFile(
115
+ self._temp_path, "w", self.compression
116
+ )
117
+ else:
118
+ raise ValueError(f"Invalid mode: {self.mode}")
119
+
120
+ def close(self) -> None:
121
+ """Close the zip bundle."""
122
+ if self._zipfile and not self._closed:
123
+ self._zipfile.close()
124
+ self._closed = True
125
+ # Clean up temp file if not committed (error case)
126
+ if self._temp_path and self._temp_path.exists():
127
+ if self.mode in ("w", "a") and not self.path.exists():
128
+ # Commit wasn't called, clean up
129
+ self._temp_path.unlink()
130
+
131
+ def _atomic_commit(self) -> None:
132
+ """Atomically commit writes by renaming temp file.
133
+
134
+ This ensures the bundle is never in an inconsistent state.
135
+ Either the old file exists completely, or the new one does.
136
+ """
137
+ if self._temp_path is None:
138
+ return
139
+
140
+ # Write all pending and cached content to the temp zip
141
+ self._zipfile.close()
142
+ self._closed = True
143
+
144
+ # Atomic rename (works on same filesystem)
145
+ # On Windows, we need to remove target first
146
+ if os.name == "nt" and self.path.exists():
147
+ backup_path = self.path.with_suffix(self.path.suffix + ".bak")
148
+ self.path.rename(backup_path)
149
+ try:
150
+ self._temp_path.rename(self.path)
151
+ backup_path.unlink()
152
+ except Exception:
153
+ # Restore backup on failure
154
+ backup_path.rename(self.path)
155
+ raise
156
+ else:
157
+ # Unix: atomic rename
158
+ self._temp_path.rename(self.path)
159
+
160
+ # =========================================================================
161
+ # File listing
162
+ # =========================================================================
163
+
164
+ def namelist(self) -> List[str]:
165
+ """List all files in the bundle."""
166
+ if self.mode == "r":
167
+ return self._zipfile.namelist()
168
+ else:
169
+ # Include both cached and pending writes
170
+ names = set(self._cache.keys())
171
+ names.update(self._pending_writes.keys())
172
+ return sorted(names)
173
+
174
+ def __contains__(self, name: str) -> bool:
175
+ """Check if file exists in bundle."""
176
+ return name in self.namelist()
177
+
178
+ def __iter__(self) -> Iterator[str]:
179
+ """Iterate over file names in bundle."""
180
+ return iter(self.namelist())
181
+
182
+ # =========================================================================
183
+ # Reading
184
+ # =========================================================================
185
+
186
+ def read_bytes(self, name: str) -> bytes:
187
+ """Read file as bytes.
188
+
189
+ Args:
190
+ name: File path within the zip (e.g., "spec.json", "exports/plot.png")
191
+
192
+ Returns:
193
+ File contents as bytes.
194
+ """
195
+ # Check cache first (for append mode)
196
+ if name in self._pending_writes:
197
+ return self._pending_writes[name]
198
+ if name in self._cache:
199
+ return self._cache[name]
200
+
201
+ # Read from zip
202
+ if self._zipfile is None:
203
+ raise RuntimeError("Bundle not opened")
204
+
205
+ # Handle files inside .d directory structure
206
+ # Try direct name first, then with .d prefix
207
+ try:
208
+ data = self._zipfile.read(name)
209
+ self._cache[name] = data
210
+ return data
211
+ except KeyError:
212
+ # Try with directory prefix (e.g., "bundle.pltz.d/spec.json")
213
+ # The path.name includes extension, so "foo.pltz" -> "foo.pltz.d"
214
+ dir_name = self.path.name + ".d"
215
+ full_name = f"{dir_name}/{name}"
216
+ try:
217
+ data = self._zipfile.read(full_name)
218
+ self._cache[name] = data
219
+ return data
220
+ except KeyError:
221
+ # Try to find the .d directory dynamically
222
+ # (handles case where pltz was renamed, e.g., panel_A.pltz -> A.pltz
223
+ # but internal structure is still panel_A.pltz.d/)
224
+ for arc_name in self._zipfile.namelist():
225
+ if arc_name.endswith('.d/' + name) or arc_name.endswith('.d/' + name.replace('/', '/')):
226
+ data = self._zipfile.read(arc_name)
227
+ self._cache[name] = data
228
+ return data
229
+ raise FileNotFoundError(f"File not found in bundle: {name}")
230
+
231
+ def read_text(self, name: str, encoding: str = "utf-8") -> str:
232
+ """Read file as text.
233
+
234
+ Args:
235
+ name: File path within the zip.
236
+ encoding: Text encoding (default: utf-8).
237
+
238
+ Returns:
239
+ File contents as string.
240
+ """
241
+ return self.read_bytes(name).decode(encoding)
242
+
243
+ def read_json(self, name: str = "spec.json") -> Dict[str, Any]:
244
+ """Read and parse JSON file.
245
+
246
+ Args:
247
+ name: JSON file path within the zip.
248
+
249
+ Returns:
250
+ Parsed JSON as dictionary.
251
+ """
252
+ return json.loads(self.read_text(name))
253
+
254
+ def read_csv(self, name: str = "data.csv", **kwargs) -> pd.DataFrame:
255
+ """Read CSV file as pandas DataFrame.
256
+
257
+ Args:
258
+ name: CSV file path within the zip.
259
+ **kwargs: Additional arguments passed to pd.read_csv.
260
+
261
+ Returns:
262
+ DataFrame with CSV contents.
263
+ """
264
+ data = self.read_bytes(name)
265
+ return pd.read_csv(io.BytesIO(data), **kwargs)
266
+
267
+ def read_image(self, name: str) -> bytes:
268
+ """Read image file as bytes.
269
+
270
+ Args:
271
+ name: Image file path (e.g., "exports/figure.png").
272
+
273
+ Returns:
274
+ Image bytes.
275
+ """
276
+ return self.read_bytes(name)
277
+
278
+ # =========================================================================
279
+ # Writing
280
+ # =========================================================================
281
+
282
+ def write_bytes(self, name: str, data: bytes) -> None:
283
+ """Write bytes to file in bundle.
284
+
285
+ Args:
286
+ name: File path within the zip.
287
+ data: Bytes to write.
288
+ """
289
+ if self.mode == "r":
290
+ raise RuntimeError("Cannot write in read mode")
291
+
292
+ self._pending_writes[name] = data
293
+ self._cache[name] = data # Update cache
294
+
295
+ # Write to zip immediately
296
+ self._zipfile.writestr(name, data)
297
+
298
+ def write_text(self, name: str, text: str, encoding: str = "utf-8") -> None:
299
+ """Write text to file in bundle.
300
+
301
+ Args:
302
+ name: File path within the zip.
303
+ text: Text to write.
304
+ encoding: Text encoding (default: utf-8).
305
+ """
306
+ self.write_bytes(name, text.encode(encoding))
307
+
308
+ def write_json(
309
+ self, name: str, data: Dict[str, Any], indent: int = 2
310
+ ) -> None:
311
+ """Write dictionary as JSON file.
312
+
313
+ Args:
314
+ name: JSON file path within the zip.
315
+ data: Dictionary to serialize.
316
+ indent: JSON indentation (default: 2).
317
+ """
318
+ text = json.dumps(data, indent=indent, ensure_ascii=False)
319
+ self.write_text(name, text)
320
+
321
+ def write_csv(
322
+ self, name: str, df: pd.DataFrame, index: bool = False, **kwargs
323
+ ) -> None:
324
+ """Write pandas DataFrame as CSV.
325
+
326
+ Args:
327
+ name: CSV file path within the zip.
328
+ df: DataFrame to write.
329
+ index: Include index column (default: False).
330
+ **kwargs: Additional arguments passed to df.to_csv.
331
+ """
332
+ buffer = io.BytesIO()
333
+ df.to_csv(buffer, index=index, **kwargs)
334
+ self.write_bytes(name, buffer.getvalue())
335
+
336
+ def write_image(self, name: str, data: bytes) -> None:
337
+ """Write image bytes to bundle.
338
+
339
+ Args:
340
+ name: Image file path (e.g., "exports/figure.png").
341
+ data: Image bytes.
342
+ """
343
+ self.write_bytes(name, data)
344
+
345
+ # =========================================================================
346
+ # Convenience methods
347
+ # =========================================================================
348
+
349
+ @property
350
+ def spec(self) -> Optional[Dict[str, Any]]:
351
+ """Get bundle specification (spec.json)."""
352
+ try:
353
+ return self.read_json("spec.json")
354
+ except FileNotFoundError:
355
+ return None
356
+
357
+ @property
358
+ def style(self) -> Optional[Dict[str, Any]]:
359
+ """Get bundle style (style.json)."""
360
+ try:
361
+ return self.read_json("style.json")
362
+ except FileNotFoundError:
363
+ return None
364
+
365
+ @property
366
+ def data(self) -> Optional[pd.DataFrame]:
367
+ """Get bundle data (data.csv)."""
368
+ try:
369
+ return self.read_csv("data.csv")
370
+ except FileNotFoundError:
371
+ return None
372
+
373
+
374
+ def open_bundle(
375
+ path: Union[str, Path], mode: str = "r"
376
+ ) -> ZipBundle:
377
+ """Open a bundle for reading or writing.
378
+
379
+ Args:
380
+ path: Path to bundle file.
381
+ mode: 'r' for read, 'w' for write, 'a' for append.
382
+
383
+ Returns:
384
+ ZipBundle instance (use as context manager).
385
+
386
+ Example:
387
+ with open_bundle("figure.figz") as bundle:
388
+ spec = bundle.spec
389
+ data = bundle.data
390
+ """
391
+ return ZipBundle(path, mode=mode)
392
+
393
+
394
+ def create_bundle(
395
+ path: Union[str, Path],
396
+ spec: Dict[str, Any],
397
+ data: Optional[pd.DataFrame] = None,
398
+ style: Optional[Dict[str, Any]] = None,
399
+ exports: Optional[Dict[str, bytes]] = None,
400
+ ) -> Path:
401
+ """Create a new bundle with atomic write.
402
+
403
+ Args:
404
+ path: Output path (.figz, .pltz, or .statsz).
405
+ spec: Bundle specification dictionary.
406
+ data: Optional CSV data as DataFrame.
407
+ style: Optional style dictionary.
408
+ exports: Optional dict mapping export paths to bytes.
409
+
410
+ Returns:
411
+ Path to created bundle.
412
+
413
+ Example:
414
+ create_bundle(
415
+ "plot.pltz",
416
+ spec={"schema": {"name": "scitex.plt", "version": "1.0"}},
417
+ data=df,
418
+ exports={"exports/plot.png": png_bytes},
419
+ )
420
+ """
421
+ path = Path(path)
422
+
423
+ with ZipBundle(path, mode="w") as bundle:
424
+ bundle.write_json("spec.json", spec)
425
+
426
+ if data is not None:
427
+ bundle.write_csv("data.csv", data)
428
+
429
+ if style is not None:
430
+ bundle.write_json("style.json", style)
431
+
432
+ if exports:
433
+ for export_path, export_data in exports.items():
434
+ bundle.write_bytes(export_path, export_data)
435
+
436
+ return path
437
+
438
+
439
+ # EOF
File without changes
scitex/schema/_plot.py CHANGED
File without changes
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: scitex
3
- Version: 2.7.3
3
+ Version: 2.8.1
4
4
  Summary: A comprehensive Python library for scientific computing and data analysis
5
5
  Project-URL: Homepage, https://github.com/ywatanabe1989/scitex-code
6
6
  Project-URL: Documentation, https://scitex.readthedocs.io
@@ -1,7 +1,7 @@
1
1
  scitex/.mcp.json,sha256=ge1NDrBZkRIxJgx_tCS9QvcEa_P_ay8AAAafraZVRP4,1259
2
2
  scitex/__init__.py,sha256=ESpP5HKTZ34-xh1a2K_oJR3akM4hbkVVBfDb-A1CkrA,6083
3
3
  scitex/__main__.py,sha256=_7OnKtETkmRU1QhAGIUJaT2WrCdsYar0ggzgMJ-HyEI,489
4
- scitex/__version__.py,sha256=iQ0rp6rW9R0PfZp6PjAMyELi7pslATuNZUPRNUDqNvY,400
4
+ scitex/__version__.py,sha256=NcPRlyVnKJaSOV7QCDikJE_oFfPtxPQDGpJ4tu0CgfA,400
5
5
  scitex/_optional_deps.py,sha256=dRLke1qnkOQ0RJBlKQ45ErfAphxjRcohpIjzYhnyylA,3607
6
6
  scitex/errors.py,sha256=R317_uneFtBWA8yYPOHq6CRi0menDk0NCooMLbCMBQs,15228
7
7
  scitex/units.py,sha256=lm2SH4PGXz-22tjUoBQhvKJDKmPD01ykSFWoCaFC384,10356
@@ -374,6 +374,13 @@ scitex/dev/plt/plot_stx_scatter.py,sha256=yJnZE0aL5Z0armnKyxCgdSIfmwSx0MO_BoDbzT
374
374
  scitex/dev/plt/plot_stx_shaded_line.py,sha256=Ss4RD0qxO_uH1h_NL_meSH1-_ZXfOKnV1MAT48tegnI,718
375
375
  scitex/dev/plt/plot_stx_violin.py,sha256=oEAWE4RwG7SQ3JlVuzfSbTFDF02VRb_vE4qBLU3tMu4,680
376
376
  scitex/dev/plt/plot_stx_violinplot.py,sha256=wafuzIKs9WJRfXcH4bxxuigqCh75nxcZDfFq-9P1zxA,687
377
+ scitex/diagram/README.md,sha256=nJGYjSQRaQyecrs93Y5veiV9NYBI3BREC8VQRkja_fQ,4822
378
+ scitex/diagram/__init__.py,sha256=JfT2X9-PNrUyUcvDiz_z7Na3ABzVUOftDV4aS9lGdHo,1488
379
+ scitex/diagram/_compile.py,sha256=JPjVHEJPk884Qfrk9wpbxjQ0PB7AlzQxsi4Sv-osXHU,10282
380
+ scitex/diagram/_diagram.py,sha256=lPTTjrPuAO0WJlTxluygzU7qaKL5cYIqK4yUSwO8NHI,10565
381
+ scitex/diagram/_presets.py,sha256=X1bHVTxGeVHXGCUXJ1y-z7al9k_eh1TmuBnwogWPE20,5392
382
+ scitex/diagram/_schema.py,sha256=moLs8yCthdDI9P4ehFPacGxdEUjeTJ0jAA1knkZtjWw,6173
383
+ scitex/diagram/_split.py,sha256=EaLhK4X65luTx4Q0hPG-6kwESoQNbOAMdzUA3ekPlIY,8394
377
384
  scitex/dict/_DotDict.py,sha256=ES8FTu5icpyDimNEhCPybCKTvtmxiAb5qu2BvLdfGfA,14822
378
385
  scitex/dict/__init__.py,sha256=HX5JwsBeDp5mraVQrhSUOQz-KFead6fPDNBRAOkteVM,402
379
386
  scitex/dict/_flatten.py,sha256=S69tIfqeyhvsJU29FKrTKanWZ6mV-lal_aDGQ1dLElw,613
@@ -427,26 +434,74 @@ scitex/fig/backend/_export.py,sha256=WSHIDn_LjaScBoe0e27vCHgMLkuA3IVXw1I69DwdI_A
427
434
  scitex/fig/backend/_parser.py,sha256=WNPVW6peqeWBZRth0e4o6JWEFtREo6CAgyxhkKH7kjM,4490
428
435
  scitex/fig/backend/_render.py,sha256=_LEqJ2NmJxzDzi8FfgEWuT-Lvm_YlFRtNt3neKnQnXk,11138
429
436
  scitex/fig/docs/CANVAS_ARCHITECTURE.md,sha256=LF5GSiUA1ZWriZt1lAc0FNsGEjl__zgqDQLIp6HKkb8,10559
430
- scitex/fig/editor/__init__.py,sha256=WOTzc1pn-_GJb4WOATlI8T48_kbsPqUsLSnHgA3u4HM,578
431
- scitex/fig/editor/_dearpygui_editor.py,sha256=2ec6TuoPU_qNDn38C37YLk9pGbLzOWv_GrCTHzpmdhQ,76300
437
+ scitex/fig/editor/__init__.py,sha256=FpsAFnNPTVeH_UudaRIMB_wHpO9MjYoqocLvzaFutkU,648
438
+ scitex/fig/editor/_dearpygui_editor.py,sha256=9nKfqE45okVr6XbHwWdmJYqX-nAcuENIH5ElXeg_NaM,76299
432
439
  scitex/fig/editor/_defaults.py,sha256=4-oIZZmwkBTFJj7tKDCy7Ezp55GxbLFP8s_YTYvuFD0,9855
433
- scitex/fig/editor/_edit.py,sha256=VzSWGV7O3dtyGda77vojXLRa_3pQLPYEehxmAFf3Agw,23476
434
440
  scitex/fig/editor/_flask_editor.py,sha256=ZC_T-6zpB3SXO4I_p8rtEdSEfWckCGU-TsVh5IMf-Vs,848
435
- scitex/fig/editor/_mpl_editor.py,sha256=FzouErJ6gernrRDpXLXs0riWsKEC30YjH_uMJamkIzA,7909
436
- scitex/fig/editor/_qt_editor.py,sha256=AOMnlRzGOfIykvERc2QVJ1JaRQMHYQtosFktVGEwxKE,40688
437
- scitex/fig/editor/_tkinter_editor.py,sha256=MiiJCkNOUvYEvRn6ZqCaJWlc8hsTIZBV_9NEepKNFGM,19322
441
+ scitex/fig/editor/_mpl_editor.py,sha256=HbcVkob-OTt4UcQtQXiGNkZ1iUOVyg8nlvGbV6jvzD4,7908
442
+ scitex/fig/editor/_qt_editor.py,sha256=VS0PBC9VsXxRDrrNb5yFa42Cxc4Si9wsgNUGeBsRaHc,40687
443
+ scitex/fig/editor/_tkinter_editor.py,sha256=JN2Oy2uyu0GB0fJjIQ8bb8YR9_gX2TQ_bhj4GQsSKP0,19321
444
+ scitex/fig/editor/edit/__init__.py,sha256=T0L8PDwb7nO1myg-iR2Yy9qojTJdk0NI6uVVCKrawdw,1383
445
+ scitex/fig/editor/edit/backend_detector.py,sha256=UN5Tc50UatJMafsdBypY0NBpRd01SxVv4DFCRTUVPIQ,2917
446
+ scitex/fig/editor/edit/bundle_resolver.py,sha256=oMziNJPYvtIuEfXMeryLyYay9gEM8k3Ecq8pbjAU7k4,7476
447
+ scitex/fig/editor/edit/editor_launcher.py,sha256=eQVVU7f2vWyuN78QZRX9ppbMVeyuO2LfFZE3L6XZoBQ,8135
448
+ scitex/fig/editor/edit/manual_handler.py,sha256=5zKfn2T9ox4n_q5S351OY5r7bW1seOqZdTg1jB7o1_w,1249
449
+ scitex/fig/editor/edit/panel_loader.py,sha256=cOf20nPtdGin35wNtNNleQwlctV9hplmD4uLQ0DMGV0,7099
450
+ scitex/fig/editor/edit/path_resolver.py,sha256=9b1PCj9-ragRWvDNwW0oR733qTlvpjBp7zH2L7IUSTw,2056
438
451
  scitex/fig/editor/flask_editor/__init__.py,sha256=C-5iDsc5c2xSRhgexgB_XvQqJQBvNrGbzKzxOKSSMkA,531
439
- scitex/fig/editor/flask_editor/_bbox.py,sha256=EDm8OLtajxrX-eDAQ0HPuTzoyS77yTSVpN43ZUEaPAg,49546
440
- scitex/fig/editor/flask_editor/_core.py,sha256=bY71vAl2IZSxjCkOYpYk3oV4Vsi_L7OeD-wjeagSLhk,24673
452
+ scitex/fig/editor/flask_editor/_bbox.py,sha256=o_hyh4ZFvV1-_ydf3UyRyp_DfJx5C4zICOywMNXlOck,50862
453
+ scitex/fig/editor/flask_editor/_core.py,sha256=ZjYRiu_qDxgBJ_sBfh6fcYuqiniaWg0eJGlZFrtuOQc,62893
441
454
  scitex/fig/editor/flask_editor/_plotter.py,sha256=FUWHlGVac0mc3MmtuDWIfwe5jw47vGypL0Cbk0LvWPE,21221
442
- scitex/fig/editor/flask_editor/_renderer.py,sha256=O_HC8ysuWjzq41qC_r0_IF3c7w2jsKCqqmaO4IfSMJk,25216
455
+ scitex/fig/editor/flask_editor/_renderer.py,sha256=m_8mvQjIo-r5rNmFt7qJ-mXqe6KGEW7Q_tamNB78FaE,27442
443
456
  scitex/fig/editor/flask_editor/_utils.py,sha256=V9wyfWy61tgnJIFshF2S-d7T8wiNdAgz_CIXCRfBkuI,2513
444
- scitex/fig/editor/flask_editor/templates/__init__.py,sha256=TwAn7WoL3mtQTCIQp5L7y9StTYEHcrBGje_B7qFPnKo,718
445
- scitex/fig/editor/flask_editor/templates/_html.py,sha256=qR7SYE_-CXZvMRcSGNI6yM1IzCChmsMRk4dR-zoTnCk,46319
446
- scitex/fig/editor/flask_editor/templates/_scripts.py,sha256=WKdjZy0HAzFraR4DMaNUC7E7OTCmoRFtNwsE3BYkMSw,120350
447
- scitex/fig/editor/flask_editor/templates/_styles.py,sha256=fj67d3zdYn7TvJEAagWpQj-EAZhj2O-VrrkVe8mnWmw,30258
457
+ scitex/fig/editor/flask_editor/static/css/index.css,sha256=69FxUW6r2K5ZgtiyxqCelJSgpKE_sj9pWKjLjKb6PCk,1234
458
+ scitex/fig/editor/flask_editor/static/css/base/reset.css,sha256=TzCtLzXMbgPwEo4KdiL9GCdgJ1JHomS0NYnI_IXeoOQ,1132
459
+ scitex/fig/editor/flask_editor/static/css/base/typography.css,sha256=vfnz3WiZ11r_eE4ZZSflCu4ZfINZynGUwbEbZsFoU_s,402
460
+ scitex/fig/editor/flask_editor/static/css/base/variables.css,sha256=Am4S_gvNCPO692hMQhsS-HYn_Ovt6iGJEnNEEhJ7cj4,2767
461
+ scitex/fig/editor/flask_editor/static/css/components/buttons.css,sha256=8Zh-ujPAsgPpO3cw32lDYY-M3NrmkSUR01xwIw8kvUA,4076
462
+ scitex/fig/editor/flask_editor/static/css/components/context-menu.css,sha256=UUmapB6BhXSQbWX7AMpPinZa6dsjfXx3KettnaZZgHk,2023
463
+ scitex/fig/editor/flask_editor/static/css/components/dropdown.css,sha256=CbjVS5rWpB17OdryKbVchORBctLP4g0vs7WYr89K35E,1153
464
+ scitex/fig/editor/flask_editor/static/css/components/forms.css,sha256=JlArbNGllH2rY0rcJ7fc3h1H5RZvn9inV4tsrT8bbAQ,2136
465
+ scitex/fig/editor/flask_editor/static/css/components/modal.css,sha256=qjGRknJaMU5Uw3HojQ5zreiwEkp7tl1kn5MedygrOIA,1272
466
+ scitex/fig/editor/flask_editor/static/css/components/sections.css,sha256=KEdPP7cPzWzIR2gKT68bKB3VWrokYJ92rfsbWGJlYD4,4613
467
+ scitex/fig/editor/flask_editor/static/css/features/canvas.css,sha256=cpkX9ZHT985D7z6fnJHmdKnjm_Brtnm25I35xMXW8Lk,4134
468
+ scitex/fig/editor/flask_editor/static/css/features/element-inspector.css,sha256=jqqvNBNrXZ0oSAiECKCXhz5CovPLs2x9a9x-4TDCHTQ,5100
469
+ scitex/fig/editor/flask_editor/static/css/features/loading.css,sha256=Sk2dZHGOivFn78A6vi9jVzeXoJRTUWYR0tjv2TLnsBA,1367
470
+ scitex/fig/editor/flask_editor/static/css/features/overlay.css,sha256=X3Fmului2p3CENs25kOQM61dEnh2mFY1Y93ea8kq-9A,1031
471
+ scitex/fig/editor/flask_editor/static/css/features/panel-grid.css,sha256=AYoy-5c0QX7tA4SFq_axICtc5cj6AMIGJnfsblnt5ug,2002
472
+ scitex/fig/editor/flask_editor/static/css/features/selection.css,sha256=v7J9AFHCCtgS7WLHJPfhot7IkCSGAOGB9oholS5Ys44,2686
473
+ scitex/fig/editor/flask_editor/static/css/features/statistics.css,sha256=294QxYffE_pk_nzFl47TgD07s2QCDuaT1wjJFu43voE,2728
474
+ scitex/fig/editor/flask_editor/static/css/layout/container.css,sha256=kEJrivH0Cz3MNQrHx_lv1a3B22LBDvZq9aNEYnUlX60,243
475
+ scitex/fig/editor/flask_editor/static/css/layout/controls.css,sha256=aVLaIJNcQGCe4f_sY0EuScDYbyqGjA3Hd8CZ1KqltqE,1280
476
+ scitex/fig/editor/flask_editor/static/css/layout/preview.css,sha256=GCT4fU0NnQJCIojQCuQT9Hp1Gkk-ax05Pg40dH-Hnr0,1744
477
+ scitex/fig/editor/flask_editor/static/js/main.js,sha256=fL0rRoGd9pAKj4USw3KMulDEm5vxOm0O2oI59TiIBPA,16445
478
+ scitex/fig/editor/flask_editor/static/js/alignment/axis.js,sha256=wCDseHMBhvfogY6qjrZqv0AZ7ZawDN1Z_0oQWP9QQZ8,11270
479
+ scitex/fig/editor/flask_editor/static/js/alignment/basic.js,sha256=3Qq7webElt_TEL7Kfwj3hCuL05HzlnYDU0j2GaSNqRs,3984
480
+ scitex/fig/editor/flask_editor/static/js/alignment/distribute.js,sha256=NQqSG_ShFcPq0bXdlKDmzHb6uKNurx8d2PU2sjd67vA,1979
481
+ scitex/fig/editor/flask_editor/static/js/canvas/canvas.js,sha256=qu6n8W3Zc9v5Dmw8kNXyUPo-AeJp6KKaDY94758Ufc0,6051
482
+ scitex/fig/editor/flask_editor/static/js/canvas/dragging.js,sha256=YqVM8U5I2ZuGMmr-i2MLZY3s-gxq2nf3ej6bgUMuHu4,8911
483
+ scitex/fig/editor/flask_editor/static/js/canvas/resize.js,sha256=OnS6L8j0X8S51lSNS4i17GgFozDiynrGIBj1JrZIjAk,1610
484
+ scitex/fig/editor/flask_editor/static/js/canvas/selection.js,sha256=1wwq0myWJ5VFvkB_kcOPbdiqeeyzwq9ZCgoMUqc4w_g,2601
485
+ scitex/fig/editor/flask_editor/static/js/core/api.js,sha256=YW1q5rSvLUSrZKREWS9K0w56ipBgZ32iTsif7_snQrk,9131
486
+ scitex/fig/editor/flask_editor/static/js/core/state.js,sha256=tq0ThqAwlIkzB4F2LqFQ8CPuuVxq80elPF5U1uvTrtw,6129
487
+ scitex/fig/editor/flask_editor/static/js/core/utils.js,sha256=4dAKWUQlPsaOK2YHJpoO8mpxHDFyiOPmrudOQPV3J4Q,9201
488
+ scitex/fig/editor/flask_editor/static/js/dev/element-inspector.js,sha256=2IlMg0MSYHr66GPIRuxvxAeMK4qnBUyU0JKLLxrN5mg,35549
489
+ scitex/fig/editor/flask_editor/static/js/editor/bbox.js,sha256=WR0482ZyQwcQg4Au4xssEdEPSecmnecivC-m3luYNx4,12101
490
+ scitex/fig/editor/flask_editor/static/js/editor/element-drag.js,sha256=0UjtQS4vmSfouvA5u5ahOWKUgZ29HuuAPmWvngxAre8,10393
491
+ scitex/fig/editor/flask_editor/static/js/editor/overlay.js,sha256=-f6ktu593FXmomVsF1O8KS3tBdNRGWeiY7t6Hjz3Ca8,14147
492
+ scitex/fig/editor/flask_editor/static/js/editor/preview.js,sha256=ZB2j_DmlPwYBoNKLFXPh9UsOjv-3LPwSZi4EOAzcDD8,11757
493
+ scitex/fig/editor/flask_editor/static/js/shortcuts/context-menu.js,sha256=z0a2HVrEc7EXBUsOaMRvX5TnZ8Dky-30oxAh3aHtqSY,7901
494
+ scitex/fig/editor/flask_editor/static/js/shortcuts/keyboard.js,sha256=wdMhZqVF4xVY92-rkSFKc_ZCxXQa7JZaCCn0hByFPRg,8435
495
+ scitex/fig/editor/flask_editor/static/js/ui/controls.js,sha256=jBL2j0ve4Ca9V39Hn4PhGt9cLHlA8fGeOSiUHvnDVOc,7852
496
+ scitex/fig/editor/flask_editor/static/js/ui/download.js,sha256=Y4kQLVb2ylki9YHR1hyupDJKOZKPlIKCmMVmTSHFWUk,1958
497
+ scitex/fig/editor/flask_editor/static/js/ui/help.js,sha256=9n6IM8r2yBPufo8OokiRwtUljayLLbZlQNcqcr2t4dA,5229
498
+ scitex/fig/editor/flask_editor/static/js/ui/theme.js,sha256=wM9xwZtBNQ5Lq6E-KANbDt9H83Uf7wGiPSI9jQqbzKE,1075
499
+ scitex/fig/editor/flask_editor/templates/__init__.py,sha256=SheAQc9TECkZNEjX8g4ZUpDEh8iAZPaPlmahkfN4Rdk,3287
500
+ scitex/fig/editor/flask_editor/templates/_html.py,sha256=9Fh6Jgt5UQINI5HtltwpYkZ0VLyx5RyqxF1i14dkvDo,47419
501
+ scitex/fig/editor/flask_editor/templates/_scripts.py,sha256=_23IW9n68vkBbbGDa78wYSI2LUiDObP3QsLFY0GYrjA,189756
502
+ scitex/fig/editor/flask_editor/templates/_styles.py,sha256=CnpyH4hnBi8pRaMCjDhDMwhfdmqwdSvTU_YU0RuRX-w,37873
448
503
  scitex/fig/io/__init__.py,sha256=64TIywi_WWk79tkXYyOyF6Llmfuq1lDAc2XaS2puHcU,2580
449
- scitex/fig/io/_bundle.py,sha256=mgYJf5VarxdkX_SttXgN6h62529DsDPqzq22hao2wZY,33431
504
+ scitex/fig/io/_bundle.py,sha256=653oxds6HQEQ_u9O0XgTwvukPF61JDdqIZRywgEokW0,37068
450
505
  scitex/fig/io/_canvas.py,sha256=IC-pm4sLYoUyYp55lJW_B20rfNlgG7TrQiHZ9y16TZw,5721
451
506
  scitex/fig/io/_data.py,sha256=13ob2Mp-5qDNFSQozZMlZvRvobpHFvIkn560mqgkmxI,4827
452
507
  scitex/fig/io/_directory.py,sha256=P6v5Lpef6uyv2V58v0gOfZMmgIertNXRE_gsriLvVg4,5385
@@ -525,8 +580,8 @@ scitex/git/_validation.py,sha256=Hobe4BGXRpvHIk_E71O_KtbZyVnqgSy7ow5fEAvcW_E,260
525
580
  scitex/git/_workflow.py,sha256=Cdi3Hh8Br1OAP6Yl9ikABp_4V2_pbX91truMgcY0200,2235
526
581
  scitex/io/.gitkeep,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
527
582
  scitex/io/README.md,sha256=kB10P6YkqqgiyT_cL6Z2kHLbEUKDwQPxsXRYh-ENcmQ,10727
528
- scitex/io/__init__.py,sha256=YZenY6B3vC7jTQlLVhXLIz1Gn9ApfxtZdbjtIVYTn1I,2570
529
- scitex/io/_bundle.py,sha256=VgY2XgoAAvawJpwUexOSuXw_VIcGOFuNkANCKk3sUzA,12746
583
+ scitex/io/__init__.py,sha256=zNnKKIEZt-ShbZ2E5MI5ShXxhudFyLfIqs803zCjVqg,2857
584
+ scitex/io/_bundle.py,sha256=v25EXcx9Yc-W_wbS6RJYNEiLVhuNKuEmNeX1vRp0cDU,15192
530
585
  scitex/io/_cache.py,sha256=2T10CGtFaxwTGICtFvWWEAhpENlgCMJ1cEqIm2nyTSo,2931
531
586
  scitex/io/_flush.py,sha256=jwrMub6mKqvFPcwAN_fm0fYG6EbVbtl69iYTItG8_eE,562
532
587
  scitex/io/_glob.py,sha256=HS95I9UhxELzhGtawqhgSForIekNBDYdy3335mr46mQ,3541
@@ -540,6 +595,7 @@ scitex/io/_path.py,sha256=mqbs2Y2kJP-IHwvdtnJs8vyime9i0QY8bh3IyVEP3qA,7803
540
595
  scitex/io/_qr_utils.py,sha256=4BcTQ97McNTAt5_3TsG5BQcWo6Cc-BTu9BxIy97ofoY,2047
541
596
  scitex/io/_reload.py,sha256=k3FSMO-ts0sAqNVYroVAG5rxk7haIRtyDbPl1ZvLIfw,2780
542
597
  scitex/io/_save.py,sha256=06-pR4v21pxd_mK3ybcHBf4uGoJqPCHqUok3sxKcR6o,71592
598
+ scitex/io/_zip_bundle.py,sha256=lLEAmz_aaIJcA9I3fj-06hjoULDSKf3jA4H09a9F18A,14313
543
599
  scitex/io/_load_modules/_H5Explorer.py,sha256=AkFpSMvAQFAuZ1FH6M4nHhH2TAsuxpvdsiihRUjmk54,10281
544
600
  scitex/io/_load_modules/_ZarrExplorer.py,sha256=nh9WaxnVTSU5hK7fsZrj64pCiJBD8vkacBV3TaKpFW0,3320
545
601
  scitex/io/_load_modules/__init__.py,sha256=53Z8frCV8Z9xkr4W-x95fQJMZ3jrJtTvu3ujfcDBPJA,1057
@@ -3118,8 +3174,8 @@ scitex/writer/utils/__init__.py,sha256=wizvQZbOWHsNnkdDsB8J4-lPInRM3gDdwOCRg1fLI
3118
3174
  scitex/writer/utils/_parse_latex_logs.py,sha256=Ox52kSK7fCh6tyefRTwkcCvfEMarhMcqM0rsJuJ7UeA,3147
3119
3175
  scitex/writer/utils/_parse_script_args.py,sha256=Fkx1ze_jlKYIpviLuT7z0hpqE4cdtXXA_7sK3sKpVs4,4593
3120
3176
  scitex/writer/utils/_watch.py,sha256=nYzPQ-iPAOzbwzAPBtSrrVBLLPMl08e0qxw0mtv0Y8I,2577
3121
- scitex-2.7.3.dist-info/METADATA,sha256=uFoaHsFPZ5U03hgCrrChIe5z-yyFRGFCdPcZUu7J9U4,30066
3122
- scitex-2.7.3.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
3123
- scitex-2.7.3.dist-info/entry_points.txt,sha256=jmgM0XEEIfCoMvwDSUNwRHBHaX_cfcJWQgi-lFc-BNU,48
3124
- scitex-2.7.3.dist-info/licenses/LICENSE,sha256=TfPDBt3ar0uv_f9cqCDMZ5rIzW3CY8anRRd4PkL6ejs,34522
3125
- scitex-2.7.3.dist-info/RECORD,,
3177
+ scitex-2.8.1.dist-info/METADATA,sha256=SFTWutMBqky89_M4DiioNN55MXLQW5fgrfrKoiJConc,30066
3178
+ scitex-2.8.1.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
3179
+ scitex-2.8.1.dist-info/entry_points.txt,sha256=jmgM0XEEIfCoMvwDSUNwRHBHaX_cfcJWQgi-lFc-BNU,48
3180
+ scitex-2.8.1.dist-info/licenses/LICENSE,sha256=TfPDBt3ar0uv_f9cqCDMZ5rIzW3CY8anRRd4PkL6ejs,34522
3181
+ scitex-2.8.1.dist-info/RECORD,,