scitex 2.15.1__py3-none-any.whl → 2.15.2__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.
- scitex/__init__.py +68 -61
- scitex/_mcp_tools/introspect.py +42 -23
- scitex/_mcp_tools/template.py +24 -0
- scitex/ai/classification/timeseries/_TimeSeriesSlidingWindowSplit.py +30 -1550
- scitex/ai/classification/timeseries/_sliding_window_core.py +467 -0
- scitex/ai/classification/timeseries/_sliding_window_plotting.py +369 -0
- scitex/audio/__init__.py +2 -2
- scitex/audio/_tts.py +18 -10
- scitex/audio/engines/base.py +17 -10
- scitex/audio/engines/elevenlabs_engine.py +1 -1
- scitex/canvas/editor/flask_editor/_core/__init__.py +27 -0
- scitex/canvas/editor/flask_editor/_core/_bbox_extraction.py +200 -0
- scitex/canvas/editor/flask_editor/_core/_editor.py +173 -0
- scitex/canvas/editor/flask_editor/_core/_export_helpers.py +353 -0
- scitex/canvas/editor/flask_editor/_core/_routes_basic.py +190 -0
- scitex/canvas/editor/flask_editor/_core/_routes_export.py +332 -0
- scitex/canvas/editor/flask_editor/_core/_routes_panels.py +252 -0
- scitex/canvas/editor/flask_editor/_core/_routes_save.py +218 -0
- scitex/canvas/editor/flask_editor/_core.py +25 -1684
- scitex/cli/introspect.py +112 -74
- scitex/cli/main.py +2 -0
- scitex/cli/plt.py +357 -0
- scitex/cli/repro.py +15 -8
- scitex/cli/resource.py +15 -8
- scitex/cli/scholar/__init__.py +15 -8
- scitex/cli/social.py +6 -6
- scitex/cli/stats.py +15 -8
- scitex/cli/template.py +129 -12
- scitex/cli/tex.py +15 -8
- scitex/cli/writer.py +15 -8
- scitex/cloud/__init__.py +41 -2
- scitex/config/_env_registry.py +84 -19
- scitex/context/__init__.py +22 -0
- scitex/dev/__init__.py +20 -1
- scitex/gen/__init__.py +50 -14
- scitex/gen/_list_packages.py +4 -4
- scitex/introspect/__init__.py +16 -9
- scitex/introspect/_core.py +7 -8
- scitex/{gen/_inspect_module.py → introspect/_list_api.py} +43 -54
- scitex/introspect/_mcp/__init__.py +10 -6
- scitex/introspect/_mcp/handlers.py +37 -12
- scitex/introspect/_members.py +7 -3
- scitex/introspect/_signature.py +3 -3
- scitex/introspect/_source.py +2 -2
- scitex/io/_save.py +1 -2
- scitex/logging/_formatters.py +19 -9
- scitex/mcp_server.py +1 -1
- scitex/os/__init__.py +4 -0
- scitex/{gen → os}/_check_host.py +4 -5
- scitex/plt/__init__.py +11 -14
- scitex/session/__init__.py +26 -7
- scitex/session/_decorator.py +1 -1
- scitex/sh/__init__.py +7 -4
- scitex/social/__init__.py +10 -8
- scitex/stats/_mcp/_handlers/__init__.py +31 -0
- scitex/stats/_mcp/_handlers/_corrections.py +113 -0
- scitex/stats/_mcp/_handlers/_descriptive.py +78 -0
- scitex/stats/_mcp/_handlers/_effect_size.py +106 -0
- scitex/stats/_mcp/_handlers/_format.py +94 -0
- scitex/stats/_mcp/_handlers/_normality.py +110 -0
- scitex/stats/_mcp/_handlers/_posthoc.py +224 -0
- scitex/stats/_mcp/_handlers/_power.py +247 -0
- scitex/stats/_mcp/_handlers/_recommend.py +102 -0
- scitex/stats/_mcp/_handlers/_run_test.py +279 -0
- scitex/stats/_mcp/_handlers/_stars.py +48 -0
- scitex/stats/_mcp/handlers.py +19 -1171
- scitex/stats/auto/_stat_style.py +175 -0
- scitex/stats/auto/_style_definitions.py +411 -0
- scitex/stats/auto/_styles.py +22 -620
- scitex/stats/descriptive/__init__.py +11 -8
- scitex/stats/descriptive/_ci.py +39 -0
- scitex/stats/power/_power.py +15 -4
- scitex/str/__init__.py +2 -1
- scitex/str/_title_case.py +63 -0
- scitex/template/__init__.py +25 -10
- scitex/template/_code_templates.py +147 -0
- scitex/template/_mcp/handlers.py +81 -0
- scitex/template/_mcp/tool_schemas.py +55 -0
- scitex/template/_templates/__init__.py +51 -0
- scitex/template/_templates/audio.py +233 -0
- scitex/template/_templates/canvas.py +312 -0
- scitex/template/_templates/capture.py +268 -0
- scitex/template/_templates/config.py +43 -0
- scitex/template/_templates/diagram.py +294 -0
- scitex/template/_templates/io.py +107 -0
- scitex/template/_templates/module.py +53 -0
- scitex/template/_templates/plt.py +202 -0
- scitex/template/_templates/scholar.py +267 -0
- scitex/template/_templates/session.py +130 -0
- scitex/template/_templates/session_minimal.py +43 -0
- scitex/template/_templates/session_plot.py +67 -0
- scitex/template/_templates/session_stats.py +77 -0
- scitex/template/_templates/stats.py +323 -0
- scitex/template/_templates/writer.py +296 -0
- scitex/ui/_backends/_email.py +10 -2
- scitex/ui/_backends/_webhook.py +5 -1
- scitex/web/_search_pubmed.py +10 -6
- {scitex-2.15.1.dist-info → scitex-2.15.2.dist-info}/METADATA +1 -1
- {scitex-2.15.1.dist-info → scitex-2.15.2.dist-info}/RECORD +105 -64
- scitex/gen/_ci.py +0 -12
- scitex/gen/_title_case.py +0 -89
- /scitex/{gen → context}/_detect_environment.py +0 -0
- /scitex/{gen → context}/_get_notebook_path.py +0 -0
- /scitex/{gen/_shell.py → sh/_shell_legacy.py} +0 -0
- {scitex-2.15.1.dist-info → scitex-2.15.2.dist-info}/WHEEL +0 -0
- {scitex-2.15.1.dist-info → scitex-2.15.2.dist-info}/entry_points.txt +0 -0
- {scitex-2.15.1.dist-info → scitex-2.15.2.dist-info}/licenses/LICENSE +0 -0
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# Timestamp: "2026-01-24 (ywatanabe)"
|
|
3
|
+
# File: /home/ywatanabe/proj/scitex-python/src/scitex/canvas/editor/flask_editor/_core/_bbox_extraction.py
|
|
4
|
+
|
|
5
|
+
"""Bounding box extraction from pltz metadata."""
|
|
6
|
+
|
|
7
|
+
from typing import Any, Dict, Optional
|
|
8
|
+
|
|
9
|
+
__all__ = ["extract_bboxes_from_metadata"]
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def extract_bboxes_from_metadata(
|
|
13
|
+
metadata: Dict[str, Any],
|
|
14
|
+
display_width: Optional[float] = None,
|
|
15
|
+
display_height: Optional[float] = None,
|
|
16
|
+
) -> Dict[str, Any]:
|
|
17
|
+
"""Extract element bounding boxes from pltz metadata.
|
|
18
|
+
|
|
19
|
+
Builds bboxes from selectable_regions in the metadata for click detection.
|
|
20
|
+
This allows the editor to highlight elements when clicked.
|
|
21
|
+
|
|
22
|
+
Coordinate system (new layered format):
|
|
23
|
+
- selectable_regions bbox_px: Already in final image space (figure_px)
|
|
24
|
+
- Display size: Actual displayed image size (PNG pixels or SVG viewBox)
|
|
25
|
+
- Scale = display_size / figure_px (usually 1:1, but may differ for scaled display)
|
|
26
|
+
|
|
27
|
+
Parameters
|
|
28
|
+
----------
|
|
29
|
+
metadata : dict
|
|
30
|
+
The pltz JSON metadata containing selectable_regions
|
|
31
|
+
display_width : float, optional
|
|
32
|
+
Actual display image width (from PNG size or SVG viewBox)
|
|
33
|
+
display_height : float, optional
|
|
34
|
+
Actual display image height (from PNG size or SVG viewBox)
|
|
35
|
+
|
|
36
|
+
Returns
|
|
37
|
+
-------
|
|
38
|
+
dict
|
|
39
|
+
Mapping of element IDs to their bounding box coordinates (in display pixels)
|
|
40
|
+
"""
|
|
41
|
+
bboxes = {}
|
|
42
|
+
selectable = metadata.get("selectable_regions", {})
|
|
43
|
+
|
|
44
|
+
# Figure dimensions from new layered format (bbox_px are in this space)
|
|
45
|
+
figure_px = metadata.get("figure_px", [])
|
|
46
|
+
if isinstance(figure_px, list) and len(figure_px) >= 2:
|
|
47
|
+
fig_width = figure_px[0]
|
|
48
|
+
fig_height = figure_px[1]
|
|
49
|
+
else:
|
|
50
|
+
# Fallback for old format: try hit_regions.path_data.figure
|
|
51
|
+
hit_regions = metadata.get("hit_regions", {})
|
|
52
|
+
path_data = hit_regions.get("path_data", {})
|
|
53
|
+
orig_fig = path_data.get("figure", {})
|
|
54
|
+
fig_width = orig_fig.get("width_px", 944)
|
|
55
|
+
fig_height = orig_fig.get("height_px", 803)
|
|
56
|
+
|
|
57
|
+
# Use actual display dimensions if provided, else use figure_px
|
|
58
|
+
if display_width is None:
|
|
59
|
+
display_width = fig_width
|
|
60
|
+
if display_height is None:
|
|
61
|
+
display_height = fig_height
|
|
62
|
+
|
|
63
|
+
# Scale factor: display / figure_px
|
|
64
|
+
scale_x = display_width / fig_width if fig_width > 0 else 1
|
|
65
|
+
scale_y = display_height / fig_height if fig_height > 0 else 1
|
|
66
|
+
|
|
67
|
+
def to_display_bbox(bbox, is_list=True):
|
|
68
|
+
"""Convert bbox to display pixels."""
|
|
69
|
+
if is_list:
|
|
70
|
+
x0, y0, x1, y1 = bbox[0], bbox[1], bbox[2], bbox[3]
|
|
71
|
+
else:
|
|
72
|
+
x0 = bbox.get("x0", 0)
|
|
73
|
+
y0 = bbox.get("y0", 0)
|
|
74
|
+
x1 = bbox.get("x1", bbox.get("x0", 0) + bbox.get("width", 0))
|
|
75
|
+
y1 = bbox.get("y1", bbox.get("y0", 0) + bbox.get("height", 0))
|
|
76
|
+
|
|
77
|
+
disp_x0 = x0 * scale_x
|
|
78
|
+
disp_x1 = x1 * scale_x
|
|
79
|
+
disp_y0 = y0 * scale_y
|
|
80
|
+
disp_y1 = y1 * scale_y
|
|
81
|
+
|
|
82
|
+
return {
|
|
83
|
+
"x0": disp_x0,
|
|
84
|
+
"y0": disp_y0,
|
|
85
|
+
"x1": disp_x1,
|
|
86
|
+
"y1": disp_y1,
|
|
87
|
+
"x": disp_x0,
|
|
88
|
+
"y": disp_y0,
|
|
89
|
+
"width": disp_x1 - disp_x0,
|
|
90
|
+
"height": disp_y1 - disp_y0,
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
# Extract from selectable_regions.axes
|
|
94
|
+
axes_regions = selectable.get("axes", [])
|
|
95
|
+
for ax_idx, ax in enumerate(axes_regions):
|
|
96
|
+
ax_key = f"ax_{ax_idx:02d}"
|
|
97
|
+
|
|
98
|
+
# Title
|
|
99
|
+
title = ax.get("title", {})
|
|
100
|
+
if title and "bbox_px" in title:
|
|
101
|
+
bbox_disp = to_display_bbox(title["bbox_px"])
|
|
102
|
+
bboxes[f"{ax_key}_title"] = {
|
|
103
|
+
**bbox_disp,
|
|
104
|
+
"type": "title",
|
|
105
|
+
"text": title.get("text", ""),
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
# X label
|
|
109
|
+
xlabel = ax.get("xlabel", {})
|
|
110
|
+
if xlabel and "bbox_px" in xlabel:
|
|
111
|
+
bbox_disp = to_display_bbox(xlabel["bbox_px"])
|
|
112
|
+
bboxes[f"{ax_key}_xlabel"] = {
|
|
113
|
+
**bbox_disp,
|
|
114
|
+
"type": "xlabel",
|
|
115
|
+
"text": xlabel.get("text", ""),
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
# Y label
|
|
119
|
+
ylabel = ax.get("ylabel", {})
|
|
120
|
+
if ylabel and "bbox_px" in ylabel:
|
|
121
|
+
bbox_disp = to_display_bbox(ylabel["bbox_px"])
|
|
122
|
+
bboxes[f"{ax_key}_ylabel"] = {
|
|
123
|
+
**bbox_disp,
|
|
124
|
+
"type": "ylabel",
|
|
125
|
+
"text": ylabel.get("text", ""),
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
# Legend
|
|
129
|
+
legend = ax.get("legend", {})
|
|
130
|
+
if legend and "bbox_px" in legend:
|
|
131
|
+
bbox_disp = to_display_bbox(legend["bbox_px"])
|
|
132
|
+
bboxes[f"{ax_key}_legend"] = {
|
|
133
|
+
**bbox_disp,
|
|
134
|
+
"type": "legend",
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
# X-axis spine
|
|
138
|
+
xaxis = ax.get("xaxis", {})
|
|
139
|
+
if xaxis:
|
|
140
|
+
spine = xaxis.get("spine", {})
|
|
141
|
+
if spine and "bbox_px" in spine:
|
|
142
|
+
bbox_disp = to_display_bbox(spine["bbox_px"])
|
|
143
|
+
bboxes[f"{ax_key}_xaxis_spine"] = {
|
|
144
|
+
**bbox_disp,
|
|
145
|
+
"type": "xaxis",
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
# Y-axis spine
|
|
149
|
+
yaxis = ax.get("yaxis", {})
|
|
150
|
+
if yaxis:
|
|
151
|
+
spine = yaxis.get("spine", {})
|
|
152
|
+
if spine and "bbox_px" in spine:
|
|
153
|
+
bbox_disp = to_display_bbox(spine["bbox_px"])
|
|
154
|
+
bboxes[f"{ax_key}_yaxis_spine"] = {
|
|
155
|
+
**bbox_disp,
|
|
156
|
+
"type": "yaxis",
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
# Extract traces from artists
|
|
160
|
+
artists = metadata.get("artists", [])
|
|
161
|
+
if not artists:
|
|
162
|
+
hit_regions = metadata.get("hit_regions", {})
|
|
163
|
+
path_data = hit_regions.get("path_data", {})
|
|
164
|
+
artists = path_data.get("artists", [])
|
|
165
|
+
|
|
166
|
+
for artist in artists:
|
|
167
|
+
artist_id = artist.get("id", 0)
|
|
168
|
+
artist_type = artist.get("type", "line")
|
|
169
|
+
bbox_px = artist.get("bbox_px", {})
|
|
170
|
+
if bbox_px:
|
|
171
|
+
bbox_disp = to_display_bbox(bbox_px, is_list=False)
|
|
172
|
+
trace_entry = {
|
|
173
|
+
**bbox_disp,
|
|
174
|
+
"type": artist_type,
|
|
175
|
+
"label": artist.get("label", f"Trace {artist_id}"),
|
|
176
|
+
"element_type": artist_type,
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
path_px = artist.get("path_px", [])
|
|
180
|
+
if path_px:
|
|
181
|
+
scaled_points = [
|
|
182
|
+
[pt[0] * scale_x, pt[1] * scale_y] for pt in path_px if len(pt) >= 2
|
|
183
|
+
]
|
|
184
|
+
trace_entry["points"] = scaled_points
|
|
185
|
+
|
|
186
|
+
bboxes[f"trace_{artist_id}"] = trace_entry
|
|
187
|
+
|
|
188
|
+
bboxes["_meta"] = {
|
|
189
|
+
"display_width": display_width,
|
|
190
|
+
"display_height": display_height,
|
|
191
|
+
"figure_px_width": fig_width,
|
|
192
|
+
"figure_px_height": fig_height,
|
|
193
|
+
"scale_x": scale_x,
|
|
194
|
+
"scale_y": scale_y,
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
return bboxes
|
|
198
|
+
|
|
199
|
+
|
|
200
|
+
# EOF
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# Timestamp: "2026-01-24 (ywatanabe)"
|
|
3
|
+
# File: /home/ywatanabe/proj/scitex-python/src/scitex/canvas/editor/flask_editor/_core/_editor.py
|
|
4
|
+
|
|
5
|
+
"""Core WebEditor class for Flask-based figure editing."""
|
|
6
|
+
|
|
7
|
+
import copy
|
|
8
|
+
import threading
|
|
9
|
+
import time
|
|
10
|
+
import webbrowser
|
|
11
|
+
from pathlib import Path
|
|
12
|
+
from typing import Any, Dict, Optional
|
|
13
|
+
|
|
14
|
+
from .._utils import check_port_available, kill_process_on_port
|
|
15
|
+
|
|
16
|
+
__all__ = ["WebEditor"]
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class WebEditor:
|
|
20
|
+
"""Browser-based figure editor using Flask.
|
|
21
|
+
|
|
22
|
+
Features:
|
|
23
|
+
- Displays existing PNG from plot bundle (no re-rendering)
|
|
24
|
+
- Hitmap-based element selection for precise clicking
|
|
25
|
+
- Property editors with sliders and color pickers
|
|
26
|
+
- Save to .manual.json
|
|
27
|
+
- SciTeX style defaults pre-filled
|
|
28
|
+
- Auto-finds available port if default is in use
|
|
29
|
+
"""
|
|
30
|
+
|
|
31
|
+
def __init__(
|
|
32
|
+
self,
|
|
33
|
+
json_path: Path,
|
|
34
|
+
metadata: Dict[str, Any],
|
|
35
|
+
csv_data: Optional[Any] = None,
|
|
36
|
+
png_path: Optional[Path] = None,
|
|
37
|
+
hitmap_path: Optional[Path] = None,
|
|
38
|
+
manual_overrides: Optional[Dict[str, Any]] = None,
|
|
39
|
+
port: int = 5050,
|
|
40
|
+
panel_info: Optional[Dict[str, Any]] = None,
|
|
41
|
+
):
|
|
42
|
+
self.json_path = Path(json_path)
|
|
43
|
+
self.metadata = metadata
|
|
44
|
+
self.csv_data = csv_data
|
|
45
|
+
self.png_path = Path(png_path) if png_path else None
|
|
46
|
+
self.hitmap_path = Path(hitmap_path) if hitmap_path else None
|
|
47
|
+
self.manual_overrides = manual_overrides or {}
|
|
48
|
+
self._requested_port = port
|
|
49
|
+
self.port = port
|
|
50
|
+
self.panel_info = panel_info
|
|
51
|
+
|
|
52
|
+
# Extract hit_regions from metadata
|
|
53
|
+
self.hit_regions = metadata.get("hit_regions", {})
|
|
54
|
+
self.color_map = self.hit_regions.get("color_map", {})
|
|
55
|
+
|
|
56
|
+
# Get SciTeX defaults and merge with metadata
|
|
57
|
+
from ..._defaults import extract_defaults_from_metadata, get_scitex_defaults
|
|
58
|
+
|
|
59
|
+
self.scitex_defaults = get_scitex_defaults()
|
|
60
|
+
self.metadata_defaults = extract_defaults_from_metadata(metadata)
|
|
61
|
+
|
|
62
|
+
# Start with defaults, then overlay manual overrides
|
|
63
|
+
self.current_overrides = copy.deepcopy(self.scitex_defaults)
|
|
64
|
+
self.current_overrides.update(self.metadata_defaults)
|
|
65
|
+
self.current_overrides.update(self.manual_overrides)
|
|
66
|
+
|
|
67
|
+
# Track initial state to detect modifications
|
|
68
|
+
self._initial_overrides = copy.deepcopy(self.current_overrides)
|
|
69
|
+
self._user_modified = False
|
|
70
|
+
|
|
71
|
+
def run(self):
|
|
72
|
+
"""Launch the web editor."""
|
|
73
|
+
try:
|
|
74
|
+
from flask import Flask
|
|
75
|
+
except ImportError:
|
|
76
|
+
raise ImportError(
|
|
77
|
+
"Flask is required for web editor. Install: pip install flask"
|
|
78
|
+
)
|
|
79
|
+
|
|
80
|
+
# Handle port conflicts
|
|
81
|
+
self._setup_port()
|
|
82
|
+
|
|
83
|
+
# Configure Flask
|
|
84
|
+
import os
|
|
85
|
+
|
|
86
|
+
static_folder = os.path.join(
|
|
87
|
+
os.path.dirname(os.path.dirname(__file__)), "static"
|
|
88
|
+
)
|
|
89
|
+
app = Flask(__name__, static_folder=static_folder, static_url_path="/static")
|
|
90
|
+
|
|
91
|
+
# Register all routes
|
|
92
|
+
self._register_routes(app)
|
|
93
|
+
|
|
94
|
+
# Open browser after short delay
|
|
95
|
+
def open_browser():
|
|
96
|
+
time.sleep(0.5)
|
|
97
|
+
webbrowser.open(f"http://127.0.0.1:{self.port}")
|
|
98
|
+
|
|
99
|
+
threading.Thread(target=open_browser, daemon=True).start()
|
|
100
|
+
|
|
101
|
+
print(f"Starting SciTeX Figure Editor at http://127.0.0.1:{self.port}")
|
|
102
|
+
print("Press Ctrl+C to stop")
|
|
103
|
+
|
|
104
|
+
app.run(host="127.0.0.1", port=self.port, debug=False, use_reloader=False)
|
|
105
|
+
|
|
106
|
+
def _setup_port(self):
|
|
107
|
+
"""Handle port conflicts."""
|
|
108
|
+
max_retries = 3
|
|
109
|
+
for attempt in range(max_retries):
|
|
110
|
+
if check_port_available(self._requested_port):
|
|
111
|
+
self.port = self._requested_port
|
|
112
|
+
break
|
|
113
|
+
print(
|
|
114
|
+
f"Port {self._requested_port} in use. Freeing... "
|
|
115
|
+
f"(attempt {attempt + 1}/{max_retries})"
|
|
116
|
+
)
|
|
117
|
+
kill_process_on_port(self._requested_port)
|
|
118
|
+
time.sleep(1.0)
|
|
119
|
+
else:
|
|
120
|
+
print(f"Warning: Port {self._requested_port} may still be in use")
|
|
121
|
+
self.port = self._requested_port
|
|
122
|
+
|
|
123
|
+
def _register_routes(self, app):
|
|
124
|
+
"""Register all Flask routes."""
|
|
125
|
+
from ._routes_basic import (
|
|
126
|
+
create_colormap_route,
|
|
127
|
+
create_hitmap_route,
|
|
128
|
+
create_index_route,
|
|
129
|
+
create_preview_route,
|
|
130
|
+
create_shutdown_route,
|
|
131
|
+
create_stats_route,
|
|
132
|
+
create_update_route,
|
|
133
|
+
)
|
|
134
|
+
from ._routes_export import (
|
|
135
|
+
create_download_figz_route,
|
|
136
|
+
create_download_route,
|
|
137
|
+
create_export_route,
|
|
138
|
+
)
|
|
139
|
+
from ._routes_panels import (
|
|
140
|
+
create_panels_route,
|
|
141
|
+
create_switch_panel_route,
|
|
142
|
+
)
|
|
143
|
+
from ._routes_save import (
|
|
144
|
+
create_save_element_position_route,
|
|
145
|
+
create_save_layout_route,
|
|
146
|
+
create_save_route,
|
|
147
|
+
)
|
|
148
|
+
|
|
149
|
+
# Basic routes
|
|
150
|
+
create_index_route(app, self)
|
|
151
|
+
create_preview_route(app, self)
|
|
152
|
+
create_hitmap_route(app, self)
|
|
153
|
+
create_colormap_route(app, self)
|
|
154
|
+
create_update_route(app, self)
|
|
155
|
+
create_stats_route(app, self)
|
|
156
|
+
create_shutdown_route(app, self)
|
|
157
|
+
|
|
158
|
+
# Panel routes
|
|
159
|
+
create_panels_route(app, self)
|
|
160
|
+
create_switch_panel_route(app, self)
|
|
161
|
+
|
|
162
|
+
# Save routes
|
|
163
|
+
create_save_route(app, self)
|
|
164
|
+
create_save_layout_route(app, self)
|
|
165
|
+
create_save_element_position_route(app, self)
|
|
166
|
+
|
|
167
|
+
# Export routes
|
|
168
|
+
create_export_route(app, self)
|
|
169
|
+
create_download_route(app, self)
|
|
170
|
+
create_download_figz_route(app, self)
|
|
171
|
+
|
|
172
|
+
|
|
173
|
+
# EOF
|